
聊到 2025 年 AI 基础设施里最绕不开的三个字母MCP 绝对排得上号。不管你是写代码的、做运维的还是在搞 AI 应用的最近大概率被 MCP、MCP 服务、Tool 这几个词刷过屏。我第一次接触 MCP 是 Claude 刚宣布支持那阵第一反应是这不就是给大模型装外接硬盘吗后来自己部署、调试、写 server才发现协议、服务、Tool 这三者的关系并没有字面上那么好理解很多人不是不会用而是第一步就被名词绕晕了。下面这篇是我按自己趟坑顺序整理出来的把 MCP 协议是什么、MCP 服务怎么搭、Tool 在其中扮演什么角色一次讲透再给出一套能直接复现的本地部署方案。适合刚开始接触 MCP、想在 Claude Desktop、Cursor 或自己业务系统里接 MCP 的开发者参考。1. 为什么会有 MCP一个“AI 时代的通用插头”1.1 过去接入 AI 的能力有多痛苦在大模型刚火起来的时候你想让 AI 帮你查数据库、发邮件、操作浏览器基本每个需求都要专门写一段胶水代码。拿调用外部工具这件事来说OpenAI 有 function callingAnthropic 有 tool use各家还都有自己的参数格式和调用规范。今天接飞书要写一套明天接 Jira 又要重新写一套后天换个模型提供商之前的适配代码又得改一遍。这感觉很像早期打印机没有统一驱动标准每个软件厂商都要专门适配每一台硬件每次新设备出来都是一次重复劳动。当时的 AI 应用开发也是这样大量的时间不是花在业务逻辑上而是花在“怎么把大模型和工具连接起来”这种低水平重复上。大家在社区里吐槽给大模型接一个数据库无非是写 Python 函数、转 JSON Schema、拼 prompt这套流程能复制上百次。MCP 就是为了终结这种碎片化而出现的。它把“AI 应用想调用外部能力”这件事标准化了只要你的服务实现了 MCP 协议任何支持 MCP 的 AI 客户端都能直接发现并调用它不需要为每家厂商单独做适配。社区里有个很形象的比喻MCP 之于 AI 工具链就像 USB-C 之于充电接口。你不需要为每台设备准备专属充电线只需要一个标准接口大家都按这个规格来就行。1.2 软件协议 vs 硬件协议MCP 属于哪一类网上有个高频问题MCP 到底是软件协议还是硬件协议和 USB、PCIe 这些概念是什么关系。答案很明确MCP 是纯软件协议而且属于应用层协议跟 HTTP、WebSocket、JSON-RPC 是同一个层级的角色。它不涉及电压、电平、引脚、时钟同步这些硬件概念它定义的是一套“AI 应用与服务之间如何交换消息”的规则。具体来说MCP 消息采用 JSON-RPC 2.0 格式所有能力都通过请求、响应、通知三类消息来表达。传输层可以选择本地 stdio也就是标准输入输出通道也可以选择基于 HTTP 的 Streamable HTTP。这种分层设计很方便协议逻辑和传输方式解耦同一个服务既能在本地被 Claude Desktop 拉起也能部署到远程服务器供网页端或者手机端 App 调用。理解这一点之后很多困惑就能解开。比如“手机怎么获取 MCP 服务”这个问题本质上不是让手机系统装一个 MCP 协议栈而是你去找一个支持 MCP 的 AI 客户端 App然后在 App 里填写远程 MCP server 的地址和鉴权信息。因为远程服务走的是 HTTP手机上照样能用只是背后多了一层网络连接罢了。2. MCP 协议核心构成Client、Server、原语2.1 三个角色Host、Client、Server 别搞混刚开始看 MCP 文档时很容易被角色绕晕因为一个完整调用链里至少有三个东西Host、Client、Server。我用餐厅来类比一下就清楚了。Host 是用户直接接触的宿主应用比如 Claude Desktop、Cursor、Trae或者你集成到业务系统里的 AI 助手它负责渲染对话、调度大模型、展示结果。Client 是宿主应用内部负责跟 MCP Server 通信的模块它执行协议握手、发现工具、发起调用相当于餐厅里的服务员。Server 是实际干活的一方它暴露出一批能力相当于后厨客人不会直接走进厨房点菜得由服务员拿着菜单过去沟通。很多人在排查问题时搞不清该改哪里。如果 Cursor 里看不到某个工具问题可能在 Client 的配置也就是 Cursor 里 MCP 配置项填得不对如果工具看到了但调用报错问题多半在 Server 端。先把角色边界划清楚排错范围立刻缩小一半。下面这个表可以帮你快速对齐角色职责常见例子Host面向用户的 AI 应用负责对话与交互Claude Desktop、Cursor、TraeClient宿主的协议代理负责发现和调用能力Cursor 内置 MCP Client、Claude Desktop 客户端模块Server独立进程或服务暴露工具、资源、提示词自建 Python 服务、Playwright MCP、GitHub MCP Server2.2 三类原语Tool、Resource、Prompt 各管什么MCP 协议里定义了三种原语也就是 Server 可以向 Client 暴露的三类能力这经常被人忽略。很多人以为“MCP 就是 Tool”其实 Tool 只是其中一种另外两种同样重要。Tool 是一个可执行函数模型根据你的描述判断“要不要调用”调用后会执行操作并返回结果典型的 Tool 包括查询天气、创建工单、执行 SQL、发 HTTP 请求等等。Resource 是只读数据用来给模型提供上下文比如一份配置文件、一篇文档、一条数据库记录它不是一个动作而是一份内容。Prompt 是预制的提示词模板帮你把高频使用的指令封装起来类似于“写好框架、填入参数”的套路。三者的关系可以理解为Resource 是“给模型看的资料”Tool 是“让模型能动手的按钮”Prompt 是“教模型怎么干活的话术”。实际项目里 Tool 最常见但如果你想把某些稳定数据传给模型用 Resource 往往比塞进 prompt 更清爽。我自己在做 MCP server 时会把产品配置做成 Resource把需要读写的操作做成 Tool职责分开后续维护也轻松。2.3 一次完整调用是怎么发生的MCP 协议底层的消息交互并不神秘本质上是一串 JSON-RPC 消息。第一次建立连接时Client 和 Server 先做 initialize 握手交换协议版本和双方支持的能力。握手成功之后Client 会发 tools/list 请求Server 返回工具清单每个工具都包含名称、描述、输入参数 Schema。大模型在对话过程中根据用户请求和工具描述决定要不要调用某个 Tool决定后由 Client 发送 tools/call 请求Server 执行并返回结果。举个例子一次 tools/list 请求可能长这样{ jsonrpc: 2.0, id: 1, method: tools/list }对应的响应里会包含你定义过的工具名、描述和参数约束。看到这个格式你会更清楚一点MCP 协议本身不定义任何具体业务能力它只定义“如何发现能力、如何请求能力、如何返回结果”这套元规则。真正的能力由每个 Server 自己实现协议负责把它们标准化地暴露出去。2.4 传输方式选择stdio 还是 HTTPMCP 的传输方式直接决定了你这个服务怎么被访问。目前主流的两种是 stdio 和 Streamable HTTP。stdio 是客户端启动一个本地子进程通过标准输入输出跟 MCP Server 通信适合在桌面客户端、IDE、本地开发环境里用。它的优点是没有网络开销、启动迅速、安全边界清晰缺点是不能跨机器调用。Streamable HTTP 则把 Server 暴露成一个远程 HTTP 端点客户端通过 URL 访问支持鉴权、支持远程部署。手机端 MCP App、网页端 AI 工具、服务器上的共享服务基本都是走这种模式。旧版协议里的 HTTP SSE 正在被 Streamable HTTP 取代WebSocket 传输也在逐步收敛。选型时不需要太纠结。本地个人开发优先用 stdio配置文件最简单要给团队用或者接入手机 App就部署成 Streamable HTTP。有一点要注意本地 stdio 模式下Server 的所有日志都不能写到标准输出因为 stdout 是协议通道一旦混入日志客户端解析 JSON-RPC 就会失败。这个坑我在后面排查章节会详细展开。3. MCP 服务与 Tool 的实际形态一个 Tool 怎么跑到大模型手里的3.1 MCP Server 就是一个“能力集装箱”从形态上看一个 MCP Server 就是一个独立的程序它可以是 Python 脚本、Node.js 服务甚至是 Java 进程。它监听在某个传输通道上用协议向外暴露能力。官方社区已经有大量现成 Server比如文件系统访问、Git 操作、数据库查询、Playwright 浏览器自动化、Chrome DevTools 调试等。这些现成 Server 的使用方式通常非常简单很多都是一条命令的事。比如想给 AI 接入浏览器操作能力官方 Playwright MCP 就能直接拉起来然后在客户端配置里把这个进程交给 MCP Client 管理。你不需要关心它内部怎么实现的只要它跑起来、暴露了 ToolAI 客户端就能发现并调用。这也是 MCP 和传统插件体系最大的区别。传统插件是“客户端主动调用插件提供的接口”MCP 则是“客户端通过标准协议发现并调用工具”Server 端只是实现协议不需要为每个客户端定制接口。对开发者来说写一次 Server就能同时服务 Cursor、Claude Desktop、Trae以及任何兼容 MCP 的客户端。3.2 Tool 的定义不是代码而是“描述 参数 Schema”很多人手写 MCP Server 时以为只要把 Python 函数写出来就算定义了一个 Tool。实际上在协议层面Tool 是一个元数据对象它由三部分组成name、description、inputSchema。模型能看到的主要是 description 和 inputSchema它通过这些信息判断这个工具是干什么的、需要传什么参数。比如说你在 Python SDK 里写这个函数mcp.tool() def get_weather(city: str) - str: 查询指定城市的当前天气 ...在协议握手阶段它会变成类似这样的元数据{ name: get_weather, description: 查询指定城市的当前天气, inputSchema: { type: object, properties: { city: {type: string} }, required: [city] } }理解这一点非常重要因为它直接影响“模型到底会不会主动调用这个 Tool”。模型不是读过你的源码再决定调用它只看到元数据。如果你的 description 写得含糊参数名和含义不清晰模型就该猜了猜错的结果就是不调用、传错参数或者连续报错。3.3 描述怎么写工具才容易被模型选中我踩过的最大一个坑就是工具写好了但模型怎么都不主动调用。后来发现不是代码问题是 description 太敷衍。工具描述要做到三个点动词开头说明动作写清楚输入参数的约束和单位最好带上一个典型调用场景。同样是“查询价格”一个写法是“查价格”另一个写法是“根据商品 ID 查询实时售价单位为人民币元返回含税和不含税两种价格”。后者显然更容易让模型在合适时机选中它。我开始意识到给 Tool 写描述本质上是在给模型写 API 文档不是在给同事写注释。这个思维转变之后工具被调用的成功率直线上升。另外要注意 inputSchema 的类型约束。MCP SDK 通常会自动从函数签名生成 Schema但如果你用了复杂对象或者可选参数最好显式检查一下生成的 Schema确认 required 字段和 type 是符合预期的。模型调用工具时如果参数校验失败体验会非常差而且这类报错不会太友好。4. 实操从零部署一个自建 MCP 服务4.1 环境准备与依赖安装下面我用 Python 来演示因为 Python SDK 封装得比较完善新手也能快速上手。建议 Python 3.10 以上版本有虚拟环境习惯的可以先建一个独立环境避免污染全局依赖。安装官方 SDK 只需要一条命令pip install mcp如果你在用 uv也可以执行uv add mcp。安装完成后可以用python -c import mcp; print(mcp.__version__)验证 SDK 是否正常。这里多说一句MCP SDK 更新速度比较快不同大版本之间 API 会有调整网上很多教程用的是 0.x 版本代码如果你的环境是新版本遇到 API 不存在的问题时优先看官方示例和本地 SDK 文档。4.2 完整代码一个带 Tool 和 Resource 的最小服务这个示例服务我起名叫 price-demo提供一个计算含税价的 Tool再提供一个返回配置信息的 Resource。代码非常短但足够把 MCP 的核心概念串起来。import sys import logging from mcp.server.fastmcp import FastMCP logging.basicConfig(streamsys.stderr, levellogging.INFO) mcp FastMCP(price-demo) mcp.tool() def calc_price(base: float, tax_rate: float 0.06) - float: 计算含税价格接受不含税金额 base 和税率 tax_rate默认 0.06返回含税金额 if base 0: raise ValueError(base 不能为负数) return round(base * (1 tax_rate), 2) mcp.resource(config://app) def get_config() - str: 返回示例配置信息演示 Resource 的用法 return version1.0\ncurrencyCNY if __name__ __main__: mcp.run(transportstdio)看到这个代码你已经完成了最核心的部分定义了一个 Tool、一个 Resource、把它们挂载到 MCP Server 上。注意 logging 的 stream 参数我故意指定成 stderr原因前面说过stdout 要留给协议通信。4.3 用官方 Inspector 做本地测试写完之后别急着接客户端先用 MCP Inspector 验证一遍。官方审查工具可以一行命令启动npx modelcontextprotocol/inspector它默认会启动一个本地调试页面。界面上可以配置要连接的服务选择 command 模式填上启动命令比如python /path/to/your/server.py启动后你可以手动发 tools/list、tools/call 等请求。我通常先看 tools/list 返回里有没有 calc_price 和 get_config再用 tools/call 传一组参数验证返回值。这样能把问题锁定在 Server 端还是客户端配置端比直接接 Claude Desktop 再排查快得多。Inspector 是调试 MCP Server 的必备工具强烈建议每一位想深入 MCP 的开发者养成熟练使用的习惯。后面遇到“客户端不显示工具”“工具调用报错”这类问题第一反应应该是开 Inspector 复现而不是反复改客户端配置。4.4 把服务接到 Claude Desktop本地验证通过之后就可以接到 Claude Desktop 了。配置文件路径在 macOS 上是~/Library/Application Support/Claude/claude_desktop_config.jsonWindows 上是%APPDATA%\Claude\claude_desktop_config.json内容这样写{ mcpServers: { price-demo: { command: /usr/local/bin/python, args: [/Users/yourname/mcp-demo/server.py] } } }有几个细节容易踩坑command 必须用绝对路径尤其是 Python 解释器路径别随手写python因为 Claude Desktop 启动子进程时的环境变量和你的终端不一定一样。args 里脚本路径也建议写绝对路径。改完配置后重启 Claude Desktop然后在对话里问它“计算一件不含税 100 元的商品按 6% 税率算含税价是多少”如果配置没问题它就会自动调用你的 calc_price 派生工具。4.5 接到 Cursor、Trae 和 IDEA 里的操作桌面 IDE 的接入方式大同小异。以 Cursor 为例打开 Settings 里的 MCP 面板选择添加 MCP server模式选 command填上跟 Claude Desktop 配置里一样的命令和参数。添加成功且服务正常启动后工具列表会出现在对话框下方。Trae 的 MCP 管理界面也类似找到相关入口把同样的命令粘进去就行。IDEA 用户可以通过通义灵码等插件接入 MCP。这类插件通常支持远程 MCP 连接的配置新建连接时填写 HTTP endpoint 和鉴权信息即可。如果你是本地调试也可以填本地命令具体入口在插件的 AI 设置里搜索 MCP。这里提醒一下IDE 类插件的 MCP 支持更新频率很高界面入口经常微调遇到找不到入口的情况直接查插件官方文档比看旧教程靠谱。4.6 从本地 stdio 到远程 HTTP如果想把服务部署到服务器或者让手机端 App 也能访问就要把传输方式改成 HTTP。FastMCP 支持直接指定 transport 为 http示例代码只要改一行if __name__ __main__: mcp.run(transporthttp, host0.0.0.0, port8000)不同 SDK 版本的参数写法可能略有差异但思路是一致的。远程模式下客户端不再用 command 启动本地进程而是配置一个 URL。比如 Claude Desktop 的配置文件可以写成{ mcpServers: { price-demo-remote: { url: http://your-server-ip:8000/mcp } } }远程部署要特别关注鉴权。MCP 协议本身不强约束鉴权方式但如果你把服务暴露到公网而不加任何防护等于把一个可以执行代码的接口公开挂在网上这是非常危险的做法。建议至少加一层 Token 鉴权客户端配置里通过 header 传递密钥。不要图省事把 Token 拼在 URL 里因为 URL 会出现在日志、历史记录和代理服务器的缓存里泄露风险很大。5. 常见问题与排查技巧实录5.1 三层排查法接 MCP 服务遇到问题我习惯按三层来拆客户端配置层、服务启动层、协议调用层。客户端配置层主要看 mcpServers 配置项是不是写对了路径是不是绝对路径URL 地址是否可达。服务启动层看 Server 进程有没有起来启动时有没有报错依赖是否齐全。协议调用层用 Inspector 发请求看 tools/list 是否有响应调一个工具看返回是否符合预期。大多数问题都出在前两层。特别是本地 stdio 模式最常见的原因是客户端启动 Server 时的工作目录或 Python 路径不对。你可以在终端手动执行配置里的命令如果能正常运行再考虑客户端环境差异。5.2 问题速查表现象常见原因处理方法客户端找不到 MCP 服务mcpServers 配置格式错误或路径错误检查配置 JSONcommand 和 args 改为绝对路径工具列表是空的Server 启动失败或协议版本不兼容终端手动启动看报错用 Inspector 连接测试工具调用报参数校验错误inputSchema 和实际参数类型不一致检查函数签名确认 required 字段符合预期模型始终不调用工具description 描述不清晰或参数名容易误解重写 description加入单位、边界、典型场景调用超时任务耗时过长或网络不稳定设置更长超时或将长任务拆分计算Codex 找不到 MCP 服务配置未生效或 URL 缺少 /mcp 后缀检查启动日志确认 endpoint 地址正确重启客户端服务端输出日志导致协议中断日志写到了 stdout日志全部写 stderr 或文件远程服务返回 401鉴权 Token 缺失或过期检查客户端 header 配置重新生成 Token5.3 Server 端日志如何做自定义管理很多人在本地 stdio 模式下调试时发现 AI 客户端连不上服务或者工具调用永远没响应打开终端一看代码里到处是 print。这在我这踩过不止一次。stdout 是 MCP 协议通道你每打印一行普通文本客户端解析 JSON-RPC 时就多一行非法输入轻则工具不显示重则整个连接失败。正确做法是让所有业务日志走 stderr或者干脆落到文件中。Python 里用 logging 模块指定streamsys.stderr或者增加一个 FileHandler 写日志文件。日志内容也建议带时间戳和函数名方便排查线上问题。如果你正在开发一个长期维护的 MCP server日志管理这件事值得一开始就规划好不然后期排障会非常痛苦。5.4 回写打通与权限控制“MCP 回写打通”是很多业务系统的真实需求。所谓回写就是让 AI 不仅能读数据还能把操作结果写回系统里比如更新工单状态、创建记录、修改配置。这在协议层面没有任何特殊之处本质上就是定义一个具有写权限的 ToolServer 端执行更新逻辑。但回写能力意味着风险成倍增加。模型有可能在错误时机调用写工具或者因为参数理解偏差产生错误操作。我的建议是写工具一定要加确认机制或权限校验参数尽量收敛避免暴露“执行任意 SQL”“执行任意命令”这类危险工具。协议不会替你负责安全问题MCP 服务至少要按内部不可信接口来对待。6. 从 IDE 到浏览器MCP 生态还能怎么玩6.1 浏览器自动化Playwright MCP、Chrome DevTools MCP、browser-use 的区别浏览器类 MCP 是近期热度最高的一类应用好多人问 Playwright MCP 和 browser-use MCP 有什么区别这里我给出一个直观判断两者定位不同。Playwright MCP 是一个 MCP Server它把浏览器操作能力暴露成 Tool让 AI 客户端决定什么时候打开网页、点击哪里、输入什么内容你是在和 Claude Desktop、Cursor 这类宿主配合使用。Chrome DevTools MCP 针对的是网页调试场景基于 Chrome DevTools Protocol偏性能分析、网络请求、DOM 调试。browser-use 则是一个独立的浏览器代理框架它自己承担 Agent 决策自己去操作浏览器不完全依赖 MCP 客户端调度。选型时你要先问自己场景是什么。如果只是想让聊天助手能帮你看网页内容Playwright MCP 就够了。如果你想做自动化测试、性能调优Chrome DevTools MCP 更对口。如果你要的是一个能自己完成多步任务的浏览器 Agent那研究 browser-use 本身更直接。另外像 Dify 这类平台也支持浏览器 MCP 的接入本质是把它当成一个 Tool Provider 配置进去思路与桌面客户端一致。6.2 设计协作类 MCP以蓝湖为例开发圈最近聊得多的还有蓝湖 MCP 服务。这类服务把设计稿标注、切图信息、组件属性暴露给 AI让 AI 能直接读取设计资源来生成代码或回答问题。部署方式和通用远程 MCP 没区别拿到服务地址和鉴权 Token在支持 URL 模式 MCP 的客户端里加一条配置就能在对话中调用相关工具。这类服务的价值在于打通设计到开发的链路。以前开发要自己打开设计稿切图、量尺寸、看标注现在这些信息可以变成 Resource 给模型当上下文。但要注意设计数据往往涉及未上线方案接入的时候要做好访问控制别把内部设计资源无防护地暴露给公网 MCP 端点。6.3 企业系统集成当 MCP 遇上中后台项目像 RuoYi-Vue-Pro 这类后台管理系统集成 MCP是另一个有意思的方向。把企业内部已有的 API 包成 Tool再让 AI 助手通过 MCP 调用就能实现“用自然语言操作后台系统”的效果。本质上不是有什么特殊的 MCP 黑魔法而是把系统服务暴露成 MCP Server然后在某个 AI 客户端里配置好连接。真正麻烦的不是协议而是权限映射。企业内部 API 各有各的角色权限体系MCP Server 在调用这些 API 时必须继承用户身份不能让它拥有一个“超级管理员”的通用凭证。我见过不少团队把服务端密钥写死在配置里结果任何能访问 MCP 端点的用户都等于获得了后台操作权限。解决思路是让 MCP Server 感知当前对话的用户身份做一层权限转换或者至少在 Tool 内做参数级白名单校验。6.4 安全上必须养成的四个习惯关于 MCP 服务安全我想额外强调几点。第一不要把私密 Token 暴露在客户端配置里分享给他人。哪怕只是本地工具也要当成敏感配置管理。第二远程 MCP 服务需要用 HTTPS 和额外鉴权不要裸奔在公网。第三工具权限要最小化能只读不开放写能限参数不放开任意输入。第四定期更新 MCP SDK 和官方 Server协议还在快速演进老版本可能存在安全隐患。我自己跑过一段时间 MCP 服务之后最大的感受是技术门槛并不高真正拉开差距的是对“协议边界”的理解。MCP 协议只负责连接和消息格式不负责业务、不负责安全、不负责模型决策这些都得靠开发者自己设计。把 description 当 API 文档写把 Server 当开放接口保护把 Tool 参数当用户输入校验做到这三点MCP 就能稳定地成为你 AI 应用里的一个坚实组件。最后再补一句实用建议刚开始不要追求把很多工具塞进一个 Server先从一个最小服务跑通全链路再去扩展能力这个节奏最不容易劝退。