MCP 协议与 Claude Code 实战

发布时间:2026/7/23 22:26:22

MCP 协议与 Claude Code 实战 MCP 协议与 Claude Code 实战大语言模型LLM早已不是只会“说话”的聊天机器。当它需要读取文件、查询数据库、调用 API、操作本地工具时一个标准化的“动手”协议就变得至关重要。MCPModel Context Protocol模型上下文协议正是为此而生。它定义了 LLM 与外部工具、数据源之间的统一交互方式让模型既能思考也能安全高效地执行操作。本文将系统梳理 MCP 的协议类型、核心场景并提供一个基于 PythonFastMCP的完整 Demo最后重点展开如何在Claude Code中配置和使用 MCP。在深入实战之前我们还会剖析一个关键概念——大模型的 Function Calling 能力——因为它是理解 MCP 工具调用机制不可绕过的基石。一、MCP 的通信协议与传输方式MCP 的通信规范建立在JSON-RPC 2.0之上并支持多种底层传输方式。可以把“协议”理解为不同的传输通道它们共享同一套请求/响应/通知的消息模型。目前主流的三种传输方式对比如下传输方式描述适用场景stdio标准输入输出通过进程的标准输入/输出流传输 JSON-RPC 消息本地开发调试、IDE 插件、桌面应用集成SSEServer-Sent Events基于 HTTP 的单向流式推送服务器可主动向客户端发送事件远程服务调用、Web 前端、跨机器通信Streamable HTTP升级版 HTTP 传输支持双向流式与批量请求对性能和灵活性要求更高的远程服务其中stdio是本地通信的基石而SSE / Streamable HTTP则面向远程部署和多客户端并发场景。在生产环境中常常是“本地用 stdio 开发远程用 HTTP 部署”。二、MCP 的应用场景全景MCP 远不止“调用一个函数”这么简单。它定义了四大原语primitives覆盖了模型与外部世界交互的主要模式工具Tools模型可以调用预定义的函数完成实际操作比如读写文件、发送 HTTP 请求、执行数据库查询、操作 GitHub Issue、发送 Slack 消息等。这是目前使用最广泛的场景。资源Resources暴露只读或可控的数据源给模型如读取本地文件内容、获取数据库的某张表结构、拉取指定 API 的静态配置。资源通常带有 URI模型可以像浏览网页一样“访问”它们。提示词模板Prompts提供预制的提示词框架模型根据用户输入填充占位符从而实现更可控、更工程化的交互。这对构建企业内部标准化工作流非常有用。采样Sampling允许 MCP Server 反向请求 LLM 进行推理。这意味着可以实现递归 Agent、多步推理、自反思等高级模式。理解这四个原语之后会发现 MCP 的强大之处在于它把“外部世界”抽象成了模型可理解、可调用的标准接口任何遵循该协议的工具都可以被无缝集成。三、MCP 工具调用的引擎解密大模型的 Function Calling 能力在编写第一行 MCP 代码之前有一个关键问题需要厘清大模型究竟如何“调用”一个工具许多开发者潜意识里认为模型像执行函数一样直接操作了 API 或文件系统但事实并非如此。3.1 真实的调用流程模型决策Agent 执行以一个简单的 MCP 工具调用为例当用户说“帮我列出当前目录的文件并向 Bob 问好”时后台实际发生的是大模型推理结合 Prompt 与可用工具列表由 MCP Server 声明决定需要依次调用list_files和greet。输出调用意图模型不返回自然语言而是生成一个结构化指令指明要调用哪个工具及参数。AgentMCP 客户端执行接收到指令后通过 MCP 协议向真正的工具服务端发起请求执行函数代码。结果回传与二次推理Agent 将执行结果再次发送给模型模型基于新信息决定下一步最终生成人类可读的回复。整个过程大模型从未亲自执行任何代码。它只负责“决策”——输出调用意图真正的执行由 MCP 客户端和服务器协作完成。3.2 Function Calling让模型“说得清楚”模型输出的那个“调用意图”在不同的模型中有着截然不同的可靠性。这里就要引出Function Calling函数调用的概念。Function Calling 是模型厂商如 OpenAI、Anthropic提供的一种原生能力让模型能够以结构化的 JSON 格式明确表达调用意图而不是用自然语言描述。没有原生 Function Calling 的模型只能通过提示词引导它输出类似 JSON 的文本例如{function:greet,args:{name:Bob}}但这种方式极度依赖提示词工程输出格式不稳定容易混入解释性文字甚至凭空编造不存在的函数名。有原生 Function Calling 的模型在训练阶段已经针对工具调用场景做了专门微调。当通过 API 传入工具定义后模型会使用专用的响应字段返回调用意图而非普通的聊天文本。以 OpenAI 的响应为例{role:assistant,tool_calls:[{id:call_abc123,type:function,function:{name:greet,arguments:{\name\:\Bob\}}}]}这种格式严格结构化支持同时调用多个函数且每个调用都带有唯一 ID便于将执行结果精准回传。核心结论Function Calling 是一种输出格式规范它让模型从“大概说一句人话”进化为“精确输出机器可读的调用指令”。3.3 Function Calling 与 MCP 的天作之合了解了 Function Calling再看 MCP 就豁然开朗了MCP Server 提供的工具定义名称、描述、参数 schema可以直接映射为模型 API 的tools参数无需二次转换。模型返回的tool_calls可以被 Agent无缝转化为MCP 客户端的call_tool请求。整个流程从“模型思考”到“工具执行”实现了端到端的自动化这正是 Claude Desktop、Cursor 等工具能够“零代码”接入任意 MCP Server 的根本原因。形象地比喻Function Calling 是模型“说得标准”的能力MCP 是 Agent“做得漂亮”的协议。两者结合才构成了今天 AI Agent 可靠执行任务的基础。四、5 分钟上手用 FastMCP 构建的第一个 MCP 工具下面我们基于 Python 的fastmcp库创建一个 MCP 服务器提供greet打招呼和list_files列出目录文件两个工具并通过客户端进行调用。1. 安装依赖pipinstallfastmcp2. 编写服务端server.py# server.pyfromfastmcpimportFastMCPimportos mcpFastMCP(DemoServer)mcp.tooldefgreet(name:str)-str:向用户打招呼returnfHello,{name}! Nice to meet you.mcp.tooldeflist_files(directory_path:str.)-list:列出指定目录下的文件和文件夹try:returnos.listdir(directory_path)exceptFileNotFoundError:return[fError: Directory {directory_path} not found.]exceptPermissionError:return[fError: Permission denied for {directory_path}.]if__name____main__:# 使用 stdio 传输启动默认方式mcp.run(transportstdio)3. 编写客户端client.py# client.pyimportasynciofromfastmcpimportClient config{mcpServers:{DemoServer:{command:python,args:[/absolute/path/to/server.py],# 修改为的实际路径transport:stdio}}}asyncdefmain():clientClient(config)asyncwithclient:resultawaitclient.call_tool(greet,{name:World})print(Greeting:,result)filesawaitclient.call_tool(list_files,{directory_path:.})print(Files:,files)if__name____main__:asyncio.run(main())4. 运行python client.py预期输出类似Greeting: Hello, World! Nice to meet you. Files: [server.py, client.py, ...]在这套流程中客户端以子进程方式启动server.py所有 JSON-RPC 消息均通过 stdin / stdout 交换。这就是stdio 传输的标准工作模式。五、深入 STDIO本地通信的基石由于很多初学者对 stdio 传输既陌生又容易误解我们特别展开一下。工作原理MCP 客户端如 IDE、Claude Code以子进程形式启动 MCP Server。客户端将 JSON-RPC 请求写入子进程的stdin。Server 从 stdin 读取请求并处理再将 JSON-RPC 响应写入stdout。所有日志、错误信息必须写入stderr避免污染通信通道。消息使用 UTF-8 编码通常以换行符分隔。下图可以帮建立直观印象┌──────────┐ stdin (JSON-RPC request) ┌──────────────┐ │ Client │ ────────────────────────── │ MCP Server │ │ │ ────────────────────────── │ │ └──────────┘ stdout (JSON-RPC response) └──────────────┘ stderr (logs)stdio 本质上就是 CLI可能会注意到配置stdio传输时永远只需要写一个命令command和参数args。这其实就是CLI命令行界面的核心概念。客户端通过python /path/to/server.py这个 CLI 命令启动服务器进程。从运维角度看这与在终端里执行一个命令行程序没有任何区别。因此stdio 传输完全可以理解为“用 CLI 命令拉起一个 MCP 服务”。任何能在命令行启动的程序Python、Node、二进制文件等都可以通过stdio成为 MCP 的一部分。这种设计让本地集成极其灵活不需要部署一个常驻后台的 HTTP 服务只需要一个可执行命令客户端就会按需拉起进程、执行任务、并回收资源。为什么本地首选 stdio零网络依赖无需监听端口、不引入网络延迟和攻击面。极致简单一个命令 参数即可拉起服务配置极简。天然进程隔离Server 崩溃不会影响 Client 主进程。跨平台一致Windows / macOS / Linux 均原生支持。stdio vs SSE 选择决策场景推荐传输本地开发、调试、单用户桌面工具stdio远程服务、多客户端并发、Web 集成SSE或 Streamable HTTP容器化部署、需要集中管理的企业服务SSE在实际项目中一个典型的策略是开发阶段用 stdio 快速迭代生产环境将同一个 Server 切换为 SSE 部署到服务器。六、扩展实战在 Claude Code 中配置 MCPClaude Code是 Anthropic 推出的命令行 AI 编程助手原生支持 MCP 协议。可以将任何 MCP 工具包括我们自己写的server.py集成到 Claude Code 中让 AI 在编程过程中直接调用。配置方式Claude Code 支持两种配置层级项目级配置在项目根目录创建.mcp.json文件。用户级配置在~/.claude/claude_desktop_config.json或.mcp.json中定义全局可用的 Server。示例将我们上面的 DemoServer 接入 Claude Code在项目根目录新建.mcp.json{mcpServers:{DemoServer:{command:python,args:[server.py],transport:stdio}}}这里command和args就是一个完整的 CLI 命令python server.py。保存后重新启动 Claude Code或执行claude mcp reloadAI 即可自动识别并调用greet和list_files工具。例如在 Claude Code 对话中直接说“用 DemoServer 的 list_files 工具列出当前目录的文件然后对每个 Python 文件统计代码行数。”Claude 会自主决定何时调用工具、如何解析结果并继续执行后续步骤。高级技巧动态管理 MCP ServerClaude Code 还内置了 MCP 管理命令无需手动编辑 JSON# 添加一个 stdio 类型的 Server本质上就是注册一个 CLI 命令claude mcpaddmy-tool -- python /path/to/server.py# 列出当前已配置的 MCP Serverclaude mcp list# 移除某个 Serverclaude mcp remove my-tool这些命令会自动修改对应的配置文件大幅降低上手成本。连接到远程 MCP ServerSSE 模式如果的 MCP 工具部署为远程 HTTP 服务Claude Code 同样支持 SSE 传输{mcpServers:{remote-tool:{type:sse,url:https://your-mcp-server.example.com/sse}}}这样就可以使用公司内部统一部署的 MCP 服务如数据库查询、内部 API 网关等让 Claude Code 的安全边界与组织权限体系保持一致。七、最佳实践与安全提醒严格区分 stdout 与 stderr协议消息必须走 stdout日志必须走 stderr。任何调试输出混入 stdout 都可能导致 JSON-RPC 解析失败。工具函数中做好错误处理在工具内部捕获异常并返回结构化错误信息而不是让异常直接传播导致 Server 进程退出。最小权限原则MCP 工具可能拥有读写文件、执行命令的能力。只运行信任的 Server并为生产环境的 Server 配置严格的权限控制如文件系统只读、网络白名单、沙箱等。传输方式按需切换本地开发和桌面集成首选 stdio远程或多租户场景使用 SSE/Streamable HTTP 并加上认证和加密。利用 Claude Code 的项目级配置实现环境隔离不同项目使用不同的.mcp.json避免全局工具污染也方便团队共享标准化的工具集。八、总结MCP 的真正价值在于它为 LLM 打造了一个开放、标准化、可组合的“手脚架”。无论是本地小工具还是企业级 API 网关只要遵循 MCP 协议就能被任何支持 MCP 的客户端发现和调用。而让这一切高效运转的幕后功臣正是大模型的 Function Calling 能力——它确保模型每次“动手”的意图都清晰、精确、可执行。stdio传输作为 MCP 的本地核心其设计思想极为简单而优雅用一条 CLI 命令拉起子进程通过标准输入输出完成所有交互。这种“命令行即服务”的模式让开发者在本地无需启动任何网络服务就能让大模型安全、高效地操控本地工具。FastMCP让 Python 开发者可以在几分钟内将想法落地为可供模型调用的工具Claude Code 则将这些工具无缝编织进日常编码工作流中真正实现了“AI 参与执行而不仅仅是对话”。如果想进一步探索可以尝试将现有的 REST API 封装为 MCP Tool使用 MCP Resources 暴露文档库或配置中心利用 Sampling 能力构建多步推理 AgentMCP 的生态正在快速发展现在正是深入掌握它的最佳时机。愿你我都能在各自的领域里不断成长勇敢追求梦想同时也保持对世界的好奇与善意!

相关新闻