MCP(Model Context Protocol)#
MCP 是 Anthropic 于 2024 年发布的开放协议,用于连接 LLM 与外部工具、数据源,标准化「AI 调用工具」的方式。
1. 是什么#
MCP(Model Context Protocol)是一个开放标准协议,定义了 LLM 应用与外部服务之间的通信方式,类似于 AI 领域的「USB 协议」。
核心概念:
| 概念 | 说明 |
|---|---|
| Host | 发起请求的 LLM 应用(如 Claude Desktop、Cursor) |
| Client | Host 内的 MCP 客户端,管理与 Server 的连接 |
| Server | 提供工具/资源的服务端(如文件系统、数据库、API) |
三种能力:
| 能力 | 说明 | 示例 |
|---|---|---|
| Tools | LLM 可调用的函数 | 执行 SQL、发送邮件、调用 API |
| Resources | LLM 可读取的数据 | 文件内容、数据库记录 |
| Prompts | 预定义的提示模板 | 代码审查模板、摘要模板 |
架构示意:
graph LR
A[LLM Host] --> B[MCP Client]
B <-->|JSON-RPC| C[MCP Server 1: 文件系统]
B <-->|JSON-RPC| D[MCP Server 2: 数据库]
B <-->|JSON-RPC| E[MCP Server 3: Web API]
为什么需要 MCP:
- 统一标准:不同工具用同一协议,无需为每个 LLM 单独适配
- 安全隔离:Server 在独立进程运行,权限可控
- 生态复用:一次实现,多处使用(Claude、Cursor、自定义应用)
2. 使用别人的 MCP 服务#
在 Claude Desktop 中配置#
编辑配置文件(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json,Windows: %APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
},
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "/path/to/database.db"]
}
}
}
在 Cursor 中配置#
编辑 .cursor/mcp.json(项目级)或全局配置:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your_token"
}
}
}
}
常用官方 MCP Server#
| Server | 安装命令 | 功能 |
|---|---|---|
| filesystem | npx @modelcontextprotocol/server-filesystem |
读写本地文件 |
| github | npx @modelcontextprotocol/server-github |
GitHub 仓库操作 |
| sqlite | uvx mcp-server-sqlite |
SQLite 数据库查询 |
| postgres | npx @modelcontextprotocol/server-postgres |
PostgreSQL 查询 |
| puppeteer | npx @modelcontextprotocol/server-puppeteer |
浏览器自动化 |
| slack | npx @modelcontextprotocol/server-slack |
Slack 消息读写 |
社区 MCP Server#
在 MCP Registry 或 mcp.so 查找更多:
- mcp-server-fetch:HTTP 请求
- mcp-server-memory:持久化记忆
- mcp-server-notion:Notion 集成
- mcp-server-brave-search:Brave 搜索
3. 自己实现 MCP Server#
Python 实现(推荐)#
安装 SDK:
pip install mcp
最小示例(实现一个天气查询工具):
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# 创建 Server
server = Server("weather-server")
# 定义工具列表
@server.list_tools()
async def list_tools():
return [
Tool(
name="get_weather",
description="获取指定城市的天气",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"}
},
"required": ["city"]
}
)
]
# 实现工具逻辑
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
# 实际应调用天气 API,这里模拟返回
return [TextContent(type="text", text=f"{city}:晴,25°C")]
raise ValueError(f"Unknown tool: {name}")
# 启动服务
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
TypeScript 实现#
安装 SDK:
npm install @modelcontextprotocol/sdk
示例:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{ name: "weather-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// 列出工具
server.setRequestHandler("tools/list", async () => ({
tools: [{
name: "get_weather",
description: "获取指定城市的天气",
inputSchema: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"]
}
}]
}));
// 调用工具
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "get_weather") {
return { content: [{ type: "text", text: `${args.city}:晴,25°C` }] };
}
throw new Error(`Unknown tool: ${name}`);
});
// 启动
const transport = new StdioServerTransport();
server.connect(transport);
注册到客户端#
将自己的 Server 添加到配置:
{
"mcpServers": {
"my-weather": {
"command": "python",
"args": ["/path/to/weather_server.py"]
}
}
}
实现 Resources(可选)#
from mcp.types import Resource
@server.list_resources()
async def list_resources():
return [
Resource(
uri="file:///config/settings.json",
name="配置文件",
mimeType="application/json"
)
]
@server.read_resource()
async def read_resource(uri: str):
if uri == "file:///config/settings.json":
return '{"theme": "dark", "language": "zh"}'
raise ValueError(f"Unknown resource: {uri}")
调试技巧#
# 使用 MCP Inspector 调试
npx @modelcontextprotocol/inspector python weather_server.py
# 查看 Claude Desktop 日志
tail -f ~/Library/Logs/Claude/mcp*.log
延伸#
- 传输方式:stdio(本地进程)、HTTP+SSE(远程服务)
- 安全考虑:Server 应限制文件访问路径、验证输入、记录日志
- 官方文档:modelcontextprotocol.io