MCP这个词,最近几乎天天都能在技术群和社区里看到。尤其是身边的朋友开始用 Codex、Cline、VS Code Copilot 去连接 Figma、蓝湖、Playwright 这些工具之后,一个声音越来越响:MCP 到底是什么协议,为什么谁都在聊,它和之前那些 Agent 框架里的“技能”又有什么区别?作为这个系列的第六篇,我不想再去复述“什么是 MCP”这种概念,而是想把它从协议理解一路落到实际接入,把 Skill 与 MCP 的边界、常见专业软件的 MCP server、Java/Spring 生态接入方式,以及我自己踩过的坑,都掰开揉碎讲一遍。这篇文章适合已经在用或准备用 AI Agent 的人,也适合那些被“MCP server 注册不上”折磨的开发者。
1. 从“模型会调用工具”到“工具接入标准化”:MCP 到底解决了什么问题
1.1 一个老问题:每个 Agent 框架都在重复造轮子
在 MCP 出现之前,想让大模型调用外部工具,基本上每个框架都要自己写一套 function calling 的逻辑。OpenAI 有 function calling,LangChain 有自己的一套 tools 抽象,AutoGen 又有它的 tool executor。直接后果就是:同一个工具,如果要在不同的 Agent 框架里用,就要写好几套适配代码。
我当时做项目的时候最头疼的就是这个。模型要查数据库,我先给 OpenAI 写一个 query_database 函数描述;后来切到 LangChain,又要包装成 @tool;再后来团队里有人想用 Cline,又得重新配置一遍。每次切换都是体力活,而且不同框架的参数处理方式还不一样,有些模型对参数类型很敏感,传错一个嵌套对象就崩。
MCP(Model Context Protocol)本质上就是把“模型调用工具”这件事标准化了。它定义了一个通用的客户端-服务器协议,让各种 AI 应用(宿主)可以通过同一种方式连接外部工具和数据源。你可以把 MCP 理解成 USB-C:以前每个设备都有自己的充电口,现在设备端只要做一个标准口,任何支持这个协议的充电器都能用。
具体到架构上,MCP 体系里有几个概念:
- Host:最终用户面对的 AI 应用,比如 Codex、Cline、Claude Desktop、VS Code Copilot。
- Client:运行在 Host 内部的 MCP 客户端组件,负责和 Server 通信。
- Server:暴露工具给模型使用的独立程序,可以是一个本地进程,也可以是一个远程服务。
- Tool / Resource / Prompt:Server 暴露给模型的三类能力原语。
Tools 是让模型执行一个动作(比如“打开浏览器”“执行一段 SQL”“调用设计稿接口”),Resources 是让模型读取一个数据源(比如读取某个文件、某个数据库表),Prompts 是预设的提示模板。现在大家讨论得最多的还是 Tools,因为它是让 Agent “动手做事”的关键。
1.2 协议层干了什么:请求、响应和工具描述
MCP 并不规定模型应该怎么推理,它只负责把工具清单发给 Host,然后把模型选中的调用转给 Server,再把结果传回来。这个过程看起来简单,但难点在于“标准”。
协议里有一个很关键的点,就是工具描述格式。MCP 用 JSON Schema 描述每个工具的入参,格式大概是这样的:
json复制{
"name": "query_order",
"description": "根据订单号查询订单信息",
"inputSchema": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "订单号"
}
},
"required": ["order_id"]
}
}
Host 启动后会把所有工具描述和系统提示一起塞给模型,模型在生成回答时判断“要不要调用某个工具”,然后输出一个工具调用指令。Host 收到指令后,通过 MCP 协议去执行对应的 Server 方法,再把返回值作为新的上下文喂回模型。
这个流程决定了 MCP 的很多特性:工具描述必须足够清晰,入参必须稳定,Server 响应必须快。如果 Server 很慢,模型等结果等到超时,整个对话体验就崩了。而且工具的命名和描述也要遵循“模型友好”的原则,不能用太模糊的语言,否则模型很容易选错工具。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Skill 和 MCP 的区别:AI Agent 社区最常问的边界问题
2.1 Skill 是“剧本”,MCP 是“接口”
后台和群里总有人问:Agent Skill 和 MCP 有什么区别?开个新项目到底应该用哪个?我刚接触时也纠结过,后来发现它们根本不是同一个层级的东西。
Skill(或 Agent Skill)一般指的是一组有结构的提示词、流程步骤和示例,目的是让模型在特定场景下“做得更好”。比如我写过一个“代码审查 Skill”,里面包含了审查的步骤、关注点、输出格式,以及“先读 diff 再读相关文件”这样的规则。Skill 改变的是模型的行为方式,它不直接连接外部系统。
MCP 则是模型和外部系统之间的桥梁。它不告诉模型“你该怎么思考”,它只给模型提供“你可以调用哪些能力”以及“调用成功后你能得到什么结果”。
用一个类比来说:
- Skill 是剧本,告诉演员怎么演。
- MCP 是舞台上的道具,演员想用的时候伸手就能拿到,但拿道具的通道是标准化的。
- Actor(模型)根据剧本来决定什么时候伸手拿道具,而不是剧本本身自带道具。
所以“Skill 与 MCP 的区别”这个问题本身包含了误区。Skill 和 MCP 并不互斥。你完全可以写一个 Skill,在里面写明“先用 Figma MCP 拉取设计稿,再用 Playwright MCP 打开页面做对比”,但 Skill 本身不是 MCP,MCP 只是 Skill 落地时依赖的工具接口。
2.2 选型建议:什么时候单独用 Skill,什么时候必须上 MCP
如果你的任务只是让模型“用某种方式思考”,不涉及外部系统,那 Skill 就够了。比如代码审查、需求分析、SQL 编写规范,这些都是纯提示词层面的东西,没必要为了它搭一个 MCP server。
但如果你要让模型“真的去执行某个操作”,比如“把 Figma 设计稿转成网页”,那就必须有一个能访问 Figma 的通道,这就是 MCP 的活。哪怕你自己用 function calling 也能实现,但一旦你希望这段能力不仅能给当前这个 Agent 用,还能给 Codex、Cline、Copilot 复用,那用 MCP 就是最省事的选择。
还有一种混合场景:团队里既有 Skill 又有 MCP。比如我们内部有一个“前端还原”Skill,它规定模型要按“先看设计稿 → 生成页面骨架 → 跑 Playwright 验证”的流程做,中间的每一步都对应一个 MCP 工具。Skill 管流程,MCP 管操作,两者配合起来效率很高。
2.3 MCP 在多智能体协作里的角色
热词里有个“mcp多智能体”,这里我也想多说两句。很多人以为 MCP 是智能体之间通信的协议,其实不是。MCP 的定位非常明确:模型和工具之间。多智能体场景里,智能体之间的消息交互通常还是靠编排框架(比如 LangGraph、CrewAI、AutoGen)自己去实现。
不过 MCP 在多智能体系统里依然重要。因为每个智能体往往需要访问不同的工具集。比如一个“设计助手”智能体可能要连 Figma MCP 和蓝湖 MCP,一个“测试助手”智能体要连 Playwright MCP。这种情况下,每个智能体可以挂载不同的 MCP server,最后被同一个编排中枢统一调度。MCP 的价值在于让“给智能体换工具”变成改配置,而不是改代码。
我自己做过的多智能体实验里,最舒服的一点就是:同一个 MCP server(比如一个内部订单查询服务),我可以同时挂在多个智能体上,不需要为每个智能体单独写适配。智能体的职责通过 Skill 来区分,工具能力通过 MCP 来提供。
3. 生产环境接入 MCP:从客户端配置到专业软件桥接
3.1 主流客户端的 MCP 配置:Codex、Cline、VS Code Copilot
现在支持 MCP 的客户端越来越多了,但配置方式大同小异。以最常见的方式为例,大多数客户端都支持在配置文件里声明 mcpServers。
比如我想在 Cline 或 Codex 里用 Playwright MCP,配置通常长这样:
json复制{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"-y",
"@playwright/mcp@latest"
]
}
}
}
如果是需要 HTTP 连接的服务,就要写成 "url": "http://localhost:8931/mcp" 这样的形式。还有基于 SSE 的类型,现在很多客户端也支持。
这里有几个和工具链相关的细节值得注意:
- 在 Windows 下,
npx可能不在 PATH 里,或者需要加cmd /c,否则启动不了。 - Cline 里配 uv MCP 很常见,比如
"command": "uvx", "args": ["mcp-server-xxx"]。如果 uv 没有全局安装,同样建议用绝对路径,例如C:\\Users\\xxx\\AppData\\Roaming\\Python\\Scripts\\uvx.EXE。 - VS Code Copilot 连接 Figma MCP 时,要确认端口、token 和访问权限。Figma MCP 通常需要环境变量
FIGMA_API_KEY,而且要求是 Personal Access Token。 - Codex 里配置 MCP 后,如果工具没有立刻出现,考虑重启会话,或者检查 Codex 是否开启了 MCP 开关。
我自己的经验是:先用一个简单的 MCP server(比如 Playwright MCP)跑通整个链路,再去接复杂的专业软件。因为 Playwright MCP 的文档比较完善,踩坑最少。
3.2 高频专业软件 MCP:从 Figma 到 MATLAB、SolidWorks、IDA
热词里出现了大量专业软件的 MCP,可见大家已经不满足于“浏览器自动化”这种通用能力。很多垂直软件都有人在接 MCP,目前社区里比较活跃的有这么几个:
Figma MCP:目前最火的之一。官方有 figma-developer-mcp,社区也有 figma-mcp。主要能力是读取 Figma 文件、获取设计稿节点信息、图片资源,再把这些数据交给模型生成前端代码。很多设计稿转代码项目就是靠它跑通的。常见问题是 tools 注册不上,大多是 token 配置或网络导致。
蓝湖 MCP:蓝湖是国内设计协作平台,如果你团队用蓝湖做设计交付,接 MCP 后可以让模型直接读取标注和切图信息。原理和 Figma MCP 类似。
Playwright MCP:浏览器自动化测试和页面操作。模型可以通过它打开网页、点击、输入、截图、执行 JS 脚本。这个工具用途很广,不仅能做测试,也能做“自然语言生成 JS 脚本并执行”的落地。
MATLAB MCP:之前有人用 Codex 连接 MATLAB MCP,从自然语言生成 MATLAB 脚本并执行。这个场景对理工科同学很有用。配置方式一般是先启动一个本地 MATLAB MCP server,然后在 Codex 里指向它的 endpoint。
SolidWorks MCP / Comsol MCP:机械设计和仿真领域。通过 MCP 把模型参数、几何数据传给大模型,可以做一些参数化设计、仿真结果分析。这个生态还在早期,但方向很明确。
IDA Pro MCP / x64dbg MCP:逆向工程和二进制分析。用 MCP 把反汇编结果、调试状态暴露给模型,让模型辅助分析恶意样本或漏洞。这个方向比较硬核,也很好玩,但要注意安全和合规。
Burp MCP / Chat2DB MCP:Burp 是安全测试工具,Chat2DB 是数据库客户端。Burp MCP 可以让模型读取扫描结果、调用扩展工具。Chat2DB MCP 可以让模型直接查数据库、生成 SQL、执行查询。这里要注意安全控制:如果模型能够直接执行 SQL,那一定要限制权限,最好用只读账号。
3.3 免费联网 MCP 和私有化部署的取舍
热词里还有个“免费联网mcp”,我理解是很多人想通过 MCP 让模型访问互联网,又不愿意花钱买云服务。其实完全可以用本地自托管的方案,最常见的是 Fetch MCP、Playwright MCP,或者一个简单的 HTTP 请求工具。这些 MCP server 的作用就是帮模型去请求网页或 API,然后把结果返回给模型。
不过免费和联网往往有代价。自托管的 MCP server 要自己处理反爬、超时、重试、速率限制等问题。而且如果你暴露给模型的是一个会执行任意 HTTP 请求的 Server,那也要小心 SSRF(服务端请求伪造)风险。我一般会在 Server 里限制目标域名白名单,或者加上用户确认机制。
私有化部署也一样:很多企业不希望把内部数据传到外部模型服务。MCP server 完全可以部署在企业内网,让 Codex、Cline 这些客户端通过内网地址连接。协议本身不要求必须走公网,这一点对生产环境很重要。
4. Java/Spring 生态如何零成本接入 MCP
4.1 Spring 2.x 老业务:加一层 MCP 适配器,而不是改业务代码
在 Java 社区里,“mcp服务java”、“solon ai mcp springboot”、“如何让现有spring2.x业务零成本接入mcp”这些问题很常见。我一开始也以为接入 MCP 要动业务代码,后来发现完全不是。正确的做法是把 MCP server 当作一个独立的适配层,通过它去调用已有的 Spring Service。
假设你有一个很老道的 Spring Boot 2.x 项目,里面有个 OrderService.queryOrder(String orderId) 方法。你需要做的不是去改 OrderService,而是新建一个 MCP server 模块(或者一个单独的应用),在里面用 MCP SDK 暴露一个 query_order 工具,工具内部调用 OrderService。也就是说,业务代码在服务链路的最里层,MCP 在最外层,中间的适配逻辑由新的 MCP server 来写。
以 Spring AI 或者官方 MCP Java SDK 为例,你可以这样写一个工具类:
java复制@Component
public class OrderMcpTool {
private final OrderService orderService;
public OrderMcpTool(OrderService orderService) {
this.orderService = orderService;
}
@Tool(description = "根据订单号查询订单信息")
public String queryOrder(String orderId) {
return orderService.queryOrder(orderId);
}
}
然后启动一个 MCP server endpoint,让客户端连接。这样既不改 OrderService,也不需要重构原来的 Spring 2.x 应用。如果不想嵌在同一个进程里,也可以把 MCP server 打包成独立服务,通过 RPC 或 HTTP 调内部接口。
“零成本”的真正含义是:业务层面不需要感知 MCP。你只要保证 MCP server 能拿到它需要的 Service 或 API 就可以了。
4.2 Solon AI MCP Spring Boot:轻量框架的简化
热词里提到 “solon ai mcp springboot”,Solon 是一个轻量级 Java 框架,很多人用它替代 Spring Boot 来做 AI 应用。它有专门的 AI 生态,也支持 MCP。相比 Spring 那套依赖注入和配置,Solon 的启动更快、资源配置更轻,适合做独立的 MCP server 进程。
如果团队已经在用 Spring Boot 2.x,我不建议立刻切换,就用上面说的适配层方式最稳。如果是一个新的 MCP 中间件项目,可以考虑 Solon 这种方案,尤其是当你只想要一个轻量的 MCP server 而不想引入全套 Spring 时。
我在 Java 生态里的感触是:MCP 对 Java 开发者挺友好,因为 Java 的类型系统比较强,写工具方法时天然能做参数校验和类型映射。而且 MCP 的 JSON Schema 描述和 Java 方法签名能比较好地对应起来,不像一些脚本语言那样容易出类型问题。
5. 自己写一个 MCP Server:Tool Schema 和动态调用的关键点
5.1 从零到一:一个最小 MCP Server
不管是用 Python、TypeScript 还是 Java,写一个 MCP Server 都不复杂。以 Python 的 mcp Python SDK 为例,一个最简单的 server 也就十几行代码:
python复制from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""两数相加"""
return a + b
if __name__ == "__main__":
mcp.run()
用 FastMCP 之后,工具注册、参数校验、协议通信都帮你封装好了。你只需要把自己的函数暴露出去。TypeScript 生态有 @modelcontextprotocol/sdk,Java 有 mcp-java-sdk,都是差不多思路。
这里有个很容易踩的坑:Server 的日志不要打到 stdout。因为 MCP 本地通信走 stdio,stdout 是协议通道,如果你自己写 print("hello"),会污染协议数据流,客户端解析就会失败。正确做法是打日志到文件或者 stderr。
5.2 inputSchema 支持类型嵌套吗?
这个热词问得很细:“mcp tools inputschema是否支持类型嵌套”。答案是支持。MCP 的工具入参就是 JSON Schema,所以 object 嵌套 array、嵌套 object 都是合法的。举个例子:
json复制{
"type": "object",
"properties": {
"filters": {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"required": ["filters"]
}
模型在调用工具时,会按照这个 schema 生成一个 {"filters": {"status": "pending", "tags": ["urgent"]}} 这样的参数对象。如果你的工具实现端支持这种嵌套结构,那完全没问题。
但我实际测试下来的经验是:能浅尽量浅。嵌套层次越深,模型生成错误参数的概率越高。尤其是当你用的模型能力不强时,让它生成一个三层的嵌套对象,经常会把字段名拼错或者缺失必填字段。比较好的做法是拆分工具,把复杂的入参拆成多个简单工具,或者用 description 写清楚每个字段的含义和示例值。
5.3 自然语言生成 JS 脚本:自己实现还是用现成 MCP?
热词里有一句“自然语言生成js脚本,需要自己实现mcp?还是用相关现有的mcp就可以了”。这个问题非常典型。如果你要做的只是“让模型打开一个网页,执行一段 JS 脚本并获取结果”,那直接用 Playwright MCP 就够了,它本身就支持 execute_script 这类工具。
但如果你要的是一个“专门生成并且执行 JS 脚本的沙箱”,可能就需要自己写一个 MCP server。原因很简单:Playwright MCP 是在浏览器环境里执行 JS,如果你的脚本需要 Node.js 环境,需要访问文件系统、调用第三方 npm 包,那浏览器环境就不合适了。你需要写一个 MCP server,内部用 Node 子进程或者一个安全沙箱去执行用户生成的 JS 代码。
我的建议是:
- 如果是通用场景,优先找现成 MCP。去 GitHub 搜
mcp-server关键词,再对着热词里的场景找,大概率已经有了。 - 如果是公司内部特有逻辑,自己实现。但要控制好执行权限,最好把 MCP server 封装成独立服务,别让它直接接内网核心数据库。
5.4 判断标准:复用现成还是自研
我给自己定的判断标准就三条:
- 能力是否是通用的?是 → 现成 MCP。
- 是否需要对接内部私有 API?是 → 自研。
- 是否有安全和审计要求?是 → 自研,并且要有完整的日志和权限控制。
很多时候大家会高估自研的必要性。我现在遇到新需求,第一反应永远是去搜有没有现成的 MCP server,第二反应才是自己写。因为你写一个能用的 server 容易,但你要维护好协议的版本兼容、异常重试、安全边界,这就不是一两天的事了。
6. 高频问题排查与避坑实录
6.1 Codex 里 Figma MCP 总是工具注册不上
这个是热词里被问了很多次的问题:“figma mcp 在 codex 中总是工具注册不上”。我遇到过,也帮人排查过,通常就这几个原因:
- Token 没有传递到子进程:Figma MCP 启动时需要读取
FIGMA_API_KEY环境变量。在 Codex 的 MCP 配置里,你要在配置文件中显式设置env字段,而不是依赖系统环境变量。 - npx 缓存或网络问题:如果本地曾经装过旧版本,npx 可能会缓存出问题。可以先手动跑一遍
npx -y figma-developer-mcp --stdio,看能不能正常启动。 - 协议输出被污染:如果你用的 MCP server 版本比较老,它可能在 stderr 或 stdout 里打印了无关内容,导致 Codex 无法解析。换最新版试试。
- 配置文件没有生效:Codex 有时候需要重启会话才重新读取 MCP 配置。
排查顺序就是:先手动启动 server → 再确认 token → 再看延迟出现的报错 → 最后看协议日志。
6.2 Kilo 调用 MCP 是靠模型还是靠代码规则?
热词里有“kilo调用mcp是通过模型,还是通过代码规则?”。我的理解是用户在问 MCP 调用决策的机制。答案是:最终决定权在模型,但代码规则负责边界和安全性。
MCP 协议本身不会替模型决定“这个工具该不该调用”。Host 只是把工具清单给了模型,模型根据用户问题的上下文,在推理的时候生成一个工具调用请求。如果模型觉得不需要,它就不会调。所以说“模型决策”这个环节是真实的。
但同时,MCP server 的代码规则也在起作用。工具是否暴露、参数是否合法、返回结果如何过滤,这些都写在代码里。你可以在 MCP server 里加权限校验、次数限制、敏感字段脱敏,这些规则是模型无法绕过的。所以更好的说法是:模型负责“决定调用哪个工具”,代码负责“决定什么情况下允许调用”。
6.3 其他高频问题速查表
| 问题 | 可能原因 | 解决建议 |
|---|---|---|
| MCP server 连接后工具列表为空 | 协议配置错误或 server 启动失败 | 手动运行 server 命令,看是否有报错;确认启动路径正确 |
| 工具能看见但调用超时 | server 阻塞或网络延迟 | 查看 server 日志;给工具调用设置 timeout;检查代理/防火墙 |
| Windows 下 npx 无法启动 | PATH 或 shell 解析问题 | 在 command 前加 cmd /c,或写绝对路径 |
| Cline 配置 uv MCP 失败 | uv 未安装或 uvx 路径不对 | 安装 uv 并确认 uvx 可用,配置中使用绝对路径 |
| Figma 工具注册了但说没有权限 | token 过期或权限不足 | 重新生成 Personal Access Token,并确认有项目访问权限 |
| 本地 dev server 通过 MCP 访问不到 | CORS 或端口绑定问题 | 确认 server 监听 127.0.0.1 还是 0.0.0.0,调整客户端访问地址 |
| Spring 2.x 接入 MCP 后事务失效 | MCP server 与业务服务不在同一个 Spring 容器 | 通过已有接口调用,避免在 MCP 工具层直接开事务 |
还有一点要提醒:有些专业软件 MCP 本身还处于早期阶段,作者可能没有做很好的异常处理。你在接入时最好先把对方 server 的源码跑一遍,看看它对外部依赖的要求,比如 MATLAB MCP 是不是真的需要本地安装 MATLAB、SolidWorks MCP 是不是只能跑在 Windows + 特定版本上。这种生态型工具,很多时候问题不在 MCP 协议,而在上游软件本身。
最后再分享一个小技巧:如果你刚开始接触 MCP,不要从自己写 server 开始。先把 Playwright MCP 配上,随便写一句“打开某个页面,截一张图给我”,感受一下整个调用链路。等你理解了模型、客户端、server 三者之间的关系,再去看 Schema、嵌套参数、权限控制这些细节,会轻松非常多。这也是我在这个系列里反复强调的理念:协议理解得再好,不如真正跑通一个案例。
