开发你的第一个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绝对值得一试。

相关推荐
智海观潮20 小时前
AIGC、Agent、MCP、A2A和AG-UI促进AI从基础能力到协同生态演进
人工智能·chatgpt·aigc·mcp
冴羽1 天前
Nano Banana Pro 很强,但你要学会写提示词才能为所欲为
人工智能·aigc·mcp
Cleaner2 天前
大模型的手和脚:从提示工程到 MCP
人工智能·llm·mcp
ByteCraze2 天前
面向Nodejs开发人员MCP快速入门
前端·node.js·agent·mcp
韩数3 天前
小白也能看懂! 今年爆火的 MCP 协议究竟是什么?写给普通人的 MCP 指南
后端·aigc·mcp
疯狂踩坑人5 天前
MCP理论和实战,然后做个MCP脚手架吧
前端·node.js·mcp
组合缺一5 天前
Spring Boot 国产化替代方案。Solon v3.7.2, v3.6.5, v3.5.9 发布(支持 LTS)
java·后端·spring·ai·web·solon·mcp
Ericwyn5 天前
MCP Partner, 一个在线快捷 mcp client 调试工具
mcp
Breath575 天前
代码执行 + MCP:AI 代理 token 省 98%!
agent·ai agent·mcp·上下文工程
魁首6 天前
AI Agent 协议演进:从 MCP 到 ACP 的架构对比与未来展望
openai·gemini·mcp