一句话:MCP 可以理解成 Agent 世界的"Type-C 接口"——它不保证完全零适配,但能显著减少工具跨平台集成成本。
划重点
Function Calling 的痛点:每换一个模型/平台,工具就得重新适配一遍 MCP(Model Context Protocol):Anthropic 提出的开放协议,让工具和模型之间有统一接口 类比:Function Calling 是"专用充电线",MCP 是"Type-C 接口" MCP 三个核心角色:Host(宿主)、Client(客户端)、Server(工具服务) 实战:用 Python 写一个最小 MCP Server,接入 Claude Desktop
一个真实的痛点
假设你写了一个"查天气"工具。
用 OpenAI 的 Function Calling,你需要按 OpenAI 的格式定义 JSON Schema,注册到 tools 列表里。
现在老板说:换成 Claude。
你发现 Claude 的工具格式……跟 OpenAI 不一样。重写。
再换 DeepSeek?又不一样。再重写。
如果你有 10 个工具、3 个模型平台,你就需要维护 30 份适配代码。
公平地说,2025-2026 年各平台的 API 已经在趋同(很多都兼容 OpenAI SDK),没有早期那么碎片化了。但工具定义格式、消息结构、流式协议仍有差异——换平台不至于"完全重写",但总要改一轮适配代码。
MCP 的目标是把"跨模型工具适配"从大量重复工程,收敛为统一协议层的问题。 不能保证完全"零适配",但能显著减少重复工具集成成本。
MCP 是什么?
MCP(Model Context Protocol)是 Anthropic 在 2024 年底提出的开放协议。核心思想很简单:
在模型和工具之间加一层标准协议,让两边互不感知对方的实现细节。
类比:
更精确地说,MCP 更像 AI 世界的 LSP(Language Server Protocol)——统一能力声明和调用协议,让工具、模型、IDE 各自独立演进。USB 类比帮助理解,但 MCP 不涉及硬件级热插拔。
MCP 的架构:三个角色
┌──────────────────────────────────────────────┐│ Host(宿主) ││ Claude Desktop / VS Code / 你的 App ││ ││ ┌────────────┐ ┌────────────┐ ││ │ MCP Client │ │ MCP Client │ ... ││ └─────┬──────┘ └─────┬──────┘ ││ │ │ │└────────┼──────────────────┼───────────────────┘ │ │ ┌────▼─────┐ ┌────▼─────┐ │MCP Server│ │MCP Server│ │ (天气) │ │ (数据库) │ └──────────┘ └──────────┘三个角色:
1. Host(宿主)
用户直接交互的应用——Claude Desktop、VS Code Copilot、你自己的 Agent 应用。Host 负责管理所有 MCP Client 的生命周期。
2. Client(客户端)
Host 内部的协议适配层。每个 Client 跟一个 Server 建立 1:1 连接。Client 负责把模型的工具调用请求翻译成 MCP 协议格式。
3. Server(工具服务)
暴露具体能力的服务。一个 Server 可以提供:
Tools(工具):模型可以调用的函数,比如查天气、发邮件 Resources(资源):模型可以读取的数据,比如文件内容、数据库记录 Prompts(提示模板):预定义的交互模板
MCP vs Function Calling:到底区别在哪?
关键区别在"谁拥有工具定义":
Function Calling:工具定义写在"调用模型的那段代码里",跟模型绑定 MCP:工具定义写在独立的 Server 里,任何兼容 MCP 的 Client 都能连上来发现和调用
这就像:
Function Calling = 你把打印机驱动写死在一个应用里,换电脑就不能用 MCP = 打印机自带驱动,任何电脑插上就能识别
实战:写一个最小 MCP Server
下面用 Python 写一个最简单的 MCP Server——提供一个"查天气"工具。
# weather_server.pyfrom mcp.server.fastmcp import FastMCPmcp = FastMCP("weather-server")@mcp.tool()defget_weather(city: str) -> str:"""查询指定城市的当前天气"""# 这里替换成真实 API 调用returnf"{city}:晴,28°C,湿度 45%"if __name__ == "__main__": mcp.run()这就是一个完整的 MCP Server。 大约 10 行代码。
FastMCP 是 MCP Python SDK 提供的高层封装,类似 FastAPI 对 WSGI 的抽象——你只需要用 @mcp.tool() 装饰器声明工具函数,SDK 自动处理能力声明、参数校验和通信协议。底层仍然是标准 MCP protocol。
它做了两件事:
声明工具:函数名就是工具名,docstring 就是描述,类型标注就是参数 schema 启动服务: mcp.run()默认通过 stdio 通信
接入 Claude Desktop
把上面的 Server 接入 Claude Desktop 只需要一步:编辑配置文件。
// claude_desktop_config.json{"mcpServers": {"weather": {"type": "stdio","command": "python","args": ["weather_server.py"],"cwd": "/path/to/your/project" } }}重启 Claude Desktop 后,它会自动:
启动你的 weather_server.py进程通过 MCP 协议发现 get_weather工具当用户问天气相关问题时,Claude 会自动发现并请求调用这个工具(实际调用时 Host 可能要求用户确认权限)
你不需要写任何 Function Calling 的 JSON Schema,不需要手动注册 tools——Server 自己声明了能力,Client 自动发现。
MCP 的通信方式
MCP 当前主流支持两种传输方式:
1. stdio(标准输入输出)
Client 启动 Server 进程,通过 stdin/stdout 通信。适合本地工具。
Client ──stdin──> ServerClient <─stdout── Server2. Streamable HTTP(远程服务通信)
Server 作为独立 HTTP 服务运行,Client 通过网络连接。适合远程工具/团队共享。早期版本使用 HTTP + SSE(Server-Sent Events),新版协议已转向 Streamable HTTP。
Client ──HTTP──> Server(发送请求)Client <─HTTP── Server(流式返回结果)选哪种?
本地开发/个人使用 → stdio(简单,零配置) 团队共享/生产部署 → Streamable HTTP(可远程访问)
MCP 生态现状
截至目前,MCP 生态已经相当丰富:
支持 MCP 的 Host:
Claude Desktop(原生支持) VS Code / GitHub Copilot(已支持或正在适配 MCP) Cursor(已集成 MCP 支持) 部分开源 Agent 框架(LangChain、CrewAI 等有不同程度的适配)
常见 MCP Server:
文件系统操作(读写文件、目录遍历) 数据库查询(PostgreSQL、SQLite) Web 搜索(Brave Search、Google) GitHub(PR、Issue、代码搜索) 第三方 API(Slack、Notion、飞书)
社区已经有数百个现成 Server,大多数开箱即用。
什么时候该用 MCP,什么时候用 Function Calling?
不是非此即彼。 很多生产系统是混合使用的——简单工具用 Function Calling 快速搞定,复杂/需要复用的工具用 MCP 独立部署。
总结
@mcp.tool() 声明工具函数,SDK 自动处理其余一切 | |
核心思想:工具和模型之间不应该紧耦合。MCP 在中间加了一层协议,让两边可以独立演进。
需要注意的是:MCP 解决了工具声明和调用层面的标准化,但模型能否正确理解和选择工具、权限管理、多步工作流编排等问题,仍需要 Agent Runtime 自己处理——这些正是前几篇讲的 Runtime 设计要解决的事。
换句话说:MCP 解决的是"工具怎么接",而不是"Agent 怎么思考"。 从软件工程视角看,MCP 更像"设备驱动接口标准",而 Agent Runtime 更像"操作系统"——MCP 是基础设施的一部分,但不是全部。
这跟前面讲的 Runtime 思路一脉相承——Agent 的架构越来越像传统软件工程:分层、解耦、标准化。
下期预告:Multi-Agent——一个 Agent 不够用怎么办?多个 Agent 怎么协作?主从模式、专家组模式,以及 A2A 协议。
夜雨聆风