Appearance
MCP 的执行边界:Host、Client、Server 与 Stateless Core
前置:Tool Contract;Policy / Approval;稳定的 Runtime Boundary
核心问题:MCP Host、Client、Server 各自持有什么状态,为什么协议 Server 不应该直接变成 Harness 的 Run Runtime?
IDE Host 可连接 GitHub 和数据库两个 MCP Server,各 client 独立应用授权、路由和 capability filtering。同一个 tools/list 语义可通过支持的 transport 发送;业务 adapter 不应把 HTTP connection state 当协议 state。
Mental Model
text
Harness Tool/Resource intent → MCP Adapter/Client → stateless JSON-RPC → Server → result/error → internal domain model不要用旧 session 心智模型理解 2026 MCP。长生命周期能力放在 Tasks/应用 state/缓存等明确资源里,核心 request 仍保持自描述和 stateless。
MCP Host / Client / Server
最容易理解的方法是先把三者放到一条调用链里:
text
用户所在应用 / Agent Host
↓
MCP Client
↓ protocol request
MCP Server
↓
tool / resource / prompt capabilityHost 拥有用户、权限、Agent Runtime 和最终控制权;Client 是 Host 内负责讲 MCP 协议的适配层;Server 只是通过协议暴露能力的一端。
因此 MCP Server 不是一个完整 Agent,也不应该决定 Host 的 approval、credential 或 Run state。Server 可以请求能力,真正是否执行仍由 Host 的 policy/runtime 决定。
JSON-RPC Mental Model
MCP 方法基于 JSON-RPC request/result/error 语义;协议 adapter 应把 transport/protocol error 翻译成内部错误类别。
MCP 使用 JSON-RPC 风格请求/响应/通知语义。
Stateless Core
2026-07-28 移除了 initialize/initialized 与 Mcp-Session-Id;每个 request 在 meta 携带版本/客户端能力, server/discover 可选。
2026-07-28 规范把核心改为 stateless:不再依赖初始化握手和协议 session 保存隐式状态。每个请求应携带足够路由/描述信息,应用状态由应用自己持久化。
最小实现 / 数据结构
python
class McpToolAdapter:
async def call(self, call):
request = self.codec.to_mcp(call)
response = await self.client.request(request)
return self.codec.from_mcp(response)在 Shadow Harness 中怎么落地
MCP Adapter 把远程 Tool/Resource/Extension 映射到内部 contract;Runtime 不直接依赖 SDK 类型和 protocol session。
Failure Modes
继续按旧初始化 Session 心智模型设计 2026 MCP
症状: 新实现仍要求 initialize/initialized 或把应用状态绑定 transport session。
为什么危险: 与 2026-07-28 stateless core 不一致,扩展和横向扩展被旧 session 假设绑住。
处理: 请求 self-describing;任务状态放 Durable Store/Tasks extension,旧模式只做迁移兼容。
如何验证
| Case | 断言 |
|---|---|
| 继续按旧初始化 Session 心智模型设计 2026 MCP | 无初始化握手发独立请求,server 能按 method/name/auth metadata 处理。 |
自测
- MCP Host、Client、Server 分别位于哪一侧?为什么 Server 暴露 Tool 并不等于它拥有 Harness 的顶层控制权?
- 所谓 stateless core 主要意味着请求处理不依赖隐藏会话状态;哪些长任务状态仍应放在扩展或 Harness Runtime 中?