2026年,MCP(Model Context Protocol)已成为AI Agent工具集成的标准协议。本文从零搭建一个完整的MCP Server(文件系统操作+Web搜索),并集成到Claude Code和Cursor中,全程实战,代码可运行。
关键词:MCP协议、AI Agent、MCP Server、Python、Claude Code、Cursor、Model Context Protocol
一、为什么AI Agent需要MCP?
1.1 从"笼中大脑"说起
AI Agent的"智能"被困在LLM内部——LLM再聪明,也无法直接读取你的文件、搜索网页、操作数据库。要让AI真正"动手干活",必须给它接上外部世界的接口。
1.2 碎片化的工具集成方案
在MCP出现之前,AI工具集成的方案是碎片化的:
| 方案 | 问题 | | --- | --- | | OpenAI Function Calling | 每家模型各一套,不通用 | | LangChain Tools | 框架锁定,不支持跨平台 | | IDE私有插件系统 | 各有各的插件格式 |
核心痛点:AI工具每对接一个外部能力,就要写一套适配代码。
1.3 MCP的"USB-C"隐喻
2024年11月,Anthropic提出了MCP(Model Context Protocol),定位为"AI应用的USB-C接口"——就像USB-C统一了各种充电口,MCP统一了AI工具的能力接口。
核心理念:一次开发,到处可用。同一个MCP Server,可以即插即用地接入Claude Code、Cursor以及任何支持MCP的AI工具。
二、MCP协议核心原理
2.1 三大原语
MCP采用客户端-服务器架构,Server通过三大原语暴露能力:
| 原语 | 作用 | 类比到HTTP | | --- | --- | --- | | Tool | 暴露可执行的操作(读文件、搜索、查DB) | POST请求 | | Resource | 提供结构化数据读取(文件内容、系统状态) | GET请求 | | Prompt | 可复用的交互模板 | 预定义请求体 |
2.2 传输层
MCP支持三种传输方式:
| 传输方式 | 适用场景 | | --- | --- | | stdio | 本地子进程,低延迟,适合CLI工具集成 | | SSE | 远程服务,适合跨网络调用 | | Streamable HTTP | v1.2新增,支持长时间运行任务 |
2.3 生命周期
-
初始化:Client与Server能力协商(capabilities交换)
-
操作:Client调用Tool、读取Resource、使用Prompt
-
关闭:优雅关闭,释放资源
三、MCP Server架构设计
Python SDK提供两种构建方式:
-
Server类(底层API):直接操作Request/Response,精细控制
-
FastMCP封装(高阶API):基于Python decorator,一行代码注册一个Tool
推荐:大部分场景用FastMCP,自动处理Schema生成、消息路由、JSON-RPC序列化。
四、Python实战:从零搭建MCP Server
4.1 环境准备
# 创建项目
mkdir mcp-server-demo
cd mcp-server-demo
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 安装依赖
pip install mcp httpx
4.2 基础Server骨架
from mcp.server.fastmcp import FastMCP
server = FastMCP("MyAssistant")
@server.on_startup()
async def startup():
print("Server started!")
@server.on_shutdown()
async def shutdown():
print("Server shutting down...")
if __name__ == "__main__":
server.run(transport="stdio")
4.3 实现Tool:文件系统操作
import os
from pathlib import Path
from mcp.types import TextContent
@server.tool()
async def read_file(path: str) -> list[TextContent]:
"""读取指定文件的内容。"""
try:
content = Path(path).read_text(encoding="utf-8")
return [TextContent(type="text", text=content)]
except FileNotFoundError:
raise McpError(f"文件不存在: {path}")
except Exception as e:
raise McpError(f"读取文件失败: {str(e)}")
@server.tool()
async def write_file(path: str, content: str) -> list[TextContent]:
"""将内容写入指定文件。"""
try:
Path(path).write_text(content, encoding="utf-8")
return [TextContent(type="text", text=f"成功写入文件: {path}")]
except Exception as e:
raise McpError(f"写入文件失败: {str(e)}")
@server.tool()
async def list_directory(path: str = ".") -> list[TextContent]:
"""列出指定目录的内容。"""
try:
items = os.listdir(path)
return [TextContent(type="text", text="\n".join(items))]
except FileNotFoundError:
raise McpError(f"目录不存在: {path}")
4.4 实现Tool:Web搜索
import httpx
@server.tool()
async def web_search(query: str, max_results: int = 5) -> list[TextContent]:
"""搜索网页内容,返回搜索结果摘要。"""
search_url = "https://api.duckduckgo.com/"
params = {
"q": query,
"format": "json",
"no_html": 1,
"skip_disambig": 1,
}
async with httpx.AsyncClient(timeout=10.0) as client:
try:
response = await client.get(search_url, params=params)
response.raise_for_status()
data = response.json()
results = []
for item in data.get("RelatedTopics", [])[:max_results]:
if "Text" in item and "FirstURL" in item:
results.append(f"- {item['Text']}\n {item['FirstURL']}")
if not results:
return [TextContent(type="text", text=f"未找到相关结果")]
return [TextContent(type="text", text="\n\n".join(results))]
except httpx.TimeoutException:
raise McpError("搜索请求超时")
4.5 实现Resource:系统状态
import platform
@server.resource("system://status")
async def system_status() -> str:
"""获取系统运行状态信息。"""
info = [
f"系统: {platform.system()} {platform.release()}",
f"架构: {platform.machine()}",
f"Python: {platform.python_version()}",
]
return "\n".join(info)
4.6 实现Prompt:操作模板
@server.prompt()
def search_analysis(query: str) -> str:
"""搜索分析模板:先搜索再分析结果。"""
return f"""
请按照以下步骤进行分析:
1. 使用 web_search 工具搜索关键词: "{query}"
2. 阅读搜索结果,提取关键信息
3. 对搜索结果进行综合分析
4. 给出结论和建议
"""
4.7 测试与调试
使用MCP Inspector图形化调试:
npx @modelcontextprotocol/inspector
在Inspector中加载Server(stdio模式,命令:python server.py),即可交互测试所有Tool、Resource和Prompt。
五、集成到Claude Code和Cursor
5.1 Claude Code配置
创建 claude.json:
{
"mcpServers": {
"my-assistant": {
"command": "python",
"args": ["path/to/server.py"],
"env": { "PYTHONUNBUFFERED": "1" }
}
}
}
启动Claude Code后,自动发现Server的所有工具,在对话中自然触发调用。
5.2 Cursor配置
创建 .cursor/mcp.json:
{
"mcpServers": {
"my-assistant": {
"command": "python",
"args": ["path/to/server.py"],
"env": { "PYTHONUNBUFFERED": "1" }
}
}
}
在Cursor的Settings → Features → MCP中查看已配置的Server和工具列表。
5.3 多Server组合
{
"mcpServers": {
"my-filesystem": { "command": "python", "args": ["fs-server.py"] },
"my-search": { "command": "python", "args": ["search-server.py"] },
"my-database": { "command": "python", "args": ["db-server.py"] }
}
}
同一个对话中,AI Agent可组合调用多个Server的能力——这就是MCP的"即插即用"体验。
六、MCP vs 插件 vs A2A
6.1 MCP vs 传统插件
| 维度 | MCP | 传统插件 | | --- | --- | --- | | 协议 | 开放标准 | 私有格式,厂商锁定 | | 能力发现 | 动态协商,自动暴露 | 静态注册,需预配置 | | 通信模式 | 双向(Server可推送) | 单向(Client调用) | | 多语言 | Python/TS/Java/Kotlin | 通常单语言 |
6.2 MCP vs Google A2A
互补而非竞争:MCP解决"Agent如何用工具",A2A解决"Agent之间如何通信"。
Anthropic与Google已宣布MCP + A2A合作,形成完整Agent生态栈。
6.3 生态展望
-
CNCF沙箱项目(2026-03):进入云原生基金会
-
Streamable HTTP(v1.2):支持长时间运行任务
-
Roots权限声明:Server声明资源访问范围,增强安全
-
工具市场:类似VS Code扩展市场,MCP Server Marketplace正在形成
七、总结
30分钟,你从零搭建了一个完整的MCP Server,它:
-
能读文件、写文件、列目录
-
能搜索网页,获取实时信息
-
能暴露系统状态资源
-
能提供标准化的操作模板
-
能即插即用地集成到Claude Code和Cursor
下一步可以做什么?
-
添加数据库查询能力(SQLite/PostgreSQL)
-
实现文件监听(Watchdog)+ Notification推送
-
以SSE模式部署为远程服务
-
参与MCP社区,贡献Server
参考资料
-
MCP官方规范(一级)
-
MCP Python SDK(一级)
-
MCP官方示例仓库(一级)
-
Cursor MCP集成文档(二级)