上周跟一个做 AI 应用的朋友聊 MCP,他一脸认真地说:“MCP 服务端嘛,就是跑在云上的,我搭了个 Node 服务,客户端连上去就行了。”
我愣了一下。兄弟,你用的 stdio 模式,那个“服务端”其实是你本地 Claude 拉起来的子进程。它压根没出过你的电脑。
这不是个例。我翻了翻几个技术群,发现一个诡异的现象:很多人用了 3 年 MCP,连“服务端”到底在哪都没搞明白。
不是你的问题。是 MCP 这名字起得太有迷惑性了。

MCP 全称 Model Context Protocol(模型上下文协议),由 Anthropic 推出的AI 模型与外部工具互通的标准化开放通信协议,统一规范 AI Agent(客户端)与各类工具服务(服务端)的交互格式,解决传统函数调用、工具对接碎片化、重复集成的痛点,大幅降低多模型、多工具场景下的集成成本,实现工具一次开发全模型、全 Agent 复用、全平台复用。

MCP核心分为 MCP Client(模型 / AI Agent 端) 和 MCP Server(工具服务端) 两端架构。
角色错位:MCP 的“服务端”根本不是你想的那样
先说结论:MCP 的“服务端”是一个协议角色,不是物理位置。
什么意思?
你打开 Claude Code,装了一个 MCP 插件(比如文件系统工具)。这个插件在配置里写的是 "type": "stdio"。当你问 Claude“帮我读一下桌面的文件”,Claude 会拉起一个子进程——这个子进程就是 MCP 服务端。

它跑在哪?跑在你自己的电脑上。 是 Claude 这个客户端 fork 出来的一个子进程。
所以严格来说,MCP 的架构是这样的:
客户端和服务端之间通过 MCP 协议通信。协议定义了“客户端能发什么请求”“服务端能返回什么响应”。
关键来了:服务端可以是本地的子进程,也可以是远程的服务器。 但大多数人默认以为“服务端=远程服务器”,这就错了。
我用过一个叫 mcp-server-sqlite 的工具,配置里写的是:
{ "mcpServers": { "sqlite": { "command": "uvx", "args": ["mcp-server-sqlite", "--db-path", "/tmp/test.db"] } } }
看到 command 和 args 了吗?这是 stdio 模式。Claude 会执行 uvx mcp-server-sqlite --db-path /tmp/test.db,然后通过标准输入输出跟这个进程通信。
这个“服务端”进程的 PID,你可以在任务管理器里找到。它就在你眼皮底下跑着。
stdio vs SSE:一个本地跑,一个远程连
MCP 协议支持两种传输方式:stdio 和 SSE。
▪ stdio:本地子进程模式
stdio 模式下,客户端启动服务端进程,通过标准输入(stdin)发送请求,从标准输出(stdout)读取响应。
优点: 零配置,不需要网络,不需要装服务端软件。客户端自己搞定一切。
缺点: 服务端跟客户端同生命周期。客户端关了,服务端就没了。而且只能本地用,不能远程访问。
我见过有人把 stdio 模式的服务端配置写成:
{ "mcpServers": { "my-tool": { "url": "http://localhost:3000/mcp" } } }
这是错的。 stdio 模式没有 url 字段,只有 command 和 args。你写 url,MCP 客户端会尝试用 SSE 模式连接,但你的服务端根本没启动 HTTP 服务,直接报错。
▪ SSE:远程服务模式
SSE(Server-Sent Events)模式下,服务端是一个 HTTP 服务,客户端通过 HTTP 请求跟它通信。
优点: 服务端可以跑在远程服务器上,多个客户端可以共享同一个服务端。适合做中心化的工具网关。
缺点: 需要自己搭服务端,配置 HTTPS、认证、部署。门槛比 stdio 高一个量级。
SSE 模式的配置长这样:
{ "mcpServers": { "my-remote-tool": { "type": "sse", "url": "https://api.mycompany.com/mcp" } } }
看到 type 和 url 了吗?这才是远程服务端的正确写法。
▪ 本质差别
维度 | stdio | SSE |
|---|---|---|
服务端位置 | 本地子进程 | 远程服务器 |
启动方式 | 客户端自动拉起 | 手动部署 |
通信方式 | 标准输入输出 | HTTP |
生命周期 | 随客户端 | 独立运行 |
适用场景 | 本地工具、开发调试 | 生产环境、多客户端共享 |
一个常见的误解: “SSE 模式免安装,所以更简单。”
不对。SSE 模式免装的是客户端这边的服务端,但你需要自己部署远程服务端。你还是要写服务端代码、配置环境、处理认证。只是不用在每台客户端机器上装一遍。
踩坑实录:我见过最离谱的 MCP 配置
⚠️ 踩坑提醒: 很多人以为 MCP 服务端必须是一个独立的 HTTP 服务,于是写了个 Express 应用,监听 3000 端口,然后在 Claude 配置里写 "command": "node server.js"。这其实是对的——stdio 模式。但问题在于,他以为这个服务端是“远程”的,于是把 server.js 部署到了云服务器上,然后在本地 Claude 配置里写 "command": "ssh user@server node /path/to/server.js"。
结果: Claude 在本地执行了 SSH 命令,远程启动了服务端,但 stdio 通信走的是 SSH 的标准输入输出。延迟高得离谱,而且 SSH 连接不稳定,经常断。
正确做法: 要么用 stdio 模式,服务端跑在本地;要么用 SSE 模式,服务端跑在远程,客户端通过 HTTP 连接。
还有一个更离谱的:有人把 MCP 服务端写成了一个 WebSocket 服务,然后在配置里写 "type": "sse",但 SSE 和 WebSocket 是两种不同的协议。MCP 的 SSE 模式用的是 HTTP 长连接 + Server-Sent Events,不是 WebSocket。客户端连上去直接报 Invalid protocol。
到底怎么选?一个简单的判断标准
问自己三个问题:
我的建议: 开发阶段用 stdio,简单直接。生产环境用 SSE,可控可管理。
但不管你选哪个,搞清楚服务端在哪。别像开头那个朋友一样,本地跑着 stdio 模式,却以为服务端在云上。
知识复利:把踩过的坑变成资产
说实话,MCP 的文档写得不算差,但概念确实容易绕晕。我花了大概两周才彻底搞明白客户端/服务端角色、stdio/SSE 区别。这期间踩的坑、翻的文档、试的配置,我都记在了 ExoMind(youhuale.cn)上。
为什么?因为这种知识太容易忘了。三个月不用 MCP,再回来配置,又得从头查一遍。ExoMind 帮我做了两件事:一是把零散的知识点结构化,二是每次踩坑都记录下来,下次直接搜。
比如“MCP 服务端位置”这个知识点,我记了三条:
url 字段只在 SSE 模式有效,stdio 模式用 command下次再有人问我“MCP 服务端在哪”,我直接甩这个笔记链接。知识复利的核心,就是让每一次踩坑都变成下一次的捷径。
💡 一句话带走: MCP 服务端是协议角色,stdio 在本地,SSE 在远程,别被名字骗了。
灵魂拷问: 你第一次配 MCP 的时候,是不是也默认把“服务端”当成了远程服务器?评论区说说你踩过的坑,我帮你拆。