MCP 工具列表获取机制
概述
MCP(Model Context Protocol,模型上下文协议)是一个开放协议,标准化了应用程序如何向大语言模型(LLM)提供上下文,使 AI 应用能够以一致的方式连接各种数据源和工具。
本文重点讲解 MCP 工具列表是如何获取的,以及获取的时机。
MCP 协议生命周期
MCP 定义了客户端-服务器交互的 三阶段生命周期:
1 2 3 4
| ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Initialization │ → │ Operation │ → │ Shutdown │ │ 初始化阶段 │ │ 操作阶段 │ │ 关闭阶段 │ └─────────────┘ └─────────────┘ └─────────────┘
|
初始化阶段详解
1. 建立底层连接
首先建立传输层连接,MCP 支持两种传输方式:
| 传输类型 |
适用场景 |
特点 |
| StdIO |
CLI 工具、本地进程 |
通过标准输入/输出通信 |
| HTTP |
远程访问、Web 服务 |
支持网络访问 |
2. 协议版本协商
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "clientInfo": { "name": "Claude Code", "version": "1.0.0" }, "capabilities": { "sampling": {}, "roots": { "listChanged": true } } } }
|
⚠️ 重要: 版本协商规则
- 客户端发送它支持的协议版本(通常是最新版本)
- 如果服务器支持该版本,则响应相同版本
- 双方必须就单一版本达成一致才能继续会话
3. 能力协商(Capability Negotiation)
这是 MCP 协议的核心特性,实现了协议的前向兼容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2025-06-18", "serverInfo": { "name": "Azure MCP Server", "version": "1.0.0" }, "capabilities": { "tools": { "listChanged": true }, "resources": { "subscribe": true, "listChanged": true }, "prompts": { "listChanged": true }, "logging": {} } } }
|
能力类型说明:
| 能力 |
含义 |
tools |
服务器提供可调用的工具 |
resources |
服务器提供可读取的资源 |
prompts |
服务器提供预定义的提示模板 |
logging |
支持日志功能 |
listChanged |
支持列表变更通知 |
4. 发送 initialized 通知
客户端收到服务器响应后,发送 initialized 通知,标志初始化阶段完成:
1 2 3 4
| { "jsonrpc": "2.0", "method": "notifications/initialized" }
|
工具列表获取时机
⚠️ 警告: 关键点
工具列表只能在初始化完成后获取! 在握手完成之前,不允许发送 tools/list 等功能性请求。
完整的时序图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Client Server │ │ │ ──────── 建立连接 ────────> │ │ │ │ ──── initialize request ────> │ ① 发送初始化请求 │ │ (协议版本 + 客户端能力) │ │ │ <─── initialize response ──── │ ② 返回服务器能力 │ │ (包含 tools 能力声明) │ │ │ ─── initialized notification ─> │ ③ 确认初始化完成 │ │ │ ════════ 会话就绪 ════════ │ │ │ │ ──── tools/list request ────> │ ④ 请求工具列表 │ │ │ <──── tools/list response ──── │ ⑤ 返回工具定义 │ │
|
请求:
1 2 3 4 5
| { "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
|
响应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "storage_blob_get", "description": "获取 Azure Blob 存储内容", "inputSchema": { "type": "object", "properties": { "account": { "type": "string" }, "container": { "type": "string" } }, "required": ["account", "container"] } } ] } }
|
工具列表动态更新
如果服务器声明了 tools: { listChanged: true },则支持工具列表变更通知:
1 2 3 4 5
| { "jsonrpc": "2.0", "method": "notifications/tools/list_changed" }
|
客户端收到此通知后,应重新调用 tools/list 获取最新的工具列表。
代码示例
C# 实现(Azure MCP)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public interface IMcpRuntime : IAsyncDisposable { ValueTask<ListToolsResult> ListToolsHandler( RequestContext<ListToolsRequestParams> request, CancellationToken cancellationToken );
ValueTask<CallToolResult> CallToolHandler( RequestContext<CallToolRequestParams> request, CancellationToken cancellationToken ); }
var listToolsResult = await mcpRuntime.ListToolsHandler(request, cancellationToken);
|
服务器启动模式
1 2 3 4 5 6 7 8
| azmcp server start --mode namespace --namespaces storage,keyvault
azmcp server start --mode all
azmcp server start --mode single --namespace storage
|
总结
| 阶段 |
操作 |
说明 |
| 连接建立 |
建立传输层 |
StdIO 或 HTTP |
| 初始化 |
initialize 请求 |
版本协商 + 能力声明 |
| 确认 |
initialized 通知 |
握手完成 |
| 工具发现 |
tools/list 请求 |
此时才能获取工具列表 |
| 运行时 |
工具调用 + 变更监听 |
支持动态更新 |
💡 提示: 记忆口诀
先握手,后取工具;能力先谈,功能后用
相关链接