MCP 协议详解与开发方法

Claude Code 学习笔记

分类:核心功能 > MCP 协议

核心主题:MCP(Model Context Protocol)协议深入解析与 MCP 服务器开发方法

主要内容:本文全面讲解 MCP 协议的设计原理、核心概念与架构,详细介绍使用 Python(FastMCP)和 TypeScript(SDK)开发 MCP 服务器的方法,涵盖配置管理、高级开发技术、调试测试、最佳实践及生态资源。包含丰富的代码示例、配置案例和实战经验总结。

关键词:MCP, Model Context Protocol, FastMCP, Python, TypeScript, MCP服务器, 工具开发, JSON-RPC, Anthropic, Claude Code

目录

  1. MCP 协议概述
  2. MCP 核心概念
  3. 开发环境搭建
  4. Python MCP 服务器开发
  5. TypeScript MCP 服务器开发
  6. MCP 服务器配置
  7. 高级开发技术
  8. 最佳实践与设计模式
  9. 调试与测试
  10. 生态与资源
  11. 核心要点总结

一、MCP 协议概述

MCP(Model Context Protocol)是 Anthropic 推出的一种开放标准协议,旨在为 AI 模型(LLM)与外部工具、数据源、服务之间建立统一的通信接口。可以将其理解为"AI 应用的 USB-C 接口"——它提供了一种标准化的方式,让 AI 应用能够发现、调用和交互各种外部能力。

一句话定义:MCP 是一种 JSON-RPC 协议,定义了 AI 模型与外部系统之间进行工具调用、资源访问和提示词交互的标准化接口。通过 MCP,Claude Code 等 AI 客户端可以像调用内置函数一样操作外部服务。

1.1 为什么需要 MCP

在 MCP 出现之前,让 AI 模型与外部系统交互的方式是零散的、非标准化的:有的使用函数调用(Function Calling),有的使用插件(Plugin),有的直接生成代码执行。每种方式都有各自的接口定义、认证机制和通信协议,导致开发者需要为每个 AI 平台编写不同的集成代码。

MCP 解决了以下核心问题:

MCP 类比:AI 的"USB-C"标准

就像 USB-C 统一了各种设备的连接方式一样,MCP 统一了 AI 模型与外部工具的连接方式。无论后端是数据库、API、文件系统还是第三方服务,MCP 服务器都提供一致的接口。这种标准化带来了巨大的生态优势:社区可以共享和复用 MCP 服务器实现。

1.2 客户端-服务器架构

MCP 采用典型的客户端-服务器(Client-Server)架构:

1.3 JSON-RPC 协议

MCP 基于 JSON-RPC 2.0 规范作为消息交换格式。JSON-RPC 是一种轻量级的远程过程调用协议,使用 JSON 格式编码请求和响应。

基本消息格式

// 请求(Request) { "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} } // 成功响应(Success Response) { "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "get_weather", "description": "获取指定城市的天气信息", "inputSchema": { "type": "object", "properties": { "city": { "type": "string" } } } } ] } } // 错误响应(Error Response) { "jsonrpc": "2.0", "id": 1, "error": { "code": -32603, "message": "Internal error", "data": { "details": "..." } } } // 通知(Notification,无响应) { "jsonrpc": "2.0", "method": "notifications/cancelled", "params": { "requestId": 1, "reason": "用户取消了操作" } }

标准错误码

错误码含义说明
-32700Parse ErrorJSON 解析错误
-32600Invalid Request请求格式无效
-32601Method Not Found方法不存在
-32602Invalid Params参数无效
-32603Internal Error服务器内部错误
-32000 ~ -32099Server Error服务器自定义错误

1.4 传输层(Transport Layer)

MCP 支持三种传输方式,适用于不同的部署场景:

传输方式通信机制适用场景特点
stdio标准输入/输出本地子进程模式最简单,MCP 服务器作为 Claude Code 的子进程运行;通过 stdin 发送请求,stdout 读取响应;适合开发和本地使用
HTTP + SSEHTTP POST + Server-Sent Events远程服务器模式客户端通过 HTTP POST 发送请求,服务器通过 SSE 推送响应;适合远程部署和团队共享;支持跨网络访问
Streamable HTTPHTTP 流式传输远程服务器模式最新的传输方式,在标准 HTTP 基础上支持流式响应;兼容现有的 HTTP 基础设施和工具(如 curl、浏览器);推荐用于生产环境

传输选型建议

开发阶段使用 stdio 模式最为简单——不需要启动 HTTP 服务器,不需要处理端口和网络配置。生产环境推荐 Streamable HTTP 模式,兼容性更好,且能利用现有的基础设施(负载均衡、反向代理、认证网关等)。

二、MCP 核心概念

MCP 协议定义了三大核心原语(Primitives):Tools(工具)Resources(资源)Prompts(提示词),以及一个可选的高级能力 Sampling(采样)

