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 Registrymcp.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