MCP 实战指南:如何在项目中使用 Model Context Protocol 及其通信原理
Model Context ProtocolMCP正在成为 AI 应用连接外部工具与数据的「事实标准」。本文从通信原理讲起逐步讲清它在你项目里该怎么用、怎么通信、有哪些坑。目录MCP 是什么解决什么问题核心架构Host / Client / Server 三层三大原语Tools / Resources / Prompts通信协议JSON-RPC 2.0传输方式stdio 与 Streamable HTTP通信全流程一次完整的生命周期一个完整的工具调用报文长什么样如何在你的项目里使用 MCP注意事项与安全红线常见误区与最佳实践总结与扩展阅读1. MCP 是什么解决什么问题在 MCP 出现之前一个 AI 应用想接入外部能力数据库、文件系统、GitHub、企业内部 API……基本是「一应用一适配」每个数据源都要写一套专门的集成代码。N 个 AI 应用 × M 个数据源就是N×M 的适配工作量。MCP 把这个局面改成了NM它定义了一套统一的、开放的标准协议让 AI 应用通过同一个接口就能连接任意实现了该协议的工具和数据源。一个广为流传的类比MCP 之于 AI 应用就像 USB-C 之于电子设备。过去每个设备要配一根专用线现在一个口、一根线通吃。具体来说MCP 由 Anthropic 于2024 年 11 月开源定位是「模型上下文协议」——标准化 AI 应用宿主与外部工具/数据源服务端之间的通信方式。它不绑定任何模型厂商Claude、GPT、Gemini、各类 IDE 和 Agent 框架都能用。协议演进截至 2025-11-25 最新版版本日期关键变化2024-11-052024.11首次发布stdio HTTPSSE核心原语2025-03-262025.03Streamable HTTP 取代旧 SSE 设计加入会话管理与 OAuth 2.12025-06-182025.06结构化输出、Elicitation人机协同、改进授权2025-11-252025.11Tasks异步任务、Extensions 框架、企业级认证、图标注意旧的 HTTPSSE 双端点传输已在 2025-11-25 版中被标记为废弃新项目应使用Streamable HTTP。2. 核心架构Host / Client / Server 三层MCP 是一个「参与者模型」有三类角色Host宿主承载 AI 对话的应用比如 Claude Desktop、Cursor、你自己写的 Agent 服务。它负责接收用户输入、调用大模型、并把结果呈现给用户。Client客户端协议实现层运行在 Host 内部。每个 Client 与一个 Server 保持 1:1 连接。它负责把 Host 的意图翻译成标准的 JSON-RPC 消息发给 Server。Server服务端暴露具体能力的一方比如「查天气」「读数据库」「操作 GitHub」。一个 Host 可以同时连接多个 Server。为什么要有 Client 这一层把「宿主」和「协议」解耦。Host 专注产品体验Client 专注协议细节连接管理、能力协商、消息路由这样同一个 Client 实现可以被不同 Host 复用。3. 三大原语Tools / Resources / PromptsMCP 规定 Server 可以向 AI 暴露三类「原语」primitives它们回答三个不同的问题原语回答的问题方向例子Tools工具我能做什么模型触发 → 执行动作查询数据库、发邮件、创建工单Resources资源我有什么数据可读宿主读取 → 获取上下文配置文件、日志、数据库 schemaPrompts提示词有什么模板可复用用户/宿主选择 → 套用模板代码审查模板、SQL 生成模板三者意图不同这也是 MCP 和传统「函数调用Function Calling」最大的区别之一Tools 由模型决定何时调用Prompts 由用户决定用哪个Resources 则是被读取的上下文。除了 Server 侧的原语MCP 还定义了客户端Client/Host侧的能力让 Server 能「反客为主」SamplingServer 反过来请求 Host 帮它做一次 LLM 补全。这样 Server 不用自带模型 SDK也能「借」宿主的大模型能力。ElicitationServer 请求用户补充信息或确认操作人机协同、二次确认。LoggingServer 向 Client 推送结构化日志方便调试和监控。一个常见误区很多人以为 MCP 只有「工具调用」。其实 Resources喂上下文和 Prompts喂模板同样重要很多场景下它们比工具更好用。4. 通信协议JSON-RPC 2.0MCP 的「信的内容」用的是JSON-RPC 2.0全部消息UTF-8 编码。它只有四种消息形态请求Request带id期待一个响应。响应Response / Result带id对应某个请求的结果。错误Error带id对应某个请求的失败。通知Notification不带id单向发送、不期待响应。// 请求调用一个工具{ jsonrpc: 2.0, id: 7, method: tools/call,params: { name: search_issues, arguments: { query: auth } } }// 响应工具执行结果{ jsonrpc: 2.0, id: 7,result: { content: [ { type: text, text: 找到 3 个 issue... } ] } }// 通知工具列表变了无 id无响应{ jsonrpc: 2.0, method: notifications/tools/list_changed }核心方法一览类别方法用途生命周期initialize握手、协商协议版本与能力notifications/initialized客户端确认就绪ping心跳/保活工具tools/list/tools/call发现工具 / 执行工具资源resources/list/resources/read列出资源 / 读取资源提示词prompts/list/prompts/get列出模板 / 获取模板通知notifications/tools/list_changed等能力动态变化时推送关键点能力是「运行时发现」的而不是「编译期写死」的。Client 通过tools/list等接口在连接后才知道 Server 有哪些能力这是 MCP 能解耦 N×M 问题的根基。5. 传输方式stdio 与 Streamable HTTPMCP 把「信的内容」JSON-RPC和「怎么送信」传输层分离。规范定义了两种传输5.1 stdio标准输入输出Client 把 Server作为子进程启动通过它的stdin/stdout交换 JSON-RPC 消息。每条消息一行换行符分隔消息内部不得包含换行。Server 的日志只能写到stderrstdout上只能出现合法的 MCP 消息。# 典型启动方式Client 拉起 Server 子进程 npx -y modelcontextprotocol/server-filesystem /tmp/workspace特点零网络配置、最简单、生命周期绑定进程。适合本地工具、IDE 集成、单人开发调试。5.2 Streamable HTTP可流式 HTTPServer 作为独立进程运行监听单个 HTTP 端点如https://example.com/mcp可同时服务多个客户端。客户端 → 服务端每次发消息都是一个独立的HTTP POST到该端点Accept头需同时声明application/json和text/event-stream。服务端 → 客户端服务端可返回普通 JSON也可升级为SSEServer-Sent Events流持续推送消息客户端也可用HTTP GET打开一个 SSE 流来被动接收服务端发起的消息。会话通过MCP-Session-Id头显式管理SSE 事件 ID 支持断线重连与消息回放。特点支持远程、多客户端、横向扩展能挂到标准 HTTP 基础设施负载均衡、API 网关、认证中间件后面。生产环境、云部署首选。5.3 对比维度stdioStreamable HTTP部署形态Client 拉起子进程独立进程可远程网络仅本机可跨网络多客户端不支持1:1 进程支持会话管理隐式随进程生命周期显式Session-Id 头断线重连不适用支持SSE event ID 回放认证无本机信任OAuth 2.1 / API Key / JWT适用本地工具、开发调试生产、云部署、远程经验法则开发期用 stdio 起步生产环境迁移到 Streamable HTTP。6. 通信全流程一次完整的生命周期MCP 的每一次连接都严格遵循初始化 → 能力协商 → 运行 → 关闭四个阶段。逐阶段拆解① 初始化握手Client 主动发initialize带上自己支持的protocolVersion日历版本号如2025-06-18和capabilities。Server 返回自己的版本与能力。版本若无法达成一致连接必须断开。② 能力协商双方各自声明支持的特性tools/resources/prompts/logging/sampling……并只使用「双方都声明了」的能力。例如 Server 没声明toolsClient 就不能调tools/list。③ 就绪确认Client 发一个notifications/initialized通知无id表示可以开始正常通信。在此之前双方只允许发ping和日志。④ 运行Client 通过*/list发现能力、tools/call/resources/read/prompts/get使用能力Server 可随时用notifications/*推送变化。⑤ 关闭MCP没有专门的 shutdown 方法关闭传输连接即结束会话。stdio 下 Client 先关子进程输入流、再发 SIGTERM、必要时 SIGKILLHTTP 下直接关闭连接。双方都要能优雅处理「连接意外断开」。7. 一个完整的工具调用报文长什么样把上面的流程落到最真实的场景模型决定要「查 GitHub 上 auth 模块的 open issue」一次完整的tools/call长这样// 1. Client → Server执行工具 { jsonrpc: 2.0, id: 3, method: tools/call, params: { name: search_issues, arguments: { query: auth, state: open } } } // 2. Server → Client返回结果结构化 content 数组 { jsonrpc: 2.0, id: 3, result: { content: [ { type: text, text: 找到 3 个 issue#12 登录超时、#18 鉴权绕过、#25 token 刷新 } ], isError: false } } // 3. 如果工具执行失败业务错误不是协议错误 { jsonrpc: 2.0, id: 3, result: { content: [ { type: text, text: 查询失败 } ], isError: true } }几个值得注意的细节工具的输入参数结构由tools/list返回的inputSchemaJSON Schema声明模型是读 schema 来决定怎么传参的——所以description写得越清楚模型用得越准。返回值是content数组可含多个文本/图片/资源块而不是裸字符串。业务错误用isError: true表达工具跑了但失败协议错误请求格式错误、方法不存在则走 JSON-RPC 的error字段两者要分清。8. 如何在你的项目里使用 MCP你的角色决定了用法。分三种情况8.1 你是「使用方」接入现成的 MCP Server最常见。很多常用能力已有现成 MCP Server直接配置接入即可无需自己写代码。以把「GitHub MCP Server」接进某个 Host 为例配置形如{ mcpServers: { github: { command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_PERSONAL_ACCESS_TOKEN: 你的 token } } } }不同 Host 的配置入口不同Claude Desktop 是claude_desktop_config.jsonCursor 在设置里WorkBuddy 在连接器管理里但核心字段几乎一致commandargsstdio 方式或url 认证信息Streamable HTTP 方式。结合你的运维场景GitHub MCP管仓库/PR/Issue、腾讯云轻量服务器 MCP管实例/防火墙/快照都能直接接进工作流让 Agent 直接操作这些资源而不是人肉去点控制台。8.2 你是「开发方」用 SDK 写一个 MCP Server如果内部有专属工具/数据要暴露给 AI就用官方或社区 SDK 写一个 Server。下面以 Go 为例社区流行的mark3labs/mcp-go官方亦有modelcontextprotocol/go-sdkpackage main import ( context github.com/mark3labs/mcp-go/mcp github.com/mark3labs/mcp-go/server ) func main() { s : server.NewMCPServer(my-server, 1.0.0) // 注册一个 echo 工具 s.AddTool( mcp.NewTool(echo, mcp.WithDescription(返回用户输入的内容用于连通性测试), mcp.WithString(message, mcp.Required(), mcp.Description(要回显的内容), ), ), func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { msg : req.Params.Arguments[message].(string) return mcp.NewToolResultText(echo: msg), nil }, ) // 以 stdio 方式启动生产可换 Streamable HTTP server.ServeStdio(s) }Python 官方 SDK 的写法更简洁mcp.server.fastmcp装饰器适合快速验证Go 适合写进你现有的服务里。核心思路一致定义工具 → 注册实现 → 选一个传输方式跑起来。8.3 你是「集成方」在自有 Agent 里同时当 Client 和 Server像需要维护的Go Gin 的 Agent 服务典型姿势是对外上游 Agent / IDE暴露能力 → 用 SDK 起一个 MCPServer对内调用下游数据源 / 其他工具→ 用 SDK 起一个 MCPClient去连 GitHub MCP、腾讯云 MCP 等。一个进程可以同时是 Server 又是 Client这正是 Agent 作为「中间编排层」的常见形态。选型建议对外暴露用 Streamable HTTP可远程、可认证对内调用本地子进程工具用 stdio。9. 注意事项与安全红线这是最容易踩坑、也最该认真对待的部分。9.1 传输层安全Streamable HTTP 必须做官方规范明确要求必须校验Origin头防止DNS rebinding 攻击恶意网页借本地 MCP Server 发起操作。本地运行时默认只绑定127.0.0.1不要轻易绑0.0.0.0暴露到公网。远程 Server必须做认证OAuth 2.1 / API Key / JWT。9.2 提示词注入Prompt InjectionMCP 标准化了通道但没有标准化「信任」。Server 返回的内容会被模型直接读取恶意 Server或 Server 拉到的外部数据可能夹带指令诱导模型做出危险操作。务必把「工具输出」与「系统指令」在语义上隔离不要无条件信任工具返回内容当指令执行。对高危操作删除、支付、发布设置人工确认点可用 Elicitation 实现。9.3 权限与治理MCP不定义工具级/资源级的细粒度授权也没有速率限制、审计、成本追踪。这些必须自己建一层API 网关、中间件、管理平台。记住原则「它说 MCP」只代表它能对话不代表它有权操作。该收口的权限要自己收口。9.4 日志与敏感信息日志只写stderrstdio 下绝不让日志污染stdout否则协议解析会崩。不打印 Token、密码、完整连接串等敏感信息。9.5 错误处理与超时所有请求都要设超时防止连接挂死、资源耗尽。区分两类错误协议错误JSON-RPCerror和业务错误isError: true处理与重试策略不同。服务端要能优雅处理「连接意外断开」不要假设正常关闭。10. 常见误区与最佳实践误区一MCP 就是 Function Calling。不对。MCP 是传输 发现 生命周期的完整协议Resources/Prompts/Sampling 等都是 Function Calling 不具备的。它解决的是「连接管理」而非「让模型会调函数」这件事。误区二接一个 MCP Server 就万事大吉。MCP 不提供能力发现注册中心、不提供编排多 Agent 协作请用 A2A、不提供治理。这些是你要在它之上补的。误区三工具描述随便写。description是模型和你的系统之间的唯一接口。一句模糊的「管理订单」远不如「根据订单号查询订单状态参数 orderId 必填返回含状态与时间的 JSON」可靠。最佳实践小结开发用 stdio生产用 Streamable HTTP。工具description写清「输入、输出、副作用、何时用/何时别用」。给所有工具调用设超时监控每次调用的延迟、错误率、token 消耗。高危操作加人工确认对外 Server 强制认证 Origin 校验。为工具定义做版本管理利用tools/list_changed通知客户端变化。把 MCP Server 当生产 API 一样做可观测性——它就是你新的「外部依赖」。11. 总结与扩展阅读一句话总结MCP 是一套「参与者模型Host/Client/Server 三类意图原语Tools/Resources/Prompts 基于 JSON-RPC 2.0 的可协商生命周期 可插拔传输stdio / Streamable HTTP」的开放协议。它把 AI 应用与外部工具的连接从 N×M 降到 NM但只标准化了通道不标准化信任与治理——安全与治理责任在你。核心要点回顾通信内容JSON-RPC 2.0请求 / 响应 / 错误 / 通知。通信流程initialize握手 → 能力协商 →notifications/initialized→ 发现*/list→ 使用tools/call等→ 关闭传输。能力是运行时发现的description和inputSchema是模型正确使用工具的钥匙。安全红线校验 Origin、绑 localhost、必须认证、防提示词注入、高危操作人工确认、日志脱敏。扩展阅读官方规范Specification - Model Context Protocol官方架构与生命周期说明Architecture overview - Model Context Protocol传输层规范Transports - Model Context ProtocolGo SDK社区GitHub - mark3labs/mcp-go: A Go implementation of the Model Context Protocol (MCP), enabling seamless integration between LLM applications and external data sources and tools. · GitHub官方各语言 SDK 列表What is the Model Context Protocol (MCP)? - Model Context Protocol