MCP 解决了什么,又没有解决什么?
MCP 很容易被讲成一句话:
AI 时代的 USB-C。
这个比喻有用,但也有点危险。
它会让人误以为:只要插上 MCP Server,Agent 就自然拥有了一套安全、可靠、可治理的工具系统。
不是。
MCP 解决的是连接问题。
Runtime 解决的是治理问题。
这两件事不能混在一起。
MCP 真正解决了什么
先说它解决了什么。
MCP 把 LLM 应用和外部能力之间的连接标准化了。按照官方规范,MCP 有 Host、Client、Server 这几个角色:
Host:LLM 应用,比如 IDE、聊天应用、Agent 产品
Client:Host 内部连接某个 Server 的协议客户端
Server:暴露 resources、prompts、tools 等能力
以前每接一个工具都要写一套私有 adapter。
接 GitHub,写一套。
接 Notion,写一套。
接浏览器,写一套。
接数据库,写一套。
接内部工单系统,再写一套。
MCP 的价值是把这些能力先放进同一套协议形态里:
resources/list
resources/read
prompts/list
prompts/get
tools/list
tools/call
对 Agent 产品来说,这很重要。
因为工具生态不可能全靠你自己写。未来团队内部会有 MCP Server,第三方工具会有 MCP Server,开发者本地也会有一堆 MCP Server。
没有标准协议,工具接入会碎成一地。
tools/list 让发现变标准
MCP Tools 规范里,Client 可以通过 tools/list 发现 Server 暴露了哪些工具。工具会带上名称、描述、输入 schema 等信息。
这解决了一个很实际的问题:
Runtime 不需要预先写死所有工具。
Server 可以独立升级。
工具列表可以动态变化。
模型上下文可以按需暴露工具说明。
比如一个 GitHub MCP Server 可以暴露:
search_issues
read_pull_request
create_issue
comment_on_issue
一个文件系统 MCP Server 可以暴露:
list_files
read_file
write_file
一个设计工具 MCP Server 可以暴露:
get_node
export_asset
read_variables
这些工具的发现方式统一了。
这是 MCP 的大功劳。
tools/call 让调用变标准
tools/call 解决的是调用入口。
模型决定调用哪个工具,Runtime 把调用转给 MCP Client,Client 发给对应 Server,Server 执行后返回结果。
大概是:
Model tool call
↓
Agent Runtime
↓
MCP Client
↓
MCP Server
↓
Tool result
这让外部工具像'可插拔能力'一样进入 Agent 产品。
以前一个工具要接入 Agent,需要同时考虑协议、schema、鉴权、调用、返回、错误。MCP 至少把协议层和能力描述层压平了。
开发体验会好很多。
这也是为什么 MCP 会流行。
它解决的痛点是真的。
但 MCP Server 不是 Agent
第一个误区:把 MCP Server 当 Agent。
MCP Server 暴露能力,不负责完成用户目标。
它可以提供 read_file,但不应该替用户决定要读哪个文件。
它可以提供 create_issue,但不应该替产品决定何时创建 issue。
它可以提供 query_database,但不应该替组织决定谁能查哪张表。
Agent Runtime 才是把用户目标、模型决策、工具调用、权限策略、状态和 trace 串起来的系统。
所以更准确的关系是:
User
↓
Agent Runtime
├─ Context Builder
├─ Tool Registry
├─ Permission Gate
├─ Trace / Checkpoint
└─ MCP Client Pool
├─ MCP Server A
├─ MCP Server B
└─ MCP Server C
MCP Server 是能力提供方。
Runtime 是行动管理方。
MCP Client 也不是 Runtime
第二个误区:把 MCP Client 当 Runtime。
Client 负责通信。
它知道怎么连接 Server,怎么发送 JSON-RPC 请求,怎么收结果,怎么处理 transport。
但它通常不应该独自决定:
这个工具是否暴露给模型
这个用户能不能用这个工具
这个工具是否需要审批
输出是否能进入上下文
失败后能不能重试
结果是否要写 checkpoint
这些是 Host 里的 Runtime 决策。
如果你把 MCP Client 写成'拿到工具就全部塞给模型,模型要调就直接 call',那只是接通了协议。
不是做好了 Runtime。
MCP 没有自动解决信任问题
这是最容易出事的地方。
MCP 工具的描述来自 Server。
但 Server 可以是:
你自己写的本地 Server
公司内部审计过的 Server
开源社区 Server
第三方远程 Server
临时安装的 Server
它们不能享受同一等级的信任。
一个工具描述写着:
Read project files safely.
Runtime 不能直接相信。
它还要看:
Server 从哪里来?
连接方式是什么?
工具 input schema 里有没有 path、command、url、query?
工具会不会写文件、联网、调用数据库?
输出里是否可能包含 secret?
这个用户是否允许访问对应资源?
Google Cloud 的 MCP 介绍里也提到:MCP 连接的工具可能运行代码,开发者不应盲目信任工具描述,用户应在理解工具行为后授权。
这不是小字免责声明。
这是产品边界。
MCP 没有自动解决权限审批
MCP 规范会讲 trust & safety,也有 authorization、elicitation 等能力。
但协议能力不等于你的权限系统已经完成。
权限系统要回答的问题更具体:
只读工具是否自动允许?
写入工具是否必须弹 diff?
联网工具是否展示域名?
第三方 Server 默认 ask 还是 deny?
非交互模式如何处理高风险工具?
用户批准是否持久化?
resume 后是否继续有效?
权限拒绝后模型能不能换个工具绕过去?
这些都要写进 Runtime policy。
比如我会把 MCP Server 分层:
trusted_local:本地可信,低风险只读可自动
team_audited:团队审计过,高风险仍需确认
third_party:第三方,默认 ask
unknown:未知来源,默认 deny 或强确认
同时,工具级别也要重新分类:
read
write
network
shell
database
dangerous
MCP 工具进入 Runtime 后,不应该保留'裸工具'状态。它要被包装成本地 ToolDefinition,进入同一套 Tool Registry、Permission Gate、Trace 和 Checkpoint。
MCP 没有自动解决工具过载
另一个常见问题:工具太多。
一个企业环境里,MCP Server 很容易越接越多:
GitHub
Slack
Notion
Linear
Figma
Browser
Postgres
Snowflake
Internal Docs
Kubernetes
CI/CD
如果每个 Server 暴露 10 个工具,很快就是上百个工具。
全部塞给模型会发生什么?
token 浪费
工具选择变差
误调用概率上升
prompt cache 更不稳定
调试时不知道模型看见了什么
所以 Runtime 需要两级甚至三级工具暴露:
type ToolExposure = {
allDiscovered: ToolDefinition[];
enabledForRun: ToolDefinition[];
exposedThisStep: ToolDefinition[];
};
发现到的工具,不等于本次 run 可用。
本次 run 可用,不等于本 step 要暴露给模型。
MCP 让工具变多。
Runtime 要让工具变少、变准、变安全。
MCP 没有自动解决 schema drift
MCP 工具列表可以变化。Server 升级后,schema 也可能变化。
今天:
{
"name": "search_issues",
"input": {
"query": "string"
}
}
明天:
{
"name": "search_issues",
"input": {
"repo": "string",
"query": "string"
}
}
模型上下文里如果还缓存着旧 schema,就可能继续按旧参数调用。
Runtime 要处理:
工具列表刷新
schema hash 记录
旧调用失败转 observation
trace 记录当时暴露的工具版本
eval / replay 标记不可直接复现
这类问题很烦,但必须做。
否则你会遇到最难排的 bug:昨天还能跑,今天 MCP Server 升级后,同一个 prompt 走出完全不一样的路径。
MCP 没有自动解决副作用恢复
MCP 工具不一定幂等。
read_file 可以重试。
但这些不行:
create_issue
send_message
charge_customer
run_migration
delete_record
deploy_service
如果 tools/call 发出去了,进程在等待响应时崩了,恢复时怎么办?
你不能简单说'重放上一轮'。
Runtime 要知道:
工具是否 started
是否 succeeded
是否 failed
是否 uncertain
是否可重放
是否需要人工确认状态
是否有补偿动作
这就是 tool ledger 和 checkpoint 的价值。
MCP 规范帮你定义怎么调用工具。
它不会自动知道你的 create_issue 是否已经真的创建成功。
MCP 也可以成为 Runtime 间的边界
有意思的是,MCP 不只适合'应用接外部工具'。
它也适合 Runtime 和 Runtime 之间交换能力。
比如一个产品级 Agent 可以把一部分安全工具通过 MCP 暴露给另一个 Runtime,但不暴露高风险工具:
可以暴露:
web_search
read_public_docs
export_asset
safe_browser_snapshot
不暴露:
terminal
write_file
patch
memory_write
delegate_task
credential_access
这时 MCP 变成能力边界。
边界越清楚,越能组合。
边界不清楚,就是绕过审批的新通道。
我会怎么接 MCP
如果让我在 Agent Runtime 里接 MCP,我会按这个顺序做:
第一步,只接一个本地只读 MCP Server。
不要一上来接十个。
第二步,把 MCP 工具包装成本地 ToolDefinition:
mcp.<serverId>.<toolName>
risk
source
inputSchema
timeout
outputPolicy
trustLevel
第三步,所有 MCP 工具都走同一套 Tool Registry。
不要让 MCP 工具绕过本地校验。
第四步,加 Server trust level。
未知 Server 默认不自动执行。
第五步,做工具暴露筛选。
当前任务不相关的工具,不给模型看。
第六步,把 tools/list 结果、schema hash、server id、trust level 写进 trace。
第七步,给非幂等 MCP 工具加 ledger。
恢复执行时禁止自动重放。
这套流程不华丽,但能让 MCP 从'接上了'变成'可控了'。
最后说一句实话
MCP 是好东西。
它真正解决了 AI 应用接外部能力时最痛的一层碎片化。
但不要把它当安全系统、权限系统、沙箱系统、checkpoint 系统、eval 系统。
它不是。
MCP 解决连接。
Runtime 解决控制。