原语方向描述类比
Tools模型 -> 服务器AI 模型调用的可执行函数,用于执行操作类比 API 的 POST/PUT/DELETE
Resources服务器 -> 模型模型可读取的结构化数据,用于获取信息类比 API 的 GET
Prompts服务器 -> 模型预定义的提示词模板,用于引导模型行为类比 API 的模板/预设
Sampling服务器 -> 模型服务器请求模型生成文本(反向调用)类比回调函数

2.1 Tools(工具)

Tools 是 MCP 中最核心、最常用的原语。它们是由 MCP 服务器定义的可执行函数,AI 模型可以在对话过程中自动发现并调用。每个工具都有名称、描述和输入参数模式(JSON Schema)。

工具发现:tools/list

客户端通过 tools/list 方法获取服务器提供的所有工具列表。这是 MCP 握手的第一个步骤。

// 客户端请求工具列表 { "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} } // 服务器响应 { "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "get_weather", "description": "获取指定城市的天气信息", "inputSchema": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称" }, "units": { "type": "string", "enum": ["celsius", "fahrenheit"], "default": "celsius" } }, "required": ["city"] } } ] } }

工具调用:tools/call

客户端通过 tools/call 方法实际调用工具,并传递参数。

// 客户端调用工具 { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "city": "北京", "units": "celsius" } } } // 服务器响应(工具执行结果) { "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "北京当前天气:晴,25°C,湿度40%,微风" } ] } }

工具 vs 函数调用的区别

MCP 的 Tool 概念比传统 API 的"函数调用"更高级:

  • 动态发现:客户端可以在运行时发现工具列表,无需提前硬编码
  • 自描述:每个工具通过 JSON Schema 完整描述其输入,客户端可自动生成调用
  • 结果灵活:工具返回的结果是内容数组,可以包含文本、图像、嵌入资源等多种格式
  • 错误处理:工具执行结果和错误信息分离,模型可以正确处理异常情况

2.2 Resources(资源)

Resources 是 MCP 服务器暴露给模型的结构化数据。与 Tools 不同,Resources 不是由模型主动调用的,而是由服务器推送给客户端的。Resources 通过 URI 标识,支持文本和二进制内容。

资源列表:resources/list

// 客户端请求资源列表 { "jsonrpc": "2.0", "id": 1, "method": "resources/list", "params": {} } // 服务器响应 { "jsonrpc": "2.0", "id": 1, "result": { "resources": [ { "uri": "file:///data/report.pdf", "name": "Q4报告", "mimeType": "application/pdf", "description": "第四季度业务报告" } ] } }

资源读取:resources/read

// 客户端读取资源 { "jsonrpc": "2.0", "id": 2, "method": "resources/read", "params": { "uri": "file:///data/report.pdf" } }
Resources 的典型用途:
  • 文件系统中的文档、配置文件、日志文件
  • 数据库中的查询结果(以资源形式暴露)
  • API 返回的数据缓存
  • 项目中的代码文件、文档、图片
  • 环境信息和配置数据

2.3 Prompts(提示词)

Prompts 是服务器预定义的提示词模板,用于指导 AI 模型的行为。它们像是可复用的"交互模式",帮助模型更好地完成特定类型的任务。

// 提示词定义(服务器端) { "name": "code_review", "description": "代码审查提示词模板", "arguments": [ { "name": "language", "description": "编程语言", "required": true } ] } // 获取提示词 // 请求: prompts/get { "name": "code_review", "arguments": { "language": "python" } }

2.4 Sampling(采样)

Sampling 是一种反向调用机制——服务器可以请求 LLM 生成文本。这实现了服务器与 AI 模型的双向通信,使服务器能够利用模型的自然语言理解能力来辅助完成任务。

Sampling 的安全注意事项

Sampling 赋予服务器主动向 LLM 请求生成的能力,因此需要谨慎实现:

  • 始终在配置中明确允许 Sampling 功能
  • 对生成的内容进行审核和过滤
  • 避免将敏感数据传输给 Sampling 请求
  • 设置合理的 token 限制,防止滥用

三、开发环境搭建

开发 MCP 服务器需要准备相应的语言运行环境和工具链。MCP 官方提供了 Python 和 TypeScript 两个版本的 SDK。

3.1 Python 环境准备

Python MCP 开发推荐使用 FastMCP 框架(基于 MCP Python SDK 封装),它提供了更简洁的 API。

# 安装 Python(推荐 3.10+) # 下载地址: https://www.python.org/downloads/ # 安装 uv(推荐使用 MCP 的包管理器) # macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows PowerShell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" # 安装 MCP Python SDK / FastMCP uv pip install mcp fastmcp # 或者使用 pip pip install mcp fastmcp # 验证安装 python -c "import mcp; print(mcp.__version__)"

3.2 TypeScript/Node.js 环境准备

# 安装 Node.js(推荐 18+) # 下载地址: https://nodejs.org/ # 验证安装 node --version npm --version # 创建项目并安装 MCP SDK mkdir my-mcp-server cd my-mcp-server npm init -y npm install @modelcontextprotocol/sdk # 安装 TypeScript 相关依赖 npm install typescript @types/node ts-node npx tsc --init

3.3 项目结构规范

