MCP 深入理解:协议原理与自定义开发
MCP 深入理解:协议原理与自定义开发
AI 核心技能系列 · 第 9 篇
导语
Agent 要干活,得连接外部世界——读文件、查数据库、调 API。以前每个工具都要单独写适配代码,10 个工具写 10 套,换个模型再写一遍。
MCP(Model Context Protocol) 的出现改变了这一切。它是 AI 领域的"USB-C 接口"——一个协议接所有工具。Anthropic 发起,OpenAI 和 Google 都宣布支持。三个死对头在技术标准上达成一致——这种事在互联网历史上每次发生都不是小事。
一、MCP 是什么:Agent 的"万能插头"
1.1 解决的核心问题
没有 MCP 之前,M 个 AI 应用要对接 N 个工具,需要 M×N 个集成:
Before MCP: After MCP:
App1 ──┬── Tool1 App1 ──┐
├── Tool2 App2 ──┤ ┌── Tool1
└── Tool3 App3 ──┼─MCP─┤── Tool2
App2 ──┬── Tool1 │ └── Tool3
├── Tool2 M + N 个连接
└── Tool3
App3 ──┬── Tool1
├── Tool2
└── Tool3
M × N 个连接
1.2 MCP 发展历程
| 时间 | 事件 |
|---|---|
| 2024.11 | Anthropic 发布 MCP 规范 |
| 2025.03 | OpenAI 宣布支持 MCP |
| 2025.04 | Google Gemini 支持 MCP |
| 2025.06 | MCP 生态爆发,社区 Server 超过 1000+ |
| 2026.01 | MCP 成为 Agent 工具集成的事实标准 |
二、MCP 协议规范详解
2.1 架构
┌────────────┐ ┌─────────────┐ ┌──────────────┐
│ MCP Host │ │ MCP Client │ │ MCP Server │
│ (如 Claude │ ──包含─→ │ (协议客户端) │ ──通信──→ │ (提供工具/资源) │
│ Code/IDE) │ │ │ │ │
└────────────┘ └─────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ 外部服务 │
│ DB/API/文件 │
└──────────────┘
- Host:用户侧应用(Claude Code、Cursor、VS Code 等)
- Client:Host 内部的 MCP 协议客户端,负责与 Server 通信
- Server:提供工具和资源的服务端程序
2.2 传输层
| 传输方式 | 适用场景 | 特点 |
|---|---|---|
| stdio | 本地 Server | 最简单,通过标准输入输出通信 |
| HTTP + SSE | 远程 Server | Server-Sent Events,兼容性好 |
| Streamable HTTP | 远程 Server(新) | 更灵活,支持双向流 |
2.3 三大核心原语
MCP 定义了三种能力原语:
| 原语 | 用途 | 谁控制 | 类比 |
|---|---|---|---|
| Tools | 可执行的操作 | 模型决定调用 | 函数/API |
| Resources | 可读的数据 | 应用决定读取 | 文件/数据库记录 |
| Prompts | 可复用的提示模板 | 用户选择使用 | 预设 Prompt |
Tools(最常用):
{
"name": "query_database",
"description": "查询 PostgreSQL 数据库",
"inputSchema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL 查询语句"},
"database": {"type": "string", "description": "数据库名"}
},
"required": ["sql"]
}
}
Resources:
{
"uri": "file:///project/config.yaml",
"name": "项目配置文件",
"description": "项目的配置信息",
"mimeType": "text/yaml"
}
Prompts:
{
"name": "code_review",
"description": "代码审查专家模板",
"arguments": [
{"name": "language", "description": "编程语言", "required": true},
{"name": "code", "description": "待审查的代码", "required": true}
]
}
三、MCP 生态全景
3.1 热门 MCP Server
| Server | 功能 | 适用场景 |
|---|---|---|
| @modelcontextprotocol/server-filesystem | 文件读写 | 本地文件操作 |
| @modelcontextprotocol/server-github | GitHub API | 代码管理、PR、Issues |
| @modelcontextprotocol/server-postgres | PostgreSQL | 数据库操作 |
| @modelcontextprotocol/server-slack | Slack | 团队沟通 |
| @modelcontextprotocol/server-brave-search | 网页搜索 | 信息检索 |
| @modelcontextprotocol/server-memory | 知识图谱记忆 | Agent 长期记忆 |
3.2 MCP Client 支持
| Client | 支持情况 | 特点 |
|---|---|---|
| Claude Code | 完整支持 | Anthropic 官方,支持最全 |
| Cursor | 完整支持 | IDE 集成 |
| Windsurf | 完整支持 | IDE 集成 |
| VS Code (Copilot) | 支持 | 微软生态 |
| Continue.dev | 支持 | 开源 IDE 插件 |
四、实战:开发你的第一个 MCP Server
4.1 Python 版完整示例
# weather_server.py
import json
import httpx
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, Resource
# 创建 MCP Server
server = Server("weather-server")
# ===== 定义 Tool =====
@server.list_tools()
async def list_tools():
return [
Tool(
name="get_weather",
description="获取指定城市的当前天气信息,包括温度、湿度、天气状况。",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 '北京'、'Shanghai'"
}
},
"required": ["city"]
}
),
Tool(
name="get_forecast",
description="获取指定城市未来 3 天的天气预报。",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"},
"days": {"type": "integer", "description": "预报天数,1-3", "default": 3}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
# 实际项目中调用天气 API
weather_data = {
"city": city,
"temperature": 22,
"humidity": 65,
"condition": "晴",
"wind": "东南风 3级"
}
return [TextContent(
type="text",
text=json.dumps(weather_data, ensure_ascii=False)
)]
elif name == "get_forecast":
city = arguments["city"]
days = arguments.get("days", 3)
forecast = [
{"date": f"Day {i+1}", "high": 22+i, "low": 12+i, "condition": "晴"}
for i in range(days)
]
return [TextContent(
type="text",
text=json.dumps(forecast, ensure_ascii=False)
)]
raise ValueError(f"未知工具: {name}")
# ===== 定义 Resource =====
@server.list_resources()
async def list_resources():
return [
Resource(
uri="weather://cities",
name="支持的城市列表",
description="当前支持查询天气的所有城市",
mimeType="application/json"
)
]
@server.read_resource()
async def read_resource(uri: str):
if uri == "weather://cities":
cities = ["北京", "上海", "广州", "深圳", "杭州", "成都"]
return json.dumps(cities, ensure_ascii=False)
raise ValueError(f"未知资源: {uri}")
# ===== 启动 Server =====
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
4.2 配置使用
在 Claude Code 中使用,编辑 ~/.claude/claude_code_config.json:
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["/path/to/weather_server.py"],
"env": {
"WEATHER_API_KEY": "your-api-key"
}
}
}
}
五、MCP Server 开发最佳实践
5.1 工具描述设计原则(ACI)
ACI(Agent-Computer Interface)——为 AI 设计接口,和为人类设计 UI 一样重要。
| 原则 | 说明 | 示例 |
|---|---|---|
| 名称语义化 | 工具名一看就知道干什么 | search_knowledge_base > search |
| 描述详细 | 说清楚能做什么、不能做什么 | "查询公司内部文档。不支持外部网页搜索。" |
| 参数有约束 | 枚举、范围、默认值 | enum: ["pdf", "docx"] |
| 错误信息友好 | Agent 能理解并决定下一步 | "文件不存在,请检查路径" > "Error 404" |
5.2 安全考量
# 输入验证
import re
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "query_database":
sql = arguments["sql"]
# 1. SQL 注入防护:只允许 SELECT
if not sql.strip().upper().startswith("SELECT"):
return [TextContent(type="text", text="安全限制:只允许 SELECT 查询")]
# 2. 禁止危险关键词
dangerous = ["DROP", "DELETE", "UPDATE", "INSERT", "ALTER", "EXEC"]
if any(kw in sql.upper() for kw in dangerous):
return [TextContent(type="text", text="安全限制:检测到危险操作")]
# 3. 执行查询(使用参数化查询)
result = await db.fetch(sql)
return [TextContent(type="text", text=json.dumps(result))]
六、MCP vs Function Calling vs API
| 维度 | Function Calling | MCP | 传统 API |
|---|---|---|---|
| 标准化 | 各平台不同 | 统一标准 | HTTP/REST |
| 发现机制 | 需要预定义 | 自动发现 | 需要文档 |
| 运行时 | 嵌入应用 | 独立进程 | 独立服务 |
| 生态 | 绑定特定平台 | 跨平台复用 | 通用 |
| 适用场景 | 简单工具调用 | Agent 生态 | 服务间通信 |
什么时候用 MCP:构建 Agent、需要工具复用、希望跨平台兼容
什么时候直接用 FC:简单场景、不需要复用、绑定单一平台
七、职业视角
MCP 正在成为 Agent 开发的基础设施。能开发 MCP Server 是一个重要的差异化技能。
| 问题 | 核心答案要点 |
|---|---|
| MCP 的架构? | Host → Client → Server,三层架构 |
| Tool vs Resource? | Tool 是可执行操作(模型控制),Resource 是可读数据(应用控制) |
| MCP 和 FC 的关系? | FC 是能力(模型决定调什么),MCP 是标准化的工具接口协议 |
| 为什么三大厂商都支持? | 统一标准降低整个生态的集成成本,M×N → M+N |
总结
- MCP 定位:AI 领域的 USB-C,统一 Agent 与工具的集成标准
- 三大原语:Tools(可执行操作)、Resources(可读数据)、Prompts(提示模板)
- 开发简单:Python/TypeScript SDK 成熟,一个 Server 几十行代码
- 安全重要:输入验证、权限控制、SQL 注入防护
- 生态繁荣:1000+ 社区 Server,主流 IDE/AI 工具都支持
本文是 AI 核心技能系列 第 9 篇,共 12 篇。上一篇:Agent 开发全流程 | 下一篇:Skills 与知识系统
关注公众号「coft」,获取完整系列更新、配套代码和学习路线图。一起交流 AI 转行经验,助力职业跃升,迈向高薪岗位。

浙公网安备 33010602011771号