ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MCP:从工具调用到能力协议的下一代AI集成标准

2026/9/6 6:02:54 拓冰建站 浏览量
MCP:从工具调用到能力协议的下一代AI集成标准 我第一次在一个真实项目里跑通 MCP 的时候其实并没有多激动。真正让我停下手头活的是那个瞬间——AI 在没有任何人告诉它“你查的是哪张表”的情况下自己通过 MCP 拿到了 SQLite 里的表结构然后写了一条正确的 SQL把结果拿回来解释给我听。那一刻我才意识到过去两年我做的 LLM 应用集成方式恐怕全都要重写。“工具调用”在过去两年是大模型应用的入口Embedding 之后第二个绕不开的话题。但作为实际开发过多个 LLM 项目的从业者我最清楚它的问题接口不统一、权限不清晰、上下文不连续。你和 A 模型写好的一套工具换到 B 模型就得重写你接了一个数据库再想接第二个又得写一堆胶水代码。MCP 这个协议在 2024 年底被 Anthropic 开源之后大半年时间几乎成了 AI 集成的默认标准主流的 AI 客户端、IDE、数据库工具、设计工具、游戏引擎全在往它上面靠。这篇文章我从第一性原理的角度重新讲 MCP。不堆官方文档尽量讲清楚“为什么它是下一代的工具集成方式”以及“你自己动手写一个 MCP Server 到底要多久”。如果你正在犹豫要不要学 MCP或者已经被各种 MCP 相关热词绕晕这篇应该能帮你把整条线捋直。1. 从工具调用到能力协议一次底层思维转换1.1 先问自己大模型为什么连不上“真实世界”大模型再聪明本质上也是在一个静态的权重空间里做推理。它有两堵墙绕不过去第一堵是知识的时间边界——训练数据有截止日期它不可能知道今天最新的数据第二堵是行动的物理边界——模型只能输出文本它不能自己去查数据库、不能点击按钮、不能改配置文件。所以在真实业务里我们一直都靠“工具调用”给模型开一扇窗。传统的方式很好理解开发者预先定义一批函数每个函数配一个 JSON Schema 描述模型根据用户提问从函数列表里挑一个返回带参数的调用指令应用层拿到指令后在本地执行真正的函数逻辑执行结果作为文本拼回去模型再根据结果生成最终回答这套链路本身没有问题问题出在它是一对一的。每接入一个业务系统就要为这个系统写一遍适配代码每换一个模型又要检查一遍它的 function calling 参数格式是否一致。我在给一个客户接内部工单系统的时候就深有体会光是维护 OpenAPI 到 function schema 的转换层就废了两个迭代周期。这套模式有一个隐含假设工具是“应用方”视角的是应用主动告诉模型“我有什么”然后模型来调。但真实世界的复杂度在于很多能力不是应用方自己拥有的而是分布在数据库、第三方服务、设计工具、游戏引擎、调试器里。你不可能替所有系统写适配这个成本是组合爆炸级的。1.2 工具调用的天花板它到底卡在哪里我把传统工具调用的痛点总结成三个天花板这三个点也是理解 MCP 价值的最短路径。第一个是集成成本的天花板。每接一个数据源就要写一次适配。你有 5 个数据库就要写 5 套查询函数你有 3 个外部 API 就要写 3 套鉴权逻辑而这些代码往往只能在某一个 LLM 应用里复用。换个宿主全废。第二个是上下文割裂的天花板。工具调用里的每个函数都是“一次性调用”调用完之后就是一个结果字符串模型根本不知道这个函数背后是什么状态。比如你让模型“查一下所有未付款订单”模型调了 query_orders 函数拿回一组订单但当用户接着问“这些订单里金额最大的那笔是谁”时模型并没有记住查询时的列表它可能重新调用一次函数也可能凭上下文猜测。这种割裂导致对话稍微绕两步模型的工具使用质量就断崖下跌。第三个是权限与审计的天花板。老的工具调用方案里权限控制散落在一个个函数实现里你去查日志都不知道哪个用户、哪轮对话触发过哪个工具。很多 To B 场景根本过不了合规这关。这三个天花板本质上是同一个问题工具调用是“点对点”的定制协议不是“一对多”的通用协议。它缺少一个标准化的中间层来统一描述能力、绑定上下文、管理权限。1.3 能力协议的第一性原理把适配从应用方挪到能力方MCPModel Context Protocol模型上下文协议做的事情就是把这个中间层补上。它的核心思想用一句话概括能力应该由提供方主动暴露而不是由消费方逐个适配。这个思路不是 MCP 首创的编程工具里有一个非常经典的先例——LSPLanguage Server Protocol。LSP 出现之前IDE 要支持 10 种语言就得为每种语言实现一套语法分析、补全、跳转逻辑。LSP 出现之后语言服务被封装成独立进程通过标准化的 JSON-RPC 协议和 IDE 通信VS Code 只要实现一次客户端就获得了所有语言服务。MCP 几乎是同一个剧本。宿主应用Claude Desktop、IDE、Cherry Studio、各类 Agent 框架只需要实现一次 MCP 客户端就能连接所有支持 MCP 的数据源和工具服务。不管是 Figma 设计稿、MySQL 数据库、Unity 场景树还是浏览器调试接口每个能力提供方只需要实现一次 MCP Server就能被所有 MCP 客户端使用。所以 MCP 看起来是一个“协议”但它的底层思维是革命性的它不是为了让一个模型调用一个函数而是为了让一群模型、一群工具、一群能力在同一个标准下协作。这就是标题里说的“从工具调用到能力协议”——从应用方驱动的“我要调你”变成能力方声明的“我有这些能力你来发现”。2. MCP 到底是怎么工作的协议细节拆解2.1 一次握手搞清楚全世界的能力MCP 的通信模型是标准的客户端-服务器架构传输载体是 JSON-RPC 2.0。所有消息都是 JSON 格式这一点非常轻量任何语言都能实现。整个通信从一次握手开始。客户端发起initialize请求告诉服务器“我支持这些协议版本、我支持这些特性”服务器响应时会返回自己的协议版本和 capabilities——也就是说服务器允许什么、提供了什么在这个阶段就暴露清楚了。握手完成之后客户端发一条initialized通知表示“握手结束可以正式开始”。这个设计有一个很耐人寻味的地方能力发现是动态的。客户端并不需要提前知道服务器有什么工具而是在需要的时候通过tools/list拉取当前可用的工具列表拿到每个工具的 name、description、inputSchema。模型根据这个列表决定要调用哪个工具再通过tools/call发起调用。这意味着服务器可以在运行过程中动态增删工具。你上午启动服务时只有 3 个工具下午加了一个客户端下次 list 就能看到不需要改任何客户端代码。这种“可发现性”是传统 function calling 方案里最难做到的事。2.2 三类原语Tools、Resources、PromptsMCP 把能力分成了三类这是很多新手最容易搞混的地方我建议把它当成一个固定的框架来记原语方向用途典型例子Tools模型到外部可执行操作能改变状态查询数据库、发送邮件、执行构建脚本Resources外部到模型只读数据把上下文给模型文件内容、表结构、配置文件、API 响应Prompts用户/模型主动加载可复用提示模板固定的分析流程、代码审查模板、报告模板Tools 最容易被理解因为它的体验和 function calling 几乎一样。但很多人会忽略 Resources 的价值。举个例子AI 要写 SQL 查用户表最稳的做法不是让 AI 凭记忆猜表名而是先通过一个 Resource 把CREATE TABLE user的原始结构读出来再把结构拼进上下文最后才写 SQL。有了 Resources模型就不再“凭空猜”而是基于精确的元数据做决策。Prompts 则是很多人用 MCP 之后才发现真香的部分。你可以把团队里的一套“代码审查流程”做成一个 Prompt模型调用它之后会自动按照你的标准审查 MR而不是每次都要在对话里重新交代一遍规则。2.3 两条传输stdio 和 HTTPSSEMCP 定义了两类传输方式实际用起来各有各的场景。stdio 传输是最常见的方式也是我日常开发主力用的。宿主应用把一个子进程拉起来进程的标准输入、标准输出被当作消息通道两边通过 JSON-RPC 通信。好处是不需要管端口、不需要处理跨域完全没有网络安全问题坏处是这个 MCP Server 只能服务一个宿主进程适合本地开发工具比如给 Claude Desktop 配一个本地 SQLite 查询服务。HTTP SSE 传输则是为了远程服务设计的。服务器是独立部署的 HTTP 服务客户端通过 SSEServer-Sent Events订阅服务器推送的消息同时用 HTTP POST 发送请求。适合企业内部部署一个中心化的 MCP Server让多个 AI 客户端同时连上来。两条路径的选择本质上取决于你的使用场景本地单机工具选 stdio共享服务选 HTTPSSE。2.4 MCP 与 Function Calling、Computer Use 到底是什么关系这是最近被问得最多的问题三个概念经常混在一起。Function Calling 是目前各大大模型厂商实现“让模型调用函数”的一套 API 机制。它的重点是“模型这边如何把意图转成结构化的函数调用”——它是模型能力的一部分。MCP 的重点则是“工具这边如何被统一描述、发现和调用”——它是连接层的标准。两者不是二选一而是协作关系模型用 Function Calling 输出调用意图MCP 负责把意图路由到真正的能力提供方。实际上很多 MCP 客户端的内部实现就是把 MCP 工具包装成 Function Calling 的 schema 塞给模型的。Computer Use比如 Claude 的 computer use 能力则完全不同。它强调的是让模型像人一样操作屏幕、移动鼠标、点击按钮是通过模拟人类交互来操作系统。MCP 是直连接口Computer Use 是模拟操作。直连接口精度更高、更稳但前提是目标系统能提供接口模拟操作适应性强什么软件都能用但速度和稳定性都差点。实际项目里两者是互补的MCP 用不了的角落里Computer Use 可以兜底。3. 实操手写一个 MCP Server 并用客户端接上3.1 环境与依赖我先说结论用 FastMCP 写一个 MCP Server核心代码量在 30 行以内。 FastMCP 是目前最流行的 Python MCP SDK它用装饰器风格把工具、资源、提示模板的注册收敛得很干净让你把注意力放在业务逻辑上。准备条件很简单Python 3.10 以上然后安装依赖pip install -U fastmcp写这篇文章的时候 FastMCP 已经在频繁迭代所以建议你安装前看一下最新文档。我这里用的是当前主流版本的写法如果 API 有差异以官方文档为准。我选 SQLite 做示例是因为它是 Python 标准库自带的东西不需要额外启动数据库服务读者可以零依赖复现一整条 MCP 链路。3.2 写一个 SQLite 员工查询 Server我的示例场景是这样的假设本地有一个员工数据库我想让 AI 通过 MCP 直接查员工信息和部门平均薪资。我先在内存里建一个临时库然后注册两个查询工具。# server.py import sqlite3 from fastmcp import FastMCP mcp FastMCP(employee_server) # 创建一个内存数据库方便演示 conn sqlite3.connect(:memory:) conn.execute( CREATE TABLE employees ( id INTEGER PRIMARY KEY, name TEXT, department TEXT, salary REAL ) ) conn.executemany( INSERT INTO employees (name, department, salary) VALUES (?,?,?), [ (张伟, 工程部, 18000), (李娜, 设计部, 15000), (王强, 数据部, 22000), ], ) conn.commit() mcp.tool() def query_employees(department: str | None None) - list[dict]: 查询员工列表可按部门过滤 Args: department: 部门名称例如“工程部”为空时返回全部 if department: rows conn.execute( SELECT id, name, department, salary FROM employees WHERE department ?, (department,), ).fetchall() else: rows conn.execute( SELECT id, name, department, salary FROM employees ).fetchall() return [ {id: r[0], name: r[1], department: r[2], salary: r[3]} for r in rows ] mcp.tool() def get_salary_summary() - dict: 统计各部门平均薪资 rows conn.execute( SELECT department, AVG(salary) FROM employees GROUP BY department ).fetchall() return {r[0]: round(r[1], 2) for r in rows} if __name__ __main__: mcp.run(transportstdio)你可能注意到了每个函数上面的 docstring 非常关键。MCP 客户端会把这个 docstring 转成模型的上下文描述模型就是靠它来判断“什么时候该调用这个工具”、“参数应该传什么”。所以 docstring 不是写给人看的注释它就是这个工具的接口文档写得越清楚模型越不容易用错。跑起来也简单python server.py运行之后程序会驻留等待客户端通过标准输入发 JSON-RPC 请求。单独跑它什么都不会输出这很正常因为它本来就不是给人用的是给客户端用的。3.3 配置到 Claude Desktop、Cherry Studio 与 VS Code Copilot有了一个能跑的 MCP Server接下来要做的就是把客户端接上去。每个客户端的配置方式不太一样但思路是通用的告诉客户端“有一个服务启动命令是什么”。Claude Desktop 的配置文件是claude_desktop_config.json通常在用户目录下的claude文件夹里。添加一段 server 配置{ mcpServers: { employee_server: { command: python, args: [C:/projects/mcp_demo/server.py] } } }配置完成后重启 Claude Desktop在对话界面里如果能看到锤子图标就说明 MCP 连接成功了。你可以直接问它“查一下员工列表”甚至可以问“对比一下各部门平均薪资”模型会自动调用对应的工具。Cherry Studio 更直观它提供了图形化的 MCP 配置界面。在设置里找到“MCP 服务器”点击“添加”选择类型为 stdio填上 command 是pythonargs 是[C:/projects/mcp_demo/server.py]保存后列表里刷新一下就能看到工具清单。VS Code 这边新版 Copilot 已经原生支持 MCP。你可以通过命令面板执行 “MCP: Add Server”选择“stdio”类型然后填入同样的启动命令。加好之后在 MCP 面板里能看到工具列表。这里我想多说一句VS Code 的这种接入方式对我日常开发影响很大以前写脚手架、改配置都要把文件内容复制给模型现在我直接把工具节点暴露给它它能直接读文件树、读项目配置、执行命令协作感完全不同。3.4 用 Inspector 做本地调试写完 MCP Server 第一件事不是去接客户端而是先用官方调试工具 Inspector 验证一下逻辑。这个工具能极大地减少后面接客户端的不确定性。官方提供了一个调试工具通过 npx 可以启动npx modelcontextprotocol/inspector python C:/projects/mcp_demo/server.py启动后它会打开一个本地网页面板左边能看到 MCP Server 通过握手暴露出来的协议版本和 capabilities中间是 tools/list 返回的工具列表右边是手动调用面板。你可以直接在面板里点一个工具填上参数看看返回结果。这个调试面板是我见过最实用的 MCP 调试工具。因为 MCP 的 stdio 模式本质上就是进程间通信一旦 server 端启动就报错或者不输出你是很难用普通方式观察到中间状态的。Inspector 帮你把整个握手、发现、调用、返回的链路可视化定位问题就快很多。4. 热词背后几个正在落地的 MCP 场景4.1 Figma MCP还原设计稿不再靠截图Figma MCP 是这阵子热词里最让我兴奋的一个。以前让 AI 做 UI 还原流程是截图发给模型模型“看”图写代码。几张图还可以组件一多、页面一长模型经常看漏间距、字号、色值都和设计稿对不上。Figma MCP 解决的是数据链路问题。它通过 MCP Server 让模型直接读取设计稿里的节点树、样式属性、颜色变量、字体定义。模型不再靠“看”图猜数值而是直接拿到精确的padding: 16px、font-size: 14px。很多团队接入 Figma MCP 之后前端还原一个页面的时间从按小时算压缩到按分钟算。对你在热词里看到的“自然语言生成 js 脚本”本质上是这条链路的延伸。模型读完设计稿可以直接生成带交互逻辑的 JavaScript 代码因为它是基于准确的设计数据做推导而不是凭空生成。4.2 Unity / CocosCreator MCP游戏引擎接入 AI游戏引擎这个方向MCP 的渗透速度比我想象中快。Unity MCP 和 CocosCreator MCP 是目前社区最热门的两个项目。这两个 MCP Server 的核心能力是让模型理解并操作场景树。以前做 AI 辅助游戏开发只能把脚本文件内容贴给模型让它“提建议”或“生成代码片段”但模型看不到场景结构不知道哪个 GameObject 挂在哪个节点下面。Unity MCP 接入后模型可以读取场景树、获取组件列表、修改属性甚至创建预制体。我见过有人让 AI 自动在场景里摆了一排路灯还导入了材质全程是对话驱动的。这个场景的价值在于MCP 把模型从“代码生成器”变成了“引擎操作员”。以前模型只能给你代码你手动粘贴、手动挂载、手动调试现在模型可以直接操作编辑器把代码放到正确的位置省掉最繁琐的传递环节。4.3 数据库与后端MySQL、Spring Boot数据库 MCP 是当前落地最成熟的方向之一Cursor 接 MySQL MCP、Codex 配数据库 MCP 的教程到处都是。它的核心价值在于模型写 SQL 的时候不再靠猜。我举个例子。以前你在 Cursor 里配了一个 MySQL MCP问它“上个月销售额最高的前十个产品有哪些”。模型会先通过 Resource 读取当前数据库的表结构和字段注释确认确实有 sales 表和 product 表字段名是sale_amount而不是amount然后才写 SQL。如果 schema 有问题它会在写 SQL 之前就发现自己缺少信息再读取需要的元数据。这个过程和凭记忆写 SQL 相比正确率高出一个量级。我们在真实业务里经常遇到 AI 把字段名写错、JOIN 条件写反的情况根源就是模型没有看到真实 schema。MCP 把这个信息缺口填上了。后端方向还有一个值得关注的是 “Solon AI MCP Spring Boot” 这类项目本质上是把业务系统的能力封装成 MCP Server。它意味着企业内部的老系统不一定要改造成 API只要适配一个 MCP ServerAI 客户端就能直接调用它的业务能力。对于大量存量系统来说这条路径比重新写一套开放接口要省钱得多。4.4 逆向与安全研究Ghidra、x64dbg、BurpSuite热词里有不少逆向和安全的 MCP比如 Ghidra 12.0 MCP、x64dbg MCP、BurpSuite MCP。我在安全测试这个方向是有一些实际体会的。Ghidra MCP 的价值在于反汇编和反编译的结果数据量太大、结构太复杂直接贴给模型看很容易让模型“消化不良”。Ghidra MCP 把反编译结果、函数调用关系、字符串引用这些数据结构化以后通过 MCP 工具提供给模型模型可以按需查询比如“看看这个函数调用了哪些外部函数”、“这个地址被谁引用了”、“这几个函数之间有没有循环调用”。这种按需获取的方式比一次性把整个反编译结果塞给模型有效得多。x64dbg MCP 和 BurpSuite MCP 的思路类似。x64dbg 可以给模型提供动态调试的上下文比如寄存器状态、内存内容、调用栈BurpSuite 可以给模型提供 HTTP 请求和响应数据。这里我不展开具体操作因为这个方向对读者有安全门槛要求但可以明确一点MCP 在专业分析工具上的潜力远超目前大家集中在“聊天、写代码”这些面上的认知。4.5 自己实现 MCP Server 还是用现成的我的选型建议热词里有一条是“需要自己实现 mcp 还是用相关现有的 mcp 就可以了”这是我被问得最多的问题之一。我的建议很明确分三步走。第一步去官方和社区找现成的。通用能力包括文件读取、数据库查询、浏览器自动化、GitHub 操作、Figma 设计稿读取这些基本上都有成熟的项目。不要重复造轮子特别是 Chrome 相关的 MCP Server 和文件系统 MCP直接用开源方案能省一大半时间。第二步判断你的业务是否有私有性。如果你的工具涉及内部 API、私有数据库、特定业务流程基本只能自研或者基于现有项目做二次开发。这种情况我就建议你用 FastMCP 或官方 SDK 从零写一个成本很低核心逻辑就是注册方法、写业务函数。第三步评估维护成本。MCP 协议本身还在快速演进自己写 Server 的时候不要做太重的定制不要自己发明协议层。你的业务代码和 FastMCP 的对接层尽可能薄这样即使 MCP 协议更新改动范围也很小。场景推荐方案理由读取本地文件/代码库官方 filesystem MCP 或 IDE 自带成熟稳定开箱即用数据库查询MySQL MCP / sqlite MCP / Postgres MCP生态成熟配置即可用浏览器自动化Chrome DevTools MCP 等涉及细节多现成方案踩坑少内部业务系统/私有 API自研 MCP Server需要对接内部鉴权与数据模型小众工具链/引擎插件先找社区再决定自研社区可能已有可用方案没有的话才考虑自研5. 踩坑记录与排查速查表5.1 常见连接问题速查表我在实际接入各种 MCP 客户端的过程中遇到最多的问题基本都集中在配置和传输层。整理成一张表放在下面遇到问题可以直接对着查。症状可能原因解决办法客户端提示找不到 MCP Serverstdio 模式下 command 或 args 路径写错Windows 下写绝对路径command 确认是 python 还是 pyServer 启动后立刻退出Python 脚本有语法错误或依赖缺失先在终端手动跑一遍 server.py确认能驻留工具列表是空的Server 注册了工具但没走握手流程用 Inspector 调试确认 tools/list 返回正常调用工具后长时间无响应HTTPSSE 模式下网络不通或超时检查服务器地址、端口、防火墙适当调大超时时间模型提示“没有可用工具”客户端没有把 MCP 工具交给模型部分客户端需要手动启用工具或重启客户端WSL2 里装了 ServerWindows 宿主连不上stdio 传输跨 WSL 边界不稳定用网络传输模式或直接在 Windows 侧跑 Server5.2 每个 MCP 开发者都会踩的三个坑第一个坑是在 stdio 模式下乱 print。stdio 传输模式的通道就是标准输入输出你在服务端代码里如果写了print(debug)这行文本会直接混进 JSON-RPC 消息流里客户端解析必然报错。调试信息一定要走logging模块输出到 stderr或者写到日志文件。第二个坑是工具函数的返回值不可序列化。MCP 要求返回值最终必须能转成 JSON。我在写数据分析类的 Server 时踩过这个函数直接返回了一个 NumPy 数组客户端直接报错。解决办法是在返回前手动转换转成 list 或者 dict再返回给客户端。第三个坑是冷启动依赖未初始化。很多人的 Server 在函数内部才去连数据库、加载模型文件结果第一次调用时初始化耗时过长超过了客户端的等待时间。常见解决方案是把初始化放到模块加载阶段启动时完成调用时就是纯内存操作。5.3 一些提高 MCP 调试效率的习惯调试 MCP Server 的时候我的习惯是先把业务函数单独跑一遍。比如上面的query_employees我先不挂 MCP直接在一个普通 Python 脚本里调用确认逻辑正确再把它包装成 MCP 工具。等逻辑没问题了才通过 Inspector 做协议层的联调。这样能把业务 Bug 和协议 Bug 隔离不至于搅在一起。还有一个习惯是给每个 MCP Server 只安排一套“职责”。我不建议在一个 Server 里同时放数据库查询、文件读写、HTTP 请求、消息推送。单个 Server 职责单一不仅工具列表更清晰模型选择工具的准确率也会高很多。能力多了模型反而容易选错。另外日志位置和级别要一开始就规划好。我是直接在代码里加入了环境变量MCP_LOG_LEVEL的控制默认是 INFO调试的时候切到 DEBUG能输出每次消息的原始内容。这个在做 stdio 模式联调时几乎是必备的不然你永远不知道客户端到底发了什么过来。写在最后我从第一次跑通 MCP 到现在最大的感受是真正稀缺的其实不是模型的能力而是把模型和现实世界连接起来的标准化能力。MCP 让我第一次觉得AI 产品在集成新的数据源和工具时可以像拼乐高一样有一个统一的接口标准而不是每次都为特定的系统写定制代码。如果你刚开始接触 MCP我建议别一上来就研究各种复杂框架先把今天这个 SQLite 例子跑通。十几分钟能完成的事比看十篇文档都实在。跑通之后再去看 Figma MCP、Unity MCP、数据库 MCP你会发现所有项目的背后都是同一套协议逻辑。最后再分享一个小技巧在折腾 MCP 配置的时候如果发现客户端连不上不要先怀疑 MCP 协议本身大概率是路径、端口、序列化这些小问题。大部分问题在 Inspector 阶段就能定位养成了先自测的习惯之后你会节约非常多的时间。