推荐的 MCP 服务器项目结构:

# Python MCP 项目结构 my-mcp-server/ ├── pyproject.toml # 项目配置和依赖 ├── src/ │ └── my_server/ │ ├── __init__.py # 入口文件,创建 FastMCP 应用 │ ├── tools.py # 工具定义 │ ├── resources.py # 资源定义 │ └── utils.py # 工具函数 └── tests/ └── test_tools.py # 单元测试 # TypeScript MCP 项目结构 my-mcp-server/ ├── package.json # 项目配置 ├── tsconfig.json # TypeScript 配置 ├── src/ │ ├── index.ts # 入口文件,创建 MCP 服务器 │ ├── tools.ts # 工具定义 │ └── types.ts # 类型定义 └── tests/ └── tools.test.ts # 单元测试

使用 npx -y 快速运行

对于基于 npm 包发布的 MCP 服务器,可以使用 npx -y 包名 直接运行,无需手动安装。Claude Code 的 MCP 配置中广泛使用了这种方式。例如:npx -y @modelcontextprotocol/server-filesystem

四、Python MCP 服务器开发

Python 是开发 MCP 服务器最常用的语言之一,得益于 FastMCP 框架的简洁设计,开发者可以快速创建功能完善的 MCP 服务器。

4.1 FastMCP 框架入门

FastMCP 是 MCP Python SDK 的高层封装,提供了类似 FastAPI 的开发体验——通过装饰器和类型注解即可定义工具。

# server.py - 最简单的 FastMCP 服务器 from fastmcp import FastMCP # 创建 MCP 服务器实例 mcp = FastMCP("my-tool-server") # 使用 @mcp.tool() 装饰器定义工具 @mcp.tool() def add(a: int, b: int) -> int: """计算两个数字的和""" return a + b @mcp.tool() def get_weather(city: str) -> str: """获取指定城市的天气信息""" # TODO: 接入真实天气 API return f"{city}的天气:晴,25°C" # 启动服务器(stdio 模式) if __name__ == "__main__": mcp.run()

4.2 定义复杂工具

FastMCP 支持 Pydantic 模型定义复杂参数结构:

from pydantic import BaseModel from typing import Optional, List from fastmcp import FastMCP mcp = FastMCP("advanced-tools") class SearchParams(BaseModel): query: str max_results: Optional[int] = 10 tags: Optional[List[str]] = None class SearchResult(BaseModel): title: str url: str snippet: str score: float @mcp.tool() def search_documents(params: SearchParams) -> List[SearchResult]: """搜索文档数据库,返回匹配结果列表""" # 模拟搜索结果 return [ SearchResult( title="MCP 协议介绍", url="https://example.com/mcp-intro", snippet="MCP 协议是 AI 模型与外部工具交互的标准", score=0.95 ) ]

4.3 异步工具

FastMCP 原生支持异步工具定义,适合 I/O 密集型操作:

import httpx from fastmcp import FastMCP mcp = FastMCP("async-tools") @mcp.tool() async def fetch_url(url: str) -> str: """获取指定 URL 的页面内容""" async with httpx.AsyncClient() as client: response = await client.get(url, timeout=30) response.raise_for_status() return response.text

4.4 定义 Resources

from fastmcp import FastMCP mcp = FastMCP("resource-server") # 定义一个静态资源 @mcp.resource("config://app") def get_config() -> str: """获取应用配置信息""" return "{\"version\": \"1.0\", \"debug\": false}" # 定义一个带参数资源的模板 @mcp.resource("doc://{path}") def get_document(path: str) -> str: """获取文档内容,路径格式如:readme、changelog""" import os doc_path = os.path.join("./docs", f"{path}.md") if os.path.exists(doc_path): with open(doc_path, "r") as f: return f.read() return "文档不存在" # 注册资源列表变更通知 @mcp.resource_notifier("doc://*") def notify_doc_change(): pass

4.5 错误处理

from fastmcp import FastMCP from mcp.types import ErrorData, INTERNAL_ERROR, INVALID_PARAMS mcp = FastMCP("robust-server") @mcp.tool() def divide(a: float, b: float) -> float: """安全的除法运算""" if b == 0: raise ValueError("除数不能为零") return a / b # 全局异常处理 @mcp.error_handler() def handle_error(error: Exception) -> ErrorData: if isinstance(error, ValueError): return ErrorData( code=INVALID_PARAMS, message=str(error) ) return ErrorData( code=INTERNAL_ERROR, message="服务器内部错误" )

4.6 测试服务器

# 直接运行服务器(stdio 模式) python server.py # 使用 MCP Inspector 测试 npx @modelcontextprotocol/inspector python server.py # 手动测试(发送 JSON-RPC 请求) echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | python server.py
FastMCP 优势总结:
  • 装饰器风格 API,类似 FastAPI 的开发体验
  • 自动类型推断和 JSON Schema 生成
  • 原生支持同步和异步工具
  • 内置资源管理和通知机制
  • 完善的错误处理框架
  • 自动处理 JSON-RPC 协议的细节

