MCP核心概念与架构
理解 MCP 协议要先理解三个角色:Host、Client、Server,以及它们之间的通信方式。
1. 三大角色
┌─────────────────────────────────────────┐
│ Host (Claude Desktop) │
│ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ Client A │ │ Client B │ │Client C│ │
│ └────┬─────┘ └─────┬────┘ └───┬────┘ │
└───────┼──────────────┼───────────┼──────┘
│ │ │
↓ ↓ ↓
[GitHub MCP] [SQLite MCP] [Files MCP]
Server Server Server
Host
Host 是最终用户使用的 LLM 应用,比如 Claude Desktop、Cursor、Claude Code。它负责:
- 加载用户配置的 MCP Server 列表
- 启动 Client 实例去连接 Server
- 把 Server 提供的能力暴露给底层 LLM
Client
Client 是 Host 内部的连接器,一个 Client 对应一个 Server。它负责:
- 跟某个 Server 建立连接
- 转发请求和响应
- 管理会话状态
Server
Server 是真正提供能力的进程。它声明自己有哪些 Tools、Resources、Prompts,等着 Client 来调用。
通常 Server 由第三方开发者编写并发布(GitHub MCP、SQLite MCP 等),用户只是配置使用。
2. 通信流程
MCP 基于 JSON-RPC 2.0 协议,所有消息都是 JSON 格式。
初始化握手
Client 连上 Server 后第一件事是握手:
Client → Server: initialize
{
"protocolVersion": "2024-11-05",
"capabilities": { ... },
"clientInfo": { "name": "Claude Desktop", "version": "1.0" }
}
Server → Client: initialize 响应
{
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"serverInfo": { "name": "github-mcp", "version": "0.1.0" }
}
握手中双方互相声明自己支持的能力(capabilities)。
能力发现
握手后,Client 可以查询 Server 提供了什么:
Client → Server: tools/list
Server → Client: 工具列表(含名称、描述、参数 schema)
Client → Server: resources/list
Server → Client: 资源列表(含 URI、描述)
Client → Server: prompts/list
Server → Client: 提示词列表(含名称、参数)
调用执行
发现能力后,根据需要调用:
Client → Server: tools/call
{
"name": "get_pr",
"arguments": { "repo": "anthropic/mcp", "id": 42 }
}
Server → Client: 调用结果
{
"content": [
{ "type": "text", "text": "PR 标题: ..." }
]
}
3. 三大原语详解
Tools(工具)
模型可以主动调用的函数,对应 Function Calling。
{
"name": "search_files",
"description": "在指定目录下搜索文件",
"inputSchema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"pattern": {"type": "string"}
},
"required": ["path", "pattern"]
}
}
特点:
- 由模型决定调用时机
- 有副作用(读、写、查询)
- 描述要清晰,帮助模型判断何时调用
Resources(资源)
只读的数据/上下文,可以是文件、API 响应、数据库表等。
特点:
- 由用户/客户端选择性加载(不是模型自动调用)
- 类似 RAG 中的"知识库"
- 适合提供大量背景信息
Tools vs Resources 的区别:
| 维度 | Tools | Resources |
|---|---|---|
| 控制方 | 模型 | 用户/客户端 |
| 副作用 | 可有 | 无(只读) |
| 类比 | POST/PUT 接口 | GET 接口 |
Prompts(提示词)
预制的高质量提示词模板,由用户主动触发。
{
"name": "code_review",
"description": "对代码进行严格的 Code Review",
"arguments": [
{"name": "language", "description": "编程语言", "required": true}
]
}
特点:
- 由用户触发(如在 Claude Desktop 输入
/code_review) - 服务于特定场景的最佳实践
- 可以包含多轮消息模板
4. 通信传输方式
MCP 协议本身和传输层无关,目前主要支持三种:
stdio(标准输入输出)
最简单的方式,Server 是一个本地子进程,Client 通过标准输入/输出与它通信。
适合场景: 本地工具、桌面应用集成。Claude Desktop 默认用这种。
SSE(Server-Sent Events)
基于 HTTP,Server 单独运行,Client 通过 SSE 长连接订阅消息。
适合场景: 远程 Server、Web 应用集成。
Streamable HTTP(最新版)
2025 年推出的新传输方式,纯 HTTP,比 SSE 更易实现。是未来主流。
适合场景: 云端部署、企业内部署。
5. 安全模型
MCP 设计时充分考虑了安全:
| 机制 | 说明 |
|---|---|
| 本地优先 | Server 默认运行在用户本地,敏感数据不离开设备 |
| 用户授权 | 高风险操作(写文件、发邮件)需要用户确认 |
| 能力声明 | Server 必须显式声明自己提供什么,不能"偷偷"调用 |
| 隔离运行 | 每个 Server 在独立进程中,crash 不影响其他 |
| 审计日志 | 客户端可以记录所有调用,方便排查 |
6. 一个完整的请求示例
假设用户在 Claude Desktop 问:"这个项目的 README 写了什么?"
- Claude Desktop(Host)启动时已加载文件系统 MCP Server
- Client A 连接到 File MCP Server
- Client A 调用
resources/list,获取可用资源列表,包括file:///project/README.md - Claude(LLM)看到资源列表,决定读取 README
- Client A 调用
resources/read,URI 为file:///project/README.md - Server 返回文件内容
- Claude 基于内容生成回答给用户
整个过程对用户透明,但每一步都有协议规范。
7. MCP vs 传统 RESTful API
很多人会问:"MCP 不就是 REST API 吗?"区别在于:
| 维度 | REST API | MCP |
|---|---|---|
| 目标 | 服务对服务通信 | LLM 应用集成 |
| 协议 | HTTP + JSON | JSON-RPC(多种传输) |
| 状态 | 一般无状态 | 有会话状态 |
| 能力描述 | OpenAPI / 文档 | 协议自带 list 接口 |
| 专为 AI 设计 | 否 | 是(描述、schema 都为 LLM 优化) |
MCP 的关键差异在于专为 LLM 设计——schema 描述、错误信息、返回格式都考虑到了模型如何理解和使用。
8. 协议版本与兼容性
MCP 还在快速演进,目前的版本:
2024-11-05:首次发布2025-03-26:增加 streamable HTTP 等2025-06-18:当前主流版本
握手时双方协商版本,老 Server 通常能被新 Client 兼容使用。
总结
- MCP 由 Host、Client、Server 三层组成,一个 Host 可以连多个 Server
- 协议基于 JSON-RPC 2.0,分为初始化、能力发现、调用三阶段
- 三大原语:Tools(模型调用)、Resources(用户加载)、Prompts(用户触发)
- 三种传输方式:stdio(本地)、SSE(远程)、Streamable HTTP(最新)
- 设计强调本地优先、用户授权、能力隔离,适合 LLM 时代的安全需求