MCP知识体系与实战指南
生成日期:2026-05-09
资料口径:联网核对官方来源后整理。MCP 官方规范当前最新版本为 2025-11-25。优先采用 Model Context Protocol 官方站点、官方 GitHub SDK、Anthropic/OpenAI 官方文档。
阅读目标:先建立 MCP 的完整认知框架,再能独立写一个本地 MCP Server、接入客户端、调试、做安全评审,并判断什么时候该做本地 stdio、什么时候该做远程 Streamable HTTP。
1. 一句话理解 MCP
MCP(Model Context Protocol)是一个开放协议,用标准方式把 LLM 应用连接到外部数据、工具和工作流。
它解决的问题不是“怎么调用某个模型”,而是:
- LLM 应用如何发现外部能力。
- 外部系统如何声明可用工具、资源、提示词。
- 工具参数、返回值、错误、权限、生命周期如何标准化。
- 本地工具和远程服务如何用统一协议接入不同 AI 客户端。
可以把 MCP 理解为 AI 应用生态里的“上下文与工具连接协议”。类似 LSP 统一编辑器和语言服务的连接方式,MCP 统一 LLM Host 和外部能力的连接方式。
2. 先把术语讲清楚
2.1 三个核心角色
用户
|
v
Host:AI 应用,例如 Claude Desktop、IDE、ChatGPT、内部 Agent 平台
|
| 一个 Host 可以管理多个 MCP Client 连接
v
Client:Host 内部的连接器,每个 Client 通常对应一个 Server 会话
|
| JSON-RPC 2.0 over stdio / Streamable HTTP
v
Server:暴露工具、资源、提示词等能力的程序或远程服务
- Host:用户实际使用的 AI 产品或 Agent 容器,负责 UI、用户授权、模型调用、连接生命周期。
- Client:Host 内部实现 MCP 协议的一端,负责与一个 MCP Server 通信。
- Server:提供能力的一端,可以是本地进程,也可以是远程 HTTP 服务。
2.2 MCP Server 能暴露什么
Server 主要暴露三类能力:
| 能力 | 控制方 | 用途 | 例子 |
|---|---|---|---|
| Tools | 模型可发起,Host 应要求用户确认高风险动作 | 执行动作、查询 API、计算 | search_docs、create_ticket、query_db |
| Resources | 应用/用户/模型按实现选择读取 | 给模型补上下文 | 文件、数据库 schema、文档片段、日志 |
| Prompts | 用户显式选择更合理 | 可复用提示词模板 | 代码审查模板、SQL 诊断模板 |
Client 也可以暴露能力给 Server:
| 能力 | 方向 | 用途 |
|---|---|---|
| Roots | Client -> Server | 告诉 Server 可访问的工作区边界 |
| Sampling | Server -> Client -> LLM | Server 请求 Client 代为调用模型 |
| Elicitation | Server -> Client -> 用户 | Server 通过 Client 向用户要额外信息 |
3. MCP 的分层知识体系
3.1 Base Protocol
MCP 基于 JSON-RPC 2.0:
- Request:有
id,期待 Response。 - Response:同一个
id返回result或error。 - Notification:没有
id,不期待响应。 - 消息必须 UTF-8 编码。
- MCP 的
id不能是null,同一会话内请求方不能复用请求 ID。
MCP 还规定了生命周期:
- Client 建立传输连接。
- Client 发送
initialize,声明协议版本、客户端信息、能力。 - Server 返回协议版本、服务端信息、能力。
- Client 发送
initialized通知。 - 双方进入正常交互阶段。
- 结束连接,释放资源。
3.2 Capability Negotiation
MCP 的能力必须协商。不要假设对方支持某功能。
常见能力:
- Server:
tools、resources、prompts、logging、completions、tasks。 - Client:
roots、sampling、elicitation、tasks。
工程原则:
- Server 没声明
tools,Client 不该调用tools/list。 - Client 没声明
sampling,Server 不该发sampling/createMessage。 - 支持
listChanged才发送列表变更通知。 - 支持
tasks才做异步任务增强请求。
3.3 Schema
MCP 大量使用 JSON Schema:
- 工具输入:
inputSchema。 - 工具结构化输出:
outputSchema。 - elicitation 表单:受限制的 JSON Schema 子集。
- 默认 schema dialect:JSON Schema
2020-12。 - 显式
$schema可以指定别的 dialect,但实现至少应支持 2020-12。
实战建议:
- 工具参数 schema 要严格,尽量
additionalProperties: false。 - 不要把自然语言描述当校验逻辑。
- 对外部输入做二次校验,schema 只是第一层。
- 返回结构化数据时同时提供
structuredContent和可读content,兼容旧客户端。
4. 传输层:stdio 与 Streamable HTTP
4.1 stdio
stdio 是本地 MCP Server 最常见的传输方式。
机制:
- Host/Client 启动 Server 子进程。
- Client 写 Server 的 stdin。
- Server 写 stdout。
- 每行是一条 JSON-RPC 消息。
- 日志只能写 stderr 或文件,不能写 stdout。
适用场景:
- 本地文件系统工具。
- 本地 Git/代码库工具。
- 只给单个用户本机使用的工具。
- IDE、桌面应用、CLI Agent。
关键禁忌:
- Python 不要
print()到 stdout,除非明确输出 MCP JSON-RPC。 - TypeScript 不要
console.log()到 stdout。 - 日志用
stderr、标准 logging、文件日志。
4.2 Streamable HTTP
Streamable HTTP 是远程/生产部署更重要的传输方式。官方规范中它取代了早期的 HTTP+SSE 传输。
机制:
- Server 提供一个 MCP endpoint,例如
/mcp。 - Client 用 HTTP POST 发送 JSON-RPC 消息。
- Server 可以返回 JSON,也可以返回 SSE 流。
- Client 可以 GET endpoint 来接收 Server 主动消息。
- 支持 session、恢复、重连、轮询式 SSE。
适用场景:
- 多用户远程 MCP 服务。
- 企业内统一工具平台。
- SaaS 给 AI Host 提供官方 MCP Server。
- ChatGPT/Claude API 等远程连接。
生产要求:
- 必须校验
Origin,防 DNS rebinding。 - 本地 HTTP Server 默认绑定
127.0.0.1,不要裸绑0.0.0.0。 - 远程 Server 必须做认证授权。
- 浏览器客户端要正确设置 CORS,并暴露
Mcp-Session-Id。
5. Server Features:Tools、Resources、Prompts
5.1 Tools
Tools 是 MCP 最常用、也最危险的能力。它让模型能调用外部函数。
工具定义包含:
name:唯一名称,建议只用 ASCII 字母、数字、_、-、.。title:给 UI 展示的人类可读名称。description:功能说明,会影响模型是否调用。inputSchema:参数 JSON Schema。outputSchema:可选,结构化输出 schema。annotations:可选的行为描述,不应被无条件信任。execution.taskSupport:是否支持 task-augmented execution。
常用协议方法:
tools/list:列工具。tools/call:调用工具。notifications/tools/list_changed:工具列表变更通知。
工具错误分两类:
- Protocol Error:未知工具、请求结构错误、协议级错误。
- Tool Execution Error:业务错误、输入不合法、外部 API 失败,返回
isError: true,模型可能据此自我修正后重试。
设计工具的核心原则:
- 小而准:一个工具只做一个明确动作。
- 参数强约束:枚举、格式、范围、必填字段都写进 schema。
- 描述写“何时使用/何时不用”,不要只写“调用某 API”。
- 高风险写操作必须让 Host/用户可确认。
read与write分开,不要一个工具既查又改。- 不要把密钥、内部路径、系统提示词塞进 tool description。
5.2 Resources
Resources 是 Server 暴露给 Client 的上下文数据。每个 resource 用 URI 唯一标识。
典型资源:
file:///repo/README.mdgit://repo/commit/abc123db://analytics/schema/ordersdocs://product/api/auth
常用协议方法:
resources/list:列资源。resources/read:读资源内容。resources/templates/list:列参数化 URI 模板。resources/subscribe:订阅资源变更。notifications/resources/updated:资源更新。notifications/resources/list_changed:资源列表更新。
Resource 内容可以是:
text:文本。blob:base64 二进制。
实战建议:
- 大文档不要一次塞完整,优先暴露搜索工具 + fetch 工具。
- URI 要稳定,便于缓存和引用。
- MIME type 要准确,例如
text/markdown、application/json。 - 私有资源必须按用户身份过滤。
- 不要让 Resource 绕过 Tool 的权限控制。
5.3 Prompts
Prompts 是 Server 提供的可复用提示词模板,通常由用户显式选择。
常用协议方法:
prompts/list:列模板。prompts/get:按参数生成 prompt messages。notifications/prompts/list_changed:模板列表变更。
适用场景:
- 固化高质量工作流,例如“代码审查”“生成迁移方案”“事故复盘”。
- 把团队内部方法论封装为可选择模板。
- 将 Resource 嵌入 Prompt,形成可靠上下文。
Prompt 设计建议:
- 模板参数要少,参数名明确。
- 输出格式要求写清楚。
- 不要把敏感策略或密钥写进 prompt。
- 让用户能看见并选择,而不是暗中自动注入。
6. Client Features:Roots、Sampling、Elicitation
6.1 Roots
Roots 是 Client 告诉 Server 的文件系统边界。
作用:
- Server 可以知道当前工作区有哪些目录。
- Server 应只在这些边界内读写。
- Roots 变更时,Client 可通知 Server。
实战建议:
- 本地文件工具必须把 roots 当权限边界,而不是 UI 提示。
- 路径要 canonicalize,防
..、symlink、大小写绕过。 - 默认最小权限,只暴露当前项目,不暴露整个 home 目录。
6.2 Sampling
Sampling 允许 Server 请求 Client 代为调用 LLM。
典型用途:
- Server 内部需要模型判断,但不想持有模型 API key。
- Server 想把部分推理交给 Host 控制的模型。
- Server 实现复杂 agentic workflow。
安全原则:
- 用户应能查看和拒绝 sampling 请求。
- 用户应能查看/编辑即将发给模型的 prompt。
- Server 不应假设可以访问任意模型。
- Client 应控制模型选择、token、权限和可见上下文。
最新规范点:
2025-11-25增强了 sampling 的 tool calling 支持。includeContext: "thisServer" / "allServers"属于 soft-deprecated,用时要谨慎。
6.3 Elicitation
Elicitation 允许 Server 通过 Client 向用户索取额外信息。
两种模式:
- Form mode:Client 展示表单,收集结构化非敏感信息。
- URL mode:跳转到外部 URL,处理敏感凭据、OAuth、支付等流程。
重点:
- Form mode 不能索要密码、API key、access token、支付凭据。
- 敏感信息必须走 URL mode,且用户要看到目标域名并授权跳转。
- Server 不能只靠 session ID 绑定敏感状态,应绑定真实用户身份或授权上下文。
7. 2025-11-25 规范重点变化
这一版相对 2025-06-18 的关键变化:
- 增强授权服务器发现,支持 OpenID Connect Discovery。
- tools/resources/prompts/resource templates 增加 icons 元数据。
- 授权流增加基于
WWW-Authenticate的增量 scope consent。 - 明确工具命名建议。
- Elicitation enum/schema 更贴近标准 JSON Schema。
- 新增 URL mode elicitation。
- Sampling 支持 tool calling。
- 新增 OAuth Client ID Metadata Documents,作为推荐 client registration 机制之一。
- 新增实验性 Tasks,用于持久请求、轮询和延迟结果获取。
- JSON Schema
2020-12成为默认 dialect。 - Streamable HTTP 的 Origin 校验、SSE 轮询/恢复说明更明确。
- 安全最佳实践更新。
8. Tasks:异步和长任务
Tasks 是 2025-11-25 新增的实验能力,适合耗时任务。
适用场景:
- 大文件索引。
- 批量数据导入。
- 长时间报表计算。
- 异步外部 API workflow。
基本模型:
- 请求方在原请求参数里加
task。 - 接收方立即返回
taskId和状态。 - 请求方用
tasks/get查状态。 - 完成后用
tasks/result取结果。 - 可选
notifications/tasks/status主动通知状态变化。 - 可用
tasks/cancel取消。
状态:
workinginput_requiredcompletedfailedcancelled
安全要求:
taskId必须不可预测。- 有授权上下文时,task 必须绑定用户/客户端身份。
tasks/list只能返回当前请求方有权访问的任务。- 没有身份绑定能力的服务,不建议声明
tasks.list。 - 设置 TTL、并发上限、轮询限流、审计日志。
9. 授权与安全体系
9.1 授权
MCP Authorization 主要针对 HTTP-based transport。stdio 不走这套授权,通常从环境变量或本地配置取凭据。
HTTP MCP 中:
- MCP Server 作为 OAuth Resource Server。
- MCP Client 作为 OAuth Client。
- Authorization Server 负责用户认证和发 token。
- 规范基于 OAuth 2.1、RFC 8414、RFC 7591、RFC 9728、OAuth Client ID Metadata Documents 等标准子集。
生产建议:
- 远程 MCP Server 默认要求 HTTPS。
- token audience 必须绑定到 MCP Server。
- 不要做 token passthrough。
- scope 最小化。
- 每个用户、每个客户端、每个下游 API 单独记录授权关系。
9.2 高风险攻击面
| 风险 | 解释 | 防护 |
|---|---|---|
| Prompt Injection | 外部网页/邮件/文档夹带恶意指令,诱导模型调用工具泄露数据 | 工具最小权限、写操作确认、敏感数据隔离、输出过滤 |
| Confused Deputy | MCP proxy 代用户访问第三方 API 时,被恶意 client 借权 | per-client consent、严格 redirect URI、CSRF state、scope 展示 |
| Token Passthrough | Server 接受不是发给自己的 token 并转发 | 禁止;校验 issuer/audience/scope |
| SSRF | 恶意 Server 让 Client 拉内网/metadata URL | HTTPS、私网 IP 阻断、redirect 校验、egress proxy |
| Session Hijacking | 攻击者拿到 session ID 后冒用 | session 不当认证凭据;绑定用户;安全随机;过期轮换 |
| Local Server Compromise | 一键安装/启动本地恶意命令 | 展示完整命令、用户确认、危险命令警告、沙箱 |
| Tool Definition Abuse | 工具描述或 annotation 欺骗 Host/模型 | 不信任未知 Server 的 annotations;用户确认高风险操作 |
9.3 安全评审清单
上线前逐项检查:
- Server 来源可信,依赖包可信。
- 本地 stdio Server 没有向 stdout 写日志。
- HTTP Server 校验
Origin。 - 本地 HTTP Server 只绑定
127.0.0.1。 - 远程 HTTP Server 只走 HTTPS。
- 每个 tool 都有严格
inputSchema。 - 写操作 tool 独立命名,且明显可识别。
- destructive 操作需要用户确认。
- 不在 tool description/resource/prompt 中暴露密钥。
- 不接受未发给本 MCP Server 的 token。
- token 校验 issuer、audience、scope、expiry。
- task、session、resource 都绑定用户授权上下文。
- SSRF 防护覆盖 OAuth metadata discovery 和 redirect。
- 日志脱敏,避免记录 access token、API key、用户隐私。
- 对外部 API 设置 timeout、重试、限流、熔断。
- 有审计日志:谁在什么时候调用了什么 tool,输入输出摘要是什么。
10. 实战一:Python 写一个本地 MCP Server
目标:写一个本地知识库工具,暴露两个工具:
search_notes(keyword):搜索当前目录下.md文件名和内容。read_note(path):读取指定 Markdown 文件。
10.1 创建项目
uv init mcp-notes-server
cd mcp-notes-server
uv add "mcp[cli]"
10.2 写 server.py
from pathlib import Path
from typing import Any
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("notes-server")
ROOT = Path.cwd().resolve()
def safe_path(path: str) -> Path:
candidate = (ROOT / path).resolve()
if ROOT not in candidate.parents and candidate != ROOT:
raise ValueError("path is outside the allowed workspace")
return candidate
@mcp.tool()
def search_notes(keyword: str, limit: int = 20) -> list[dict[str, Any]]:
"""Search markdown notes in the current workspace by keyword."""
if not keyword.strip():
raise ValueError("keyword must not be empty")
results: list[dict[str, Any]] = []
for file in ROOT.rglob("*.md"):
if len(results) >= limit:
break
try:
text = file.read_text(encoding="utf-8", errors="ignore")
except OSError:
continue
if keyword.lower() in file.name.lower() or keyword.lower() in text.lower():
results.append(
{
"path": str(file.relative_to(ROOT)),
"title": file.stem,
"preview": text[:300],
}
)
return results
@mcp.tool()
def read_note(path: str) -> str:
"""Read a markdown note by relative path within the workspace."""
file = safe_path(path)
if file.suffix.lower() != ".md":
raise ValueError("only markdown files are allowed")
if not file.exists() or not file.is_file():
raise FileNotFoundError("file not found")
return file.read_text(encoding="utf-8", errors="ignore")
@mcp.resource("notes://index")
def notes_index() -> str:
"""List markdown files in the workspace."""
files = sorted(str(p.relative_to(ROOT)) for p in ROOT.rglob("*.md"))
return "\n".join(files)
@mcp.prompt()
def summarize_note(path: str) -> str:
return (
"请阅读这篇笔记,输出:核心观点、关键概念、可行动清单、"
f"未解决问题。笔记路径:{path}"
)
if __name__ == "__main__":
mcp.run(transport="stdio")
10.3 本地运行
uv run server.py
stdio Server 直接运行后会等待 MCP JSON-RPC 输入,不会像普通 Web 服务那样输出提示信息。
10.4 用 MCP Inspector 调试
npx @modelcontextprotocol/inspector uv --directory /ABSOLUTE/PATH/mcp-notes-server run server.py
在 Inspector 里检查:
- Tools tab 是否出现
search_notes、read_note。 - Resource tab 是否出现
notes://index。 - Prompt tab 是否出现
summarize_note。 - 调用
search_notes是否返回结构清晰结果。 - 输入非法路径,例如
../../.ssh/id_rsa,是否被拒绝。
10.5 接入 Claude Desktop
macOS 配置文件:
~/Library/Application Support/Claude/claude_desktop_config.json
Windows 配置文件:
%APPDATA%\Claude\claude_desktop_config.json
示例:
{
"mcpServers": {
"notes": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/mcp-notes-server",
"run",
"server.py"
]
}
}
}
重启 Claude Desktop 后,让它搜索某个关键词或读取某篇笔记。
11. 实战二:TypeScript 写一个 MCP Server
适用:Node.js 生态、npm 分发、前端/平台团队更熟悉 TypeScript 的情况。
版本注意:TypeScript SDK 官方仓库的 main README 已经展示 v2 分包 API,并明确说明 v2 仍处于 pre-alpha;同时仓库 release 页显示 v1.x 仍是生产推荐线。下面示例按当前官方 README 的 v2 分包 API 编写,用于学习最新结构;生产项目应根据目标 Host 和 SDK 稳定性,优先 pin 官方推荐的稳定 v1.x,或在评估后再使用 v2。
11.1 创建项目
mkdir mcp-notes-ts
cd mcp-notes-ts
npm init -y
npm install @modelcontextprotocol/server zod@4
npm install -D typescript @types/node
package.json:
{
"type": "module",
"scripts": {
"build": "tsc"
}
}
tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}
11.2 写 src/index.ts
import { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { readFile, readdir } from "node:fs/promises";
import { resolve, relative, join } from "node:path";
import * as z from "zod/v4";
const root = process.cwd();
function safePath(input: string): string {
const candidate = resolve(root, input);
const rel = relative(root, candidate);
if (rel.startsWith("..") || rel === ".." || rel.startsWith("/")) {
throw new Error("path is outside the allowed workspace");
}
return candidate;
}
async function listMarkdownFiles(dir: string): Promise<string[]> {
const entries = await readdir(dir, { withFileTypes: true });
const files: string[] = [];
for (const entry of entries) {
const full = join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...(await listMarkdownFiles(full)));
} else if (entry.isFile() && entry.name.endsWith(".md")) {
files.push(full);
}
}
return files;
}
const server = new McpServer({
name: "notes-ts",
version: "1.0.0",
});
server.registerTool(
"read_note",
{
description: "Read a markdown note by relative path inside the current workspace.",
inputSchema: z.object({
path: z.string().min(1),
}),
},
async ({ path }) => {
const full = safePath(path);
if (!full.endsWith(".md")) {
return {
isError: true,
content: [{ type: "text", text: "Only markdown files are allowed." }],
};
}
const text = await readFile(full, "utf8");
return {
content: [{ type: "text", text }],
};
},
);
server.registerTool(
"list_notes",
{
description: "List markdown note paths in the current workspace.",
inputSchema: z.object({}),
},
async () => {
const files = await listMarkdownFiles(root);
const paths = files.map((file) => relative(root, file));
return {
structuredContent: { paths },
content: [{ type: "text", text: JSON.stringify({ paths }, null, 2) }],
};
},
);
const transport = new StdioServerTransport();
await server.connect(transport);
11.3 构建和调试
npm run build
npx @modelcontextprotocol/inspector node dist/index.js
stdio 模式下不要用 console.log() 打日志;需要日志用 console.error()。
12. 实战三:远程 Streamable HTTP Server
Python 官方 SDK 支持 Streamable HTTP:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("remote-notes", stateless_http=True, json_response=True)
@mcp.tool()
def ping() -> dict[str, str]:
"""Health check tool."""
return {"status": "ok"}
if __name__ == "__main__":
mcp.run(transport="streamable-http")
默认路径通常是:
http://localhost:8000/mcp
远程上线要补齐:
- TLS/HTTPS。
- OAuth 或企业内认证。
Origin校验。- CORS 白名单。
- rate limit。
- structured logs。
- health check。
- per-user authorization。
- deployment secrets 管理。
13. 实战四:给 OpenAI / Anthropic 这类 Host 使用
13.1 Anthropic Messages API MCP connector
Anthropic 官方 Messages API 支持直接连接远程 MCP Server,但有边界:
- 需要 beta header。
- 支持远程 URL Server。
- 目前重点支持 MCP tools。
- 本地 stdio Server 不能被 API 直接连接。
- 可配置 allowlist/denylist/per-tool settings。
- OAuth token 由 API 调用方先获取并传入。
适合:
- 你有公网 HTTPS MCP Server。
- 你只需要暴露工具给 Claude API。
- 不需要 Client 侧 roots、本地文件、prompts/resources 的完整控制。
13.2 OpenAI ChatGPT Apps / Responses API
OpenAI 官方文档中,远程 MCP Server 可用于 ChatGPT Apps、deep research、API integrations。
典型数据类 MCP Server 需要实现:
search:返回候选结果。fetch:按 ID 拉取完整内容和引用。
Responses API 使用 MCP 工具时,核心配置类似:
{
"tools": [
{
"type": "mcp",
"server_label": "docs",
"server_url": "https://example.com/sse/",
"allowed_tools": ["search", "fetch"],
"require_approval": "never"
}
]
}
注意:
- Deep research/API 场景通常要求远程可访问。
- 对自定义 MCP Server 要格外关注 prompt injection 和写操作风险。
- 不要连接未知第三方代理的“某某官方服务 MCP”,优先选择服务商自己托管的官方 Server。
14. MCP Server 设计范式
14.1 工具粒度
差设计:
manage_database(query: string)
问题:权限过大、语义不清、不可审计。
好设计:
list_tables()
describe_table(table: enum)
run_readonly_query(sql: string)
create_report(name: string, query_id: string)
优势:
- Host 能做更清晰的权限和确认。
- 模型更容易选对工具。
- 日志和审计更准确。
- 更容易做 schema 校验。
14.2 Read 与 Write 分离
只读工具:
search_docsget_customerlist_orderspreview_email
写操作工具:
send_emailrefund_orderdelete_filecreate_jira_ticket
写操作必须:
- 名称明确。
- 参数明确。
- 支持 dry-run 或 preview。
- 有用户确认。
- 有幂等键或重复提交保护。
14.3 Search + Fetch 模式
面向文档、知识库、RAG 的 MCP Server 推荐采用:
search(query, filters):返回短列表,包含id/title/url/snippet。fetch(id):返回完整内容、引用、元数据。
好处:
- 降低上下文浪费。
- 便于 deep research 类 Host 多轮检索。
- 结果可引用。
- 权限更容易按文档粒度控制。
14.4 Structured Output
如果工具返回数据给后续程序使用,应提供结构化输出:
{
"structuredContent": {
"order_id": "ord_123",
"status": "paid",
"amount": 199.0
},
"content": [
{
"type": "text",
"text": "{\"order_id\":\"ord_123\",\"status\":\"paid\",\"amount\":199.0}"
}
]
}
同时保留 content 是为了兼容旧客户端和模型可读性。
15. 调试方法论
15.1 先用 Inspector
npx @modelcontextprotocol/inspector <command> <args>
检查项:
- initialize 是否成功。
- capabilities 是否符合预期。
- tools/resources/prompts 是否能列出来。
- tool schema 是否正确。
- 非法输入是否返回
isError: true或合理协议错误。 - stdout 是否被日志污染。
- notifications 是否正常。
15.2 再接真实 Host
连接真实 Host 前先确认:
- 绝对路径正确。
- 运行命令在普通终端能启动。
- 依赖已安装。
- 环境变量存在。
- API key 不写进配置文件。
- Server 不依赖交互式输入。
15.3 常见问题
| 问题 | 可能原因 | 处理 |
|---|---|---|
| Host 找不到工具 | Server 未启动、initialize 失败、capability 未声明 | 用 Inspector 看握手 |
| JSON parse error | stdout 混入日志 | 日志改 stderr |
| tool 调用后无响应 | 外部 API 卡住 | timeout、错误捕获 |
| 路径读取越权 | 未做 canonicalize | resolve 后检查 roots |
| HTTP 被网页攻击 | 未校验 Origin | 403 拒绝非法 Origin |
| Claude/ChatGPT 不调用工具 | 描述不清、schema 太宽、工具名不语义化 | 重写 tool description |
16. 学习路线
阶段 1:基本认知
- 搞清 Host / Client / Server。
- 理解 tools/resources/prompts。
- 理解 stdio 和 Streamable HTTP。
- 用 Inspector 连一个现成 filesystem server。
阶段 2:本地实战
- 写一个 Python FastMCP Server。
- 暴露 2 个只读工具。
- 接入 Claude Desktop 或支持 MCP 的 IDE。
- 加路径安全检查。
阶段 3:生产化
- 改造成 Streamable HTTP。
- 加 OAuth 或内部认证。
- 加结构化日志、审计、限流、监控。
- 做 tool 风险分级。
阶段 4:生态集成
- 适配 OpenAI/Anthropic 的远程 MCP 接入。
- 实现 search/fetch 模式。
- 发布 server metadata。
- 设计企业内部 MCP Registry 或聚合层。
17. 权威资料索引
官方规范与文档:
- MCP 最新规范
2025-11-25:https://modelcontextprotocol.io/specification/2025-11-25 - MCP Key Changes:https://modelcontextprotocol.io/specification/2025-11-25/changelog
- Base Protocol: https://modelcontextprotocol.io/specification/2025-11-25/basic
- Transports: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- Authorization: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization
- Tools: https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- Resources: https://modelcontextprotocol.io/specification/2025-11-25/server/resources
- Prompts: https://modelcontextprotocol.io/specification/2025-11-25/server/prompts
- Roots: https://modelcontextprotocol.io/specification/2025-11-25/client/roots
- Sampling: https://modelcontextprotocol.io/specification/2025-11-25/client/sampling
- Elicitation: https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation
- Tasks: https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks
- Security Best Practices: https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices
- Build an MCP server: https://modelcontextprotocol.io/docs/develop/build-server
- Build an MCP client: https://modelcontextprotocol.io/docs/develop/build-client
- MCP Inspector: https://modelcontextprotocol.io/docs/tools/inspector
- MCP Registry: https://modelcontextprotocol.io/registry/about
官方 SDK:
- Python SDK: https://github.com/modelcontextprotocol/python-sdk
- TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
主流平台官方接入文档:
- Anthropic MCP connector: https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector
- OpenAI MCP servers for ChatGPT Apps and API integrations: https://platform.openai.com/docs/mcp
- Cloudflare Agents MCP: https://developers.cloudflare.com/agents/model-context-protocol/
18. 最后给一个判断框架
当你想做一个 MCP 集成时,先回答这 8 个问题:
- 这是本地能力还是远程服务?
- 主要是只读数据,还是会执行写操作?
- 用 tools、resources、prompts 中的哪一种最自然?
- 是否需要 search/fetch 两段式?
- 是否需要用户授权、OAuth、scope?
- 是否有 prompt injection 后可能造成的数据泄漏或破坏?
- 是否有长任务,需要 Tasks?
- 目标 Host 支持哪些 MCP 能力?不要只按协议理想状态设计。
最保守的默认方案:
- 本地个人工具:stdio + 最小 roots + Inspector 调试。
- 企业内部工具:Streamable HTTP + OAuth/SSO + 审计日志 + allowlist。
- 文档知识库:
search+fetch+ read-only tools + 引用元数据。 - 有写操作的业务系统:read/write 分离 + preview + confirmation + idempotency key。