FastMCP vs 原生 MCP SDK

FastMCP 是对 MCP Python SDK 的高层封装,推荐用于大多数场景。如果需要更底层的控制(如自定义传输层、精细管理会话状态),可以直接使用 mcp.server.Server 类。MCP SDK 提供了完整的底层 API,包括请求处理、会话管理、传输抽象等。

五、TypeScript MCP 服务器开发

TypeScript MCP 服务器使用官方 @modelcontextprotocol/sdk 包进行开发。与 Python 的 FastMCP 不同,TypeScript SDK 提供了更贴近协议底层的 API,适合需要精细控制的场景。

5.1 创建基础服务器

// src/index.ts - 基础 TypeScript MCP 服务器 import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from "@modelcontextprotocol/sdk/types.js"; // 定义工具 const GREET_TOOL: Tool = { name: "greet", description: "向用户问好", inputSchema: { type: "object", properties: { name: { type: "string", description: "用户名", }, }, required: ["name"], }, }; // 创建服务器实例 const server = new Server( { name: "example-server", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); // 注册工具列表处理函数 server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [GREET_TOOL], })); // 注册工具调用处理函数 server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === "greet") { return { content: [ { type: "text", text: `你好,`${args.name}`!欢迎使用 MCP 服务器。`, }, ], }; } throw new Error(`未知工具: `${name}`); }); // 启动服务器 async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP 服务器已启动(stdio 模式)"); } main().catch(console.error);

5.2 package.json 配置

// package.json { "name": "my-mcp-server", "version": "1.0.0", "type": "module", "bin": { "my-mcp-server": "./dist/index.js" }, "scripts": { "build": "tsc", "start": "node ./dist/index.js", "inspector": "npx @modelcontextprotocol/inspector node ./dist/index.js" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" }, "devDependencies": { "@types/node": "^20.0.0", "typescript": "^5.0.0" } }

5.3 注册多个工具

import { z } from "zod"; // 使用 Zod 定义参数模式 const WeatherArgs = z.object({ city: z.string().describe("城市名称"), units: z.enum(["celsius", "fahrenheit"]).optional().default("celsius"), }); const WEATHER_TOOL: Tool = { name: "get_weather", description: "获取城市天气", inputSchema: { type: "object", properties: { city: { type: "string", description: "城市名称" }, units: { type: "string", enum: ["celsius", "fahrenheit"], default: "celsius", }, }, required: ["city"], }, }; const CALC_TOOL: Tool = { name: "calculate", description: "执行数学运算", inputSchema: { type: "object", properties: { expression: { type: "string", description: "数学表达式,如 2 + 3 * 4", }, }, required: ["expression"], }, }; // 注册多个工具 server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [WEATHER_TOOL, CALC_TOOL], })); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case "get_weather": { const { city, units } = WeatherArgs.parse(args); // TODO: 调用真实天气 API return { content: [{ type: "text", text: `${city}` 天气:晴,25°${units === "celsius" ? "C" : "F"` }], }; } case "calculate": { try { const result = Function(`'use strict'; return (`${args.expression}`)`)(); return { content: [{ type: "text", text: `结果: ${result}` }], }; } catch { return { content: [{ type: "text", text: "表达式无效" }], isError: true, }; } } default: throw new Error(`未知工具: ${name}`); } });

5.4 HTTP 传输模式

import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { HttpServerTransport } from "@modelcontextprotocol/sdk/server/http.js"; const server = new Server( { name: "http-server", version: "1.0.0" }, { capabilities: { tools: {} } } ); // ... 注册工具代码 ... async function main() { const transport = new HttpServerTransport({ port: 3000, endpoint: "/mcp", }); await server.connect(transport); console.log("MCP HTTP 服务器已启动,端口: 3000"); } main().catch(console.error);

TypeScript vs Python 开发选择

选择 Python(FastMCP):开发速度更快,代码更简洁,适合快速原型和中小型 MCP 服务器。Pydantic 类型系统简化了参数校验。

选择 TypeScript:更底层的 API,控制更精细,适合需要自定义传输层、复杂状态管理或与现有的 Node.js 生态集成的场景。TypeScript 的类型安全在大项目中优势明显。

六、MCP 服务器配置

MCP 服务器通过 Claude Code 的配置文件进行注册和管理。配置方式有三种:命令行管理、手动编辑 JSON 配置文件、以及环境变量注入。

6.1 配置文件位置

作用域配置文件路径生效范围
全局~/.claude/settings.json所有 Claude Code 会话
项目项目根目录/.claude/settings.json仅当前项目
本地(不提交)项目根目录/.claude/settings.local.json仅当前设备,可包含敏感信息

6.2 配置文件格式

