#AI Agent #MCP #工具调用 #协议
2024 年底之前,给大模型接工具基本是「各家自扫门前雪」:OpenAI 有 Function Calling, Anthropic 有 tool use,各家 SDK 的参数格式、返回结构、鉴权方式各不相同。 一个 Agent 想同时调用 GitHub API、数据库和公司内部系统,就要为每个工具写一遍胶水代码, 每换一个模型厂商就要重写一遍。MCP(Model Context Protocol,模型上下文协议)就是 Anthropic 在 2024 年 11 月开源的一套统一标准,目标是让「模型 ↔ 工具」的连接方式 像 USB 接口一样即插即用。本文从概念、架构到最小实现,讲清 MCP 到底是什么、怎么用。
MCP 把参与者分成三层,理解这三层就理解了整个协议:
类比一下:Host 是电脑主机,Client 是 USB 接口,Server 是插上去的键盘、鼠标、U 盘。 键盘厂商不用关心你的电脑装了什么系统,只要实现 USB 标准就行——MCP Server 也一样, 写一次,任何支持 MCP 的 Host 都能直接用。
MCP Server 对外暴露三类能力,各自解决不同的问题:
create_issue、search_web。
模型决定何时调用,调用参数由 JSON Schema 声明。这是用得最多的一类。新手常犯的错是「什么都做成 Tools」。判断标准很简单:需要写操作就做 Tool, 只需要读就给模型看就做 Resource,纯粹是提示词就做 Prompt。
MCP 的传输方式主要有两种,选型取决于你的部署形态:
2025 年 3 月协议更新后,官方推荐新项目直接用 Streamable HTTP;本地开发调试仍以 stdio 为主。 不管哪种传输,上层交换的消息格式是同一套 JSON-RPC 2.0,所以 Client 侧逻辑可以复用。
用官方 mcp Python SDK 写一个「今日天气」工具,核心代码不到 20 行:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
def get_weather(city: str) -> str:
"""查询指定城市的天气(示例)。"""
return f"{city}:晴,26°C,适合出门。"
if __name__ == "__main__":
mcp.run(transport="stdio")
把这段代码跑起来,任何 MCP Host 都能发现 get_weather 工具、读取它的参数 schema
并调用它。注意两点:一是函数 docstring 会被当作工具描述喂给模型,直接影响模型判断
「什么时候该用这个工具」,要写清楚;二是 transport 参数换成
"streamable-http" 就是网络版,部署形态变了,代码几乎不用动。
很多人问「有了 Function Calling 为什么还要 MCP」,二者不是替代关系而是分工关系:
所以 MCP 的价值不在「取代」任何东西,而在「一次接入、处处可用」:你的 Agent 框架只要 实现一次 MCP Client,社区里上千个现成 Server(Git、Slack、浏览器、数据库……)全部开箱即用。
create_issue 而不是 issue),模型更好理解。{success: false, error: "..."},而不是抛异常让连接断开——模型能读到错误信息自我修正。MCP 把「模型调用工具」这件事从每家私有的胶水代码,变成了一个开放的公共标准。 对一人公司和小团队尤其划算:工具写一次,Claude、自建 Agent、IDE 全都能用, 不用为每个入口重复开发。上手路径也很短——先写一个 stdio 的最小 Server 跑通链路, 再按需换成 HTTP 部署,最后补上鉴权和错误处理,就能稳定支撑日常的 Agent 工作流了。