开发你的第一个MCP

1、什么是MCP

01、什么是mcp

全程是模型上下文协议, mcp server作为ai与外部工具的中间层, 代替人类访问或操作外部工具。MCP本质上就是一段python程序,大模型通过操作系统的STDIO(标准输入输出通道或SSE协议调用某个MCP Server, 通过指定的消息格式。MCP Server接收到这些消息后,通过代码或调用api来访问外部工具并且完成任务。mcp简单来说就是ai大模型的标准化工具箱,mcp server对接到aip客户端里实现各种智能体与工作流。

02、mcp使用流程

python可以使用uvx命令,通过stdio协议,pypi发布;也可以使用远程调用,通过sse协议,通过服务器部署来发布

nodejs可以通过npx命令,通过stdio协议,npm发布;也可以使用远程调用,通过sse协议,通过服务器部署来发布

03、mcp协议,理解stdio与sse

  • stdio本地调用,ai客户端直接调用mcp server
  • sse远程调用,ai客户端经过网络调用mcp server

mcp官方仓库,关注python-sdk和pytescript-sdk这两个开发工具包 github.com/orgs/modelc...

下面使用python-sdk来实现一个sdk

2、实现一个MCP

01、安装uv

首先,安装uv,uv是目录热度最高的python环境管理工具,登录官网找到所在系统的安装命令 docs.astral.sh/uv/#highlig...

shell 复制代码
# mac和Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# uv安装成功后,可以通过下面的命令查看一下系统上安装的python版本
uv python list

# 通过uv安装python
uv python install 3.13.7

02、初始化项目

uv初始化项目

shell 复制代码
# 初始化项目
uv init 01_mcp_getting_started -p 3.13
cd 01_mcp_getting_started

# 创建虚拟环境并进入虚拟环境
uv venv
.venv\Scripts\activate.bat
# mac执行如下命令进入虚拟环境
source .venv/bin/activate

# 安装mcp python sdk开发工具包及其他依赖
uv add "mcp[cli]" httpx openai python-dotenv

简单配置一下vscode:

  1. vscode安装python与python debugger插件
  2. 使用vscode打开这个文件夹
shell 复制代码
.env文件夹是python的虚拟环境
pyproject.toml定义了项目的基本信息
main.py是基础的代码样例

03、编写MCP

这里我们会用 dotenv 来管理我们相关的环境变量。.env 文件内容如下:

shell 复制代码
ZHI_PU_AI_API_KEY=xxx

创建文件web_search.py

python 复制代码
import httpx
from mcp.server import FastMCP
import platform
import json
import os  # 导入 os 模块
import logging
from dotenv import load_dotenv

# 加载.env文件中的环境变量
load_dotenv()

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 初始化 FastMCP 服务器
app = FastMCP('web-search')

# 从环境变量中读取 API 密钥
# ZHI_PU_AI_API_KEY = os.environ.get("ZHI_PU_AI_API_KEY")  #替换成你的环境变量名
ZHI_PU_AI_API_KEY = os.getenv("ZHI_PU_AI_API_KEY")
if not ZHI_PU_AI_API_KEY:
    logging.error("未找到 ZHI_PU_AI_API_KEY 环境变量")
    raise ValueError("请设置 ZHI_PU_AI_API_KEY 环境变量")

@app.tool()
async def web_search(query: str) -> str:
    """
    搜索互联网内容

    Args:
        query: 要搜索内容

    Returns:
        搜索结果的总结
    """
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(
                'https://open.bigmodel.cn/api/paas/v4/tools',
                headers={'Authorization': ZHI_PU_AI_API_KEY},
                json={
                    'tool': 'web-search-pro',
                    'messages': [
                        {'role': 'user', 'content': query}
                    ],
                    'stream': False
                }
            )
            response.raise_for_status()  # 抛出 HTTPError,以处理非 200 状态码

            res_data = []
            for choice in response.json()['choices']:
                for message in choice['message']['tool_calls']:
                    search_results = message.get('search_result')
                    if not search_results:
                        continue
                    for result in search_results:
                        res_data.append(result['content'])

            return '\n\n\n'.join(res_data)

        except httpx.HTTPStatusError as e:
            logging.error(f"HTTP 错误: {e}")
            return f"搜索失败:HTTP 错误 - {e}"
        except httpx.RequestError as e:
            logging.error(f"请求错误: {e}")
            return f"搜索失败:请求错误 - {e}"
        except json.JSONDecodeError as e:
            logging.error(f"JSON 解析错误: {e}, 响应内容: {response.text}")  # 记录响应内容
            return "搜索失败:无法解析 JSON 响应"
        except Exception as e:
            logging.exception("发生未知的错误")
            return "搜索失败:发生未知的错误"


@app.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b


@app.tool()
def get_host_info() -> str:
    """
    Get host information
    Returns:
        str: the host information in JSON string format
    """
    info: dict[str, str] = {
        "system": platform.system(),
        "node": platform.node(),
        "release": platform.release(),
        "version": platform.version(),
        "machine": platform.machine(),
        "processor": platform.processor(), }

    return json.dumps(info, indent=4)


# @app.resoruce("greeting://{name}")
# def get_greeting(name: str) -> str:
#     """Get a personalized greeting"""
#     return f"Hello, {name}!"

if __name__ == "__main__":
    app.run(transport='stdio')

关键点: 1、mcp函数第一行的这个注释必须要写的,使用自然语言告诉大模型这个函数的功能是什么 2、mcp函数的类型修饰符一定要写,有助于大模型理解工具的传参是什么类型,可以帮大模型更精准的调用mcp工具 3、@mcp.tool() 类似于Http Rest API中的post方法,会产生副作用 4、@mcp.resource()类似于get方法,为大模型提供只读数据,不会产生副作用

04、调试mcp

shell 复制代码
# 通过npx, node版本v20.19.2
npx -y @modelcontextprotocol/inspector uv run web_search.py

# 通过mcp dev来运行
# mcp dev web_search.py

3、接入MCP Server

01、使用Cherry Studio接入MCP Server

路径:设置 - MCP服务器

注意:

  1. 如果右上角有一个三角形的红色三角,需要先安装uv和bun,因为Chery Studio使用的是它内置的uv和bun

添加mcp

shell 复制代码
--directory
/Users/snddfhv/03learn/mcp-servers/01_mcp_getting_started
run
web_search.py

02、验证

4、PS

01、使用环境变量管理API Key

我们会申请多个平台的多个API Key,为了方便在控制台快速使用,我们可以将其添加到环境变量中。 添加永久性环境变量

shell 复制代码
# 1、执行如下命令将环境变量设置追加到~/.zshrc文件中(或~/.bashrc)
echo "export ZHI_PU_AI_API_KEY='xxx'" >> ~/.zshrc

# 2、使变更生效
要ource ~/.zshrc

# 3、重新打开一个终端端口,检查环境变量是否生效
echo $ZHI_PU_AI_API_KEY

添加临时性环境变量

shell 复制代码
# 1、设置环境变量
export ZHI_PU_AI_API_KEY='xxx'

# 2、验证环境变量是否生效
echo $ZHI_PU_AI_API_KEY

02、使用python-dotenv管理API Key

安装python-dotenv

shell 复制代码
pip3 install python-dotenv

创建.env 文件 在项目根目录下创建一个名为.env的文件,并在其中添加环境变量

shell 复制代码
ZHI_PU_AI_API_KEY=xxx

在Python代码中使用环境变量

python 复制代码
import os
from dotenv import load_dotenv
# 加载.env文件中的环境变量
load_dotenv()
# 获取ZHI_PU_AI_API_KEY
api_key = os.getenv("ZHI_PU_AI_API_KEY")
if api_key:
	print(f"ZHI_PU_AI_API_KEY: {api_key}")
else:
	print("环境变量ZHI_PU_AI_API_KEY未设置或未加载")

03、uv的使用

001、安装

shell 复制代码
# 推荐使用` pipx `进行安装,以将其隔离
pip install pipx
pipx ensurepath
pipx install uv

下面介绍一下uv的主要使用场景和命令

002、虚拟环境管理

shell 复制代码
# 创建虚拟环境
uv venv

# 指定虚拟环境的名称或路径
uv venv my_env
uv venv /path/to/my_env

# 激活虚拟环境
source .venv/bin/activate

# 退出虚拟环境
deactivate

# 列出所有虚拟环境
uv venv list

# 移除虚拟环境
uv venv remove .venv
uv venv remove my_env

003、包管理

shell 复制代码
# 安装包
uv pip install python-dotenv
uv pip install requests beautifulsoup4
uv pip install "Django=4.2"

# 从requirements.txt安装
uv pip install -r requirements.txt

# 升级包
uv pip install --upgrade python-dotenv
uv pip install --upgrade -r requirements.txt

# 卸载包
uv pip uninstall python-dotenv
uv pip uninstall requests beautifulsoup4

# 列出已安装的包
uv pip list
uv pip freeze # 通常用于生成requirements.txt

# 缓存管理
uv pip cache purge

004、运行命令

shell 复制代码
uv run python my_script.py

005、pyproject.toml支持

uv很好地支持现代Python项目中推荐的pyproject.toml文件来定义项目依赖

toml 复制代码
[project]
name = "your-awesome-project"
version = "0.1.0"
dependencies = [
  "fastapi",
  "uvicorn[standard]",
]
[project.optional-dependencies]
dev = [
	"pytest",
	"black"
]

安装项目依赖

shell 复制代码
# 在包含pyproject.toml的项目根目录中
# 安装核心依赖
uv pip install .
# 安装开发依赖
uv pip install ".[dev]"

006、uv的优势

  • 极快的性能:Rust的编译速度带来了显著的性能提升,尤其在处理复杂依赖图时
  • 一致性:旨在消除pip和pip-tools在依赖解析方面的一些不一致行为
  • 依赖解析能力:采用最先进的依赖解析算法,能够更准确地解决复杂的依赖冲突
  • 缓存:有效利用缓存,进一步回事安装过程

07、总结

uv是Python包管理领域的一个强大而有前途的新工具。通过整合虚拟环境和包管理功能,并提供卓越的速度,它为Python开发者提供了一个更高效、更愉悦的工作流程。如果你正在寻找pip的快速替代吕,并希望简化Python项目的依赖管理,uv绝对值得一试。

相关推荐
Cosmoshhhyyy4 小时前
MCP:cursor、claude code接入chrome-devtools-mcp。
ai·mcp
-D调定义之崽崽16 小时前
【初学】使用 node 编写 MCP Server
typescript·node·mcp
wuhanwhite1 天前
在 Trae 国际版中添加 Chrome Dev MCP Server(Windows 实战指南)
mcp
晨启AI1 天前
Claude Code 实战指南(三):AI辅助开发工作流 Spec Workflow MCP教程
ai·实战·mcp·claude code
SelectDB技术团队1 天前
Apache Doris 4.0 AI 能力揭秘(二):为企业级应用而生的 AI 函数设计与实践
数据库·人工智能·apache·olap·mcp
不老刘2 天前
谷歌官方 Chrome DevTools MCP 正式发布
chrome·chrome devtools·mcp
中国胖子风清扬2 天前
Rust MCP:构建智能上下文协议的未来桥梁
后端·ai·rust·ai编程·language model·ai-native·mcp
黄啊码3 天前
AI智能体落地失败的罪魁祸首除了大模型幻觉,还有它
人工智能·agent·mcp
GHOME3 天前
MCP-学习(1)
前端·后端·mcp