// ~/.claude/settings.json - 完整的 MCP 配置示例 { "mcpServers": { // Python FastMCP 服务器 "my-python-server": { "command": "uvx", "args": ["my-mcp-server"] }, // TypeScript 服务器(通过 npx) "my-ts-server": { "command": "npx", "args": ["-y", "@myorg/mcp-server"] }, // 本地开发服务器(直接执行脚本) "local-dev": { "command": "python", "args": ["-m", "my_server"] }, // 带环境变量的服务器 "weather-server": { "command": "node", "args": ["./dist/server.js"], "env": { "API_KEY": "your-api-key", "BASE_URL": "https://api.weather.com" } }, // HTTP 远程服务器 "remote-server": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-remote"], "env": { "MCP_REMOTE_URL": "https://mcp.example.com/mcp" } } } }

6.3 claude mcp 命令

Claude Code 提供了一组 claude mcp 子命令,用于管理 MCP 服务器配置:

# 列出所有已配置的 MCP 服务器 claude mcp list # 查看特定服务器的详细信息 claude mcp get 服务器名称 # 添加新的 MCP 服务器(推荐方式) # 语法: claude mcp add <名称> -- <命令> [参数...] claude mcp add my-server -- python -m my_server # 带环境变量添加 API_KEY="xxx" claude mcp add my-server -- python -m my_server # 移除 MCP 服务器 claude mcp remove 服务器名称 # 测试 MCP 服务器连接 claude mcp test 服务器名称 # 查看 MCP 服务器日志 claude mcp logs 服务器名称

6.4 多服务器配置

Claude Code 支持同时运行多个 MCP 服务器。每个服务器提供不同的工具集合,Claude Code 会自动合并所有服务器的能力。

// 多服务器配置示例 { "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"] }, "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "你的GitHub令牌" } }, "database": { "command": "python", "args": ["-m", "db_mcp_server"] } } }
多服务器注意事项:
  • 每个服务器启动独立的进程,消耗系统资源
  • 工具名称需要在所有服务器间唯一,避免冲突
  • 服务器启动顺序不影响功能,Claude Code 会自动发现所有工具
  • 建议将常用的、稳定的服务器配置在全局 settings.json 中
  • 项目特定的服务器配置在项目级 settings.json 中

6.5 settings.local.json 使用

// .claude/settings.local.json - 用于存储敏感信息 // 此文件不会提交到版本控制 { "mcpServers": { "db-server": { "command": "python", "args": ["-m", "db_server"], "env": { "DB_HOST": "localhost", "DB_PORT": "5432", "DB_USER": "admin", "DB_PASSWORD": "your-password" } } } }

安全警告

API Key、令牌、密码等敏感信息:

  • 优先放在 settings.local.json 中(已被 .gitignore 忽略)
  • 不要在 settings.json 中硬编码敏感信息
  • 或者通过环境变量注入:API_KEY=xxx claude mcp add ...
  • 使用系统密钥管理工具(如 1Password、Bitwarden、系统密钥链)管理敏感信息

七、高级开发技术

本章介绍 MCP 服务器开发中的高级主题,包括认证、流式响应、进度报告、日志记录和无状态模式等。

7.1 认证(OAuth)

对于远程 MCP 服务器,OAuth 2.1 是推荐的认证方式。MCP 协议内置了 OAuth 授权流程的支持。

# Python 示例:OAuth 认证中间件 from fastmcp import FastMCP from authlib.integrations.httpx_client import OAuth2Client mcp = FastMCP("oauth-server") class OAuthMiddleware: def __init__(self): self.client = OAuth2Client( client_id="your-client-id", client_secret="your-client-secret", token_endpoint="https://auth.example.com/token" ) async def get_token(self) -> str: if not self.client.token: token = await self.client.fetch_token() return token["access_token"] return self.client.token["access_token"] auth = OAuthMiddleware() @mcp.tool() async def get_user_data(user_id: str) -> dict: """获取用户数据(需要 OAuth 认证)""" token = await auth.get_token() # 使用 token 调用受保护的 API return {"user_id": user_id, "data": "..."}

7.2 流式响应

MCP 支持流式传输结果,适用于长时间运行的操作或大量数据的返回。流式响应允许服务器在生成结果的过程中逐步发送数据,而不必等待全部完成。

from fastmcp import FastMCP import asyncio mcp = FastMCP("streaming-server") @mcp.tool() async def stream_logs(lines: int) -> str: """流式返回日志内容""" result = [] for i in range(lines): await asyncio.sleep(0.1) # 模拟延迟 result.append(f"日志行 {i + 1}: 处理完成") return "\n".join(result) // TypeScript 流式处理示例 // 利用 async generator 实现流式输出 async function* streamProcessor(items: string[]) { for (const item of items) { await processItem(item); yield { type: "text", text: `已处理: ${item}` }; } }

7.3 进度报告

对于耗时较长的工具调用,MCP 支持进度通知机制,服务器可以向客户端发送进度更新。

from fastmcp import FastMCP import asyncio mcp = FastMCP("progress-server") @mcp.tool() async def batch_process(items: list[str]) -> str: """批量处理数据,每处理一项发送进度通知""" total = len(items) for i, item in enumerate(items): await asyncio.sleep(0.5) # 模拟处理时间 # 发送进度通知 progress = (i + 1) / total * 100 await mcp.report_progress( progress=progress, message=f"正在处理第 {i + 1}/{total} 项" ) return f"成功处理 {total} 项数据"

