别再给每个 AI 平台重复写相同的 API 胶水了。同一个查天气的函数,我给 Claude Desktop 封了一套 RESTful,Coze 要插件 JS,Dify 填 YAML,LangChain 还得自定义 Tool 类。参数名、返回格式、认证方式全不一样。上游模型一更新,又得逐行检查兼容性,感觉自己像个手工接线员,把各种 AI 工具用胶水粘在一起,维护成本指数级上升。
这不是能力问题,是协议碎片化。AI 工具大爆发,但彼此孤立,每个框架都发明了自己的"方言"。直到 Anthropic 把 MCP 协议推出来,局面才开始有实质改变。MCP 不搞框架,它要统一通信标准,让工具开发一次,能被任何支持 MCP 的客户端调用。
这篇文章不聊 5 分钟手搓玩具,直接从工程角度把 MCP 的架构、生态、实战和踩过的坑一次讲清楚。
一、MCP 不是框架,是协议
很多人刚接触 MCP,会拿它和 LangChain、Semantic Kernel 对比,这完全搞错了赛道。MCP 不管你怎么实现工具,也不定义业务逻辑,它只定义一件事:AI 客户端(Host)如何通过标准化的方式发现并调用远程工具(Server)。
整个流程拆成三个角色:
- MCP Host:AI 应用本体,比如 Claude Desktop、Cherry Studio、Cline 等。发起用户指令,展示最终结果。
- MCP Client:内嵌在 Host 里的协议客户端,和 Server 保持 1:1 连接,翻译请求。
- MCP Server:你写的工具,封装了你的"独家能力",查数据库、调 API、操作文件等。
交互流程很清晰:Host 启动时,Client 通过配置找到 Server,获取能力列表(list_tools)。用户发指令,Host 把问题加工具列表发给 LLM。LLM 分析后,决定调用哪个工具,生成符合 Schema 的参数。Client 把调用请求发给 Server,拿到结果返回给 LLM。最后 LLM 整合结果展示给用户。这就是 MCP 的"解耦"和"复用"价值:你写一次工具,所有支持 MCP 的客户端都能用,不用给每个平台重写胶水代码。
二、生态全景:不只有 Claude,国内也已经开卷
很多人以为 MCP 只为 Claude 服务,其实它的野心远不止于此。到 2026 年,MCP 生态已经覆盖了主流大厂、开源框架和创意应用。
微软官方出了 MCP Server 合集,覆盖 Azure、GitHub、Teams 等产品。阿里云也在博客里展示了 Grafana MCP Server 开发实例,用 MCP 让大模型直接返回 Dashboard 实时图片和列表。LangChain 推出了 langchain-mcp-adapters,可以直接把 MCP Server 的 tools 转成 LangChain Tool 对象,老牌框架无缝接入新协议。客户端方面,Cherry Studio 1.1.2 已经内置 MCP 支持,Cline(VS Code 插件)可以充当 Host,甚至 Unity 引擎通过 Codex 配置 MCP,让 AI 在游戏里操作场景对象。
掘金上《2026 年最佳 MCP 服务器完全指南》 列出了从知识获取、代码生成到自动化运维的数十个生产级 Server,强调"不要把它们当玩具,这是给 Agent 提供结构化访问的生产工具"。找 Server 就去三个地方:GitHub 官方仓库、awesome-mcp-servers 列表、glama.ai 市场。
现在入局不算晚。你不需要再为每个大模型平台单独写插件,把核心能力封装成 MCP Server,就能一次性接入所有主流 Host。
三、实战:从零写一个能跑的 MCP Server
下面用 Python 实现一个极简的 MCP Server,叫 math-tutor,提供两个工具:add 和 multiply。代码基于官方 mcp Python 库,完整可运行,适合 3.10+ 环境。
1. 环境准备:用 uv 管理项目
用 uv 省心:
# 安装 uv(如果没有)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 创建项目
uv init math-tutor
cd math-tutor
uv add mcp[cli]2. 核心代码:server.py
import asyncio
from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationCapabilities
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
server = Server("math-tutor")
@server.list_tools()
async def handle_list_tools() -> list[Tool]:
"""告诉 Host 我能干什么"""
return [
Tool(
name="add",
description="计算两个数字的和",
inputSchema={
"type": "object",
"properties": {
"x": {"type": "number", "description": "第一个加数"},
"y": {"type": "number", "description": "第二个加数"}
},
"required": ["x", "y"]
}
),
Tool(
name="multiply",
description="计算两个数字的乘积",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "乘数"},
"b": {"type": "number", "description": "被乘数"}
},
"required": ["a", "b"]
}
)
]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict) -> list[TextContent]:
"""执行具体工具"""
if name == "add":
result = arguments["x"] + arguments["y"]
return [TextContent(type="text", text=f"结果是 {result}")]
elif name == "multiply":
result = arguments["a"] * arguments["b"]
return [TextContent(type="text", text=f"结果是 {result}")]
else:
raise ValueError(f"未知工具: {name}")
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
InitializationCapabilities(
sampling={},
experimental={},
),
notification_options=NotificationOptions()
)
if __name__ == "__main__":
asyncio.run(main())3. 配置启动
修改 pyproject.toml,添加执行入口:
[project.scripts]
math-tutor = "server:main"然后 uv run math-tutor 就可以跑起来。现在需要一个 Host 来测试。
4. 用 MCP Inspector 测试
官方提供了调试工具 Inspector,不需要自己写客户端:
npx @anthropic-ai/mcp-inspector uv run math-tutor浏览器打开给出的地址,就能看到 Server 暴露的工具列表,点 add 输入参数,立刻看到返回结果。这比在 Claude Desktop 里反复重启调试高效得多。
5. 接入 Claude Desktop(或其他 Host)
编辑 claude_desktop_config.json(通常在 ~/Library/Application Support/Claude/ 下):
{
"mcpServers": {
"math-tutor": {
"command": "uv",
"args": ["run", "math-tutor"]
}
}
}重启 Claude Desktop,在对话框输入"用数学助手帮我算 3.14 乘以 2.5",它就会自动调用你的 Server 并返回结果。
你不需要写任何 HTTP 路由、JSON 解析、认证逻辑,MCP 框架把通信层全包了,你只需要专注在 call_tool 里实现业务逻辑。
四、进阶:对接真实业务,以 Grafana 为例
写一个玩具 Server 只是第一步,真正有用的是把企业内部系统封装成 MCP Server,让 AI 能直接操作。阿里云云原生团队的文章 MCP Server 开发实战|大模型无缝对接 Grafana 给出了一个好示范:让大模型通过 MCP 返回 Grafana 的 Dashboard 列表和实时曲线图。
核心思路:你的 call_tool 里调用 Grafana API(用 API Key 认证),获取 JSON 数据,然后按需处理。比如 list_dashboards 工具返回面板列表,get_dashboard_image 工具调用 Grafana 的渲染 API 返回图片 URL。当用户说"显示应用监控大盘",AI 就能直接拿出图片,而不是只给一串 ID。
实战要点:
- 工具描述(
description)一定要写得足够详细,因为 LLM 靠它来决定什么时候调用你。比如:"获取指定 Grafana 面板的实时截图,需要提供 dashboardUid、panelId 和时间范围。" - 参数 Schema 严格定义,
required字段要准确,否则 LLM 可能会漏传关键参数。 - 安全性:如果涉及敏感数据,考虑使用只读 API Key,并限定作用域(如仅允许查看指定 Dashboard)。建议分三步走:第一步只读服务,第二步狭窄范围,第三步完整日志,逐步放开权限。
五、避坑与选型:别让 MCP 变成新累赘
工具描述是写给 LLM 看的。 很多开发者习惯在描述里写"这是一个加法工具",这等于没写。LLM 需要足够多的上下文来判断何时调用你。正确的写法:"计算两个数字的和,适用于需要算术运算的场景,比如用户问'1+2 等于几'或'把 3 和 5 加起来'。"
一个 Server 一个职责。 别把数据库查询、文件操作、邮件发送全塞到一个 Server 里。MCP 的每个 Server 应该是正交的,职责单一,方便组合,也方便权限控制。
不要忽略传输层选择。 MCP 支持多种传输:stdio(适用于本地进程)、HTTP(Streamable HTTP,支持流式输出)。本地开发调试用 stdio 最方便,要暴露给远程团队或生产环境,就需要用 HTTP 模式,并加上认证。新规范已经在推进更安全的流式传输,值得关注。
参考来源