7.4 日志记录

MCP 服务器可以使用标准日志框架进行日志记录。对于 stdio 模式的服务器,日志应输出到 stderr,避免干扰 stdout 上的 JSON-RPC 通信。

# Python 日志配置 import logging import sys # 配置日志(输出到 stderr) logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", stream=sys.stderr # 关键:使用 stderr ) logger = logging.getLogger("mcp-server") // TypeScript 日志配置 const logger = { info: (msg: string) => console.error(`[INFO] ${msg}`), error: (msg: string) => console.error(`[ERROR] ${msg}`), debug: (msg: string) => console.error(`[DEBUG] ${msg}`), };

7.5 无状态模式(Stateless Mode)

无状态模式适用于容器化和 Serverless 部署。在这种模式下,每个请求都是独立的,服务器不维护会话状态。

# Python 无状态模式示例 from fastmcp import FastMCP # 启用无状态模式 mcp = FastMCP( "stateless-server", stateless=True # 无状态模式 ) // Settings.json 配置无状态模式 // 对于 workspace-mcp 等支持无状态的服务器 { "mcpServers": { "my-server": { "command": "uvx", "args": ["my-server", "--stateless"] } } }
高级特性最佳实践:
  • OAuth 认证:始终使用 OAuth 2.1 标准流程,避免自己实现认证逻辑
  • 流式响应:对于大数据量返回(如日志、搜索结果),优先使用流式响应
  • 进度报告:耗时超过 5 秒的操作应提供进度通知,提升用户体验
  • 日志:始终使用 stderr 输出日志,stdio 只用于 JSON-RPC 通信
  • 无状态:优先设计无状态服务器,便于水平扩展和容器化部署

stderr 日志的重要性

这是 MCP 开发中最常见的错误之一。MCP 使用 stdout(标准输出)传输 JSON-RPC 消息,任何不应出现在 stdout 上的输出都会破坏协议通信。所有日志、调试信息、控制台输出都必须使用 stderr(标准错误)。在 Python 中,这意味着始终使用 logging 库或 print(..., file=sys.stderr)

八、最佳实践与设计模式

本章总结开发 MCP 服务器时的最佳实践和常用设计模式,帮助开发者创建高质量、易维护、安全的 MCP 服务器。

8.1 工具命名规范

规范说明示例
使用下划线命名工具名称使用 snake_caseget_weather, search_files
动词开头以动词开头描述操作create_document, delete_user
名称空间前缀多个服务时使用前缀避免冲突gmail_search, drive_list_files
描述清晰详细描述工具功能和参数作用description 字段使用中文完整说明
参数精简每个工具参数不超过 5 个复杂参数使用嵌套对象

8.2 错误处理模式

良好的错误处理是 MCP 服务器质量的衡量标准。以下是推荐的错误处理模式:

# Python 推荐错误处理模式 from fastmcp import FastMCP from typing import Union, Dict mcp = FastMCP("robust-server") class ToolError(Exception): """自定义工具错误,带有用户友好的错误信息""" def __init__(self, message: str, code: str = "UNKNOWN"): self.message = message self.code = code super().__init__(message) @mcp.tool() def process_data(data: str) -> Union[str, Dict]: """处理数据并返回结果""" try: # 1. 输入验证 if not data.strip(): raise ToolError("数据不能为空", "INVALID_INPUT") # 2. 业务逻辑 result = do_processing(data) # 3. 返回成功结果 return {"status": "success", "result": result} except ToolError as e: # 4. 返回用户友好的错误信息 return { "status": "error", "code": e.code, "message": e.message } except Exception as e: # 5. 记录未预期的错误 logger.exception("处理数据时发生未预期错误") return { "status": "error", "code": "INTERNAL", "message": "服务器内部错误,请稍后重试" }

8.3 资源发现设计模式

资源发现是 MCP 的重要能力。合理设计资源 URI 结构,可以帮助 AI 模型更有效地发现和使用资源。

# 推荐的资源 URI 模式 # 层次化设计资源 URI # 文件系统资源 # file:///docs/readme.md - 文档文件 # file:///config/app.json - 配置文件 # file:///logs/app.log - 日志文件 # 数据库资源 # db://users/list - 用户列表 # db://users/{id} - 单个用户详情 # db://orders/recent - 最近订单 # API 资源 # api://weather/beijing - 北京天气 # api://stocks/AAPL - 苹果股票信息 # 项目资源 # project://config - 项目配置 # project://status - 项目状态 # project://dependencies - 依赖列表

8.4 安全设计原则

MCP 服务器安全清单

  • 最小权限原则:工具只授予完成任务所需的最小权限,避免暴露危险操作
  • 输入验证:所有工具参数必须经过严格的类型和范围校验
  • 路径安全:涉及文件操作时,防止路径遍历攻击(Path Traversal)
  • 命令注入防护:避免将用户输入直接传递给 shell 命令
  • 速率限制:对敏感操作(如发送邮件、删除数据)实施速率限制
  • 确认机制:对不可逆操作(如删除、发送)提供二次确认
  • 审计日志:记录所有工具调用及其参数,便于追责和问题排查
  • 环境隔离:不将服务器私密信息(密钥、密码)暴露给 AI 模型

8.5 设计模式总结

设计模式适用场景实现方式
外观模式将复杂 API 封装为简单工具MCP 工具作为复杂后端服务的前端接口
适配器模式适配现有系统到 MCP 协议在 MCP 工具内部调用现有 API 或 SDK
验证器模式在调用前校验参数使用 Pydantic/Zod 做输入校验
重试模式处理临时性故障在工具内部实现指数退避重试
缓存模式提高重复查询性能对只读工具的结果进行缓存
断路器模式防止级联故障在依赖的外部服务不可用时快速失败
确认模式防止误操作在危险操作前要求客户端确认

九、调试与测试

MCP 服务器的调试和测试有专用的工具和技巧。本章介绍最常用的调试方法。

9.1 MCP Inspector

MCP Inspector 是官方提供的图形化调试工具,可以在浏览器中交互式地测试 MCP 服务器。

# 启动 MCP Inspector(需要 npx) # 测试 Python MCP 服务器 npx @modelcontextprotocol/inspector python my_server.py # 测试 TypeScript MCP 服务器 npx @modelcontextprotocol/inspector node dist/index.js # Inspector 会自动在浏览器中打开调试界面 # 你可以在界面中: # - 查看 tools/list 返回的工具列表 # - 手动调用工具并查看返回结果 # - 查看 resources/list 返回的资源列表 # - 检查 JSON-RPC 通信日志 # - 测试 prompts/list 和 prompts/get

9.2 手动测试

使用 stdio 模式,可以通过管道发送 JSON-RPC 请求进行手动测试:

# 手动发送 JSON-RPC 请求到 Python MCP 服务器 # 列出工具 echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | python my_server.py # 调用工具(注意转义特殊字符) echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"北京"}}}' | python my_server.py # 列出资源 echo '{"jsonrpc":"2.0","id":1,"method":"resources/list","params":{}}' | python my_server.py

9.3 单元测试

对 MCP 服务器的核心逻辑编写单元测试,确保工具的正确行为:

# tests/test_tools.py - Python 单元测试 import pytest from my_server.tools import add, get_weather class TestTools: def test_add(self): assert add(1, 2) == 3 assert add(-1, 1) == 0 assert add(0, 0) == 0 def test_add_invalid(self): with pytest.raises(TypeError): add("a", "b") def test_get_weather(self): result = get_weather("北京") assert "北京" in result assert "天气" in result // tests/tools.test.ts - TypeScript 单元测试 import { describe, it, expect } from "vitest"; import { add } from "../src/tools"; describe("add", () => { it("should add two positive numbers", () => { expect(add(1, 2)).toBe(3); }); it("should handle negative numbers", () => { expect(add(-1, 1)).toBe(0); }); });

9.4 常见问题排查

问题可能原因解决方案
claude mcp list 显示 disconnected服务器启动失败或配置路径错误检查命令路径是否正确;手动运行启动命令测试;查看日志
"MCP server exited unexpectedly"依赖缺失或运行时错误检查 Python/Node.js 版本;重新安装依赖;运行 claude mcp logs
工具调用无响应工具内部阻塞或异常添加超时机制;使用 Inspector 单独测试工具
JSON-RPC parse error协议消息格式错误使用 Inspector 检查消息格式;确保 JSON 语法正确
工具找不到tools/list 未正确实现检查 ListToolsRequestSchema 处理函数;确认工具已注册
参数校验失败Schema 定义与实现不匹配检查 inputSchema 与工具函数参数是否一致
Node.js 版本不兼容使用过旧的 Node.js升级到 Node.js 18+ 或 20+ LTS 版本
Windows 路径问题路径格式不正确使用正斜杠或双反斜杠;使用 path 模块处理路径
stdout 被污染不小心在 stdout 上打印了非 JSON 内容确保所有日志输出到 stderr;检查是否有 print() 语句

快速排错流程

遇到 MCP 服务器问题时,按以下顺序排查:

  1. claude mcp list -- 检查服务器是否已注册及状态
  2. claude mcp logs 服务器名 -- 查看服务器日志
  3. npx @modelcontextprotocol/inspector ... -- 使用 Inspector 图形化调试
  4. 手动发送 JSON-RPC 请求 -- 绕过 Claude Code 直接测试协议
  5. 重新添加服务器 -- claude mcp remove && claude mcp add
  6. 重启 Claude Code -- 解决大部分临时性问题

十、生态与资源

MCP 协议自发布以来,社区迅速构建了丰富的生态。本章汇总主流的 MCP 服务器、工具和资源。

10.1 官方 MCP 服务器

Anthropic 官方维护的 MCP 服务器(在 @modelcontextprotocol 命名空间下):

服务器名称功能包名
Filesystem安全的文件系统操作@modelcontextprotocol/server-filesystem
GitHubGitHub API 集成@modelcontextprotocol/server-github
GitGit 仓库操作@modelcontextprotocol/server-git
PostgreSQL数据库查询和执行@modelcontextprotocol/server-postgres
SQLiteSQLite 数据库管理@modelcontextprotocol/server-sqlite
Puppeteer浏览器自动化@modelcontextprotocol/server-puppeteer
SlackSlack 工作空间集成@modelcontextprotocol/server-slack
Google Maps地图和位置服务@modelcontextprotocol/server-google-maps
Memory知识图谱记忆系统@modelcontextprotocol/server-memory
Brave Search网络搜索集成@modelcontextprotocol/server-brave-search
Sequential Thinking增强推理能力@modelcontextprotocol/server-sequential-thinking

10.2 热门社区 MCP 服务器

服务器名称功能技术栈
Google Workspace MCP12 项 Google 服务集成(Gmail、Drive、Calendar 等)Python (FastMCP)
gmail-multi-mcp零配置 Gmail 多账号管理TypeScript
gmail-autoauth-mcp精细 OAuth 控制的 Gmail 集成TypeScript
Composio850+ 应用集成的托管 MCP 平台Python/托管
Nylas跨邮件提供商(Gmail+Outlook)Python/托管
Coogle守护进程模式的多会话 Google 服务Python
MCPHubMCP 服务器发现和管理的中心化平台Python
Blender MCP通过自然语言操控 Blender 3DPython
Docker MCPDocker 容器管理TypeScript
Kubernetes MCPK8s 集群管理TypeScript
Cloudflare MCPCloudflare 服务管理TypeScript
Jira MCPJira 项目管理TypeScript
Notion MCPNotion 页面操作TypeScript
Obsidian MCPObsidian 知识库交互Python
Playwright MCPPlaywright 浏览器自动化TypeScript

10.3 社区工具与平台

10.4 官方资源

生态展望:MCP 生态正在快速增长。随着更多开发者和企业加入,MCP 正在成为 AI 模型与外部系统交互的事实标准。截至 2026 年,社区已开发超过 1000 个 MCP 服务器,覆盖从开发工具到企业服务的几乎所有领域。掌握 MCP 开发方法,将成为 AI 应用开发的核心技能。

核心要点总结

  1. MCP 是 AI 模型与外部世界的标准化接口:采用 JSON-RPC 协议,基于客户端-服务器架构,支持 Tools(工具)、Resources(资源)、Prompts(提示词)三大核心原语,以及 Sampling(采样)反向调用能力。
  2. 三种传输方式适配不同场景:stdio 适合本地开发和子进程模式,HTTP+SSE 适合远程部署,Streamable HTTP 是推荐的生产环境传输方式。
  3. Python FastMCP 是最快的开发方式:装饰器风格 API、自动类型推断、JSON Schema 生成,让开发者可以快速创建功能完善的 MCP 服务器。适合快速原型和中小型项目。
  4. TypeScript SDK 提供更底层的控制:适合需要精细控制传输层、状态管理或深度集成 Node.js 生态的场景。类型安全在大项目中优势明显。
  5. 配置管理三渠道:全局 settings.json、项目 settings.json 和本地 settings.local.json 三级配置体系,支持命令行(claude mcp)和手动编辑两种管理方式。
  6. 高级特性提升服务器质量:OAuth 认证、流式响应、进度报告、stderr 日志记录、无状态模式——这些高级特性将简易服务器升级为生产级系统。
  7. 安全是开发的第一原则:最小权限、输入验证、路径安全、命令注入防护、速率限制、二次确认——MCP 服务器的每个工具都应该是安全的。
  8. MCP Inspector 是调试利器:图形化界面让调试变得直观。配合手动 JSON-RPC 测试和单元测试,形成完整的测试体系。
  9. 生态正在爆发式增长:官方 10+ 服务器、社区 1000+ 服务器、覆盖开发工具到企业服务。Google Workspace、GitHub、数据库、文件系统等常见场景都有成熟的 MCP 实现。
  10. MCP 正在成为 AI 集成的标准协议:掌握 MCP 开发方法,就是掌握 AI 应用开发的核心技能。标准化意味着一次开发、多处部署——这是未来 AI 工具开发的基石。

MCP 开发的学习路径建议

  1. 先理解协议:深入理解 JSON-RPC 消息格式、三种原语的用途和生命周期
  2. 从 Python FastMCP 入手:用最少的代码创建你的第一个 MCP 服务器,体会开发流程
  3. 掌握配置部署:学会将 MCP 服务器配置到 Claude Code 中,理解三种配置文件的区别
  4. 深入研究 TypeScript SDK:当需要更精细的控制时,切换到 TypeScript 开发
  5. 应用高级特性:逐步引入认证、流式、进度报告等高级功能
  6. 关注生态:定期浏览 MCPHub 和官方仓库,了解新的 MCP 服务器和最佳实践
  7. 贡献社区:发布自己的 MCP 服务器到 npm 或 PyPI,成为 MCP 生态的贡献者
20168