模型上下文协议 (MCP) 允许服务器公开可被语言模型调用的工具。工具使模型能够与外部系统交互,例如查询数据库、调用 API 或执行计算。每个工具都由一个名称唯一标识,并包含描述其模式的元数据。
用户交互模型
MCP 中的工具被设计为由模型控制,这意味着语言模型可以根据其上下文理解和用户提示自动发现并调用工具。 然而,实现方可以自由地通过任何适合其需求的接口模式来公开工具——协议本身不强制要求任何特定的用户交互模型。出于信任与安全以及安保的考虑,应当 (SHOULD) 始终有人工介入,并有权拒绝工具调用。应用程序应当 (SHOULD):
- 提供清晰的 UI,明确哪些工具正被暴露给 AI 模型
- 在调用工具时插入清晰的视觉指示
- 向用户呈现操作的确认提示,以确保有人工介入
支持工具的服务器必须 (MUST) 声明 tools
能力
{
"capabilities": {
"tools": {
"listChanged": true
}
}
}
listChanged
指示服务器是否会在可用工具列表发生变化时发出通知。
协议消息
为了发现可用的工具,客户端发送一个 tools/list
请求。此操作支持分页。 请求:{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"cursor": "optional-cursor-value"
}
}
响应
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"title": "Weather Information Provider",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
],
"nextCursor": "next-page-cursor"
}
}
要调用一个工具,客户端发送一个 tools/call
请求: 请求:{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"location": "New York"
}
}
}
响应
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
}
],
"isError": false
}
}
列表变更通知
当可用工具列表发生变化时,声明了 listChanged
能力的服务器应当 (SHOULD) 发送一个通知
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}
消息流
数据类型
一个工具定义包括
name
: 工具的唯一标识符
title
: 可选的、供显示用的人类可读的工具名称。
description
: 人类可读的功能描述
inputSchema
: 定义预期参数的 JSON Schema
outputSchema
: 可选的、定义预期输出结构的 JSON Schema
annotations
: 描述工具行为的可选属性
出于信任与安全以及安保的考虑,客户端必须 (MUST) 将工具注解视为不可信,除非它们来自受信任的服务器。
工具结果可能包含结构化或非结构化内容。 非结构化内容在结果的 content
字段中返回,并且可以包含多个不同类型的内容项:所有内容类型(文本、图像、音频、资源链接和嵌入式资源)都支持可选的注解,这些注解提供关于受众、优先级和修改时间的元数据。这与资源和提示使用的注解格式相同。
文本内容
{
"type": "text",
"text": "Tool result text"
}
图像内容
{
"type": "image",
"data": "base64-encoded-data",
"mimeType": "image/png"
"annotations": {
"audience": ["user"],
"priority": 0.9
}
}
此示例演示了可选注解的使用。
音频内容
{
"type": "audio",
"data": "base64-encoded-audio-data",
"mimeType": "audio/wav"
}
资源链接
一个工具可以 (MAY) 返回指向资源的链接,以提供额外的上下文或数据。在这种情况下,该工具将返回一个可由客户端订阅或获取的 URI。
{
"type": "resource_link",
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"description": "Primary application entry point",
"mimeType": "text/x-rust",
"annotations": {
"audience": ["assistant"],
"priority": 0.9
}
}
资源链接支持与常规资源相同的资源注解,以帮助客户端理解如何使用它们。
由工具返回的资源链接不保证会出现在 resources/list
请求的结果中。
嵌入式资源
资源可以 (MAY) 使用合适的 URI 方案进行嵌入,以提供额外的上下文或数据。使用嵌入式资源的服务器应当 (SHOULD) 实现 resources
能力。
{
"type": "resource",
"resource": {
"uri": "file:///project/src/main.rs",
"title": "Project Rust Main File",
"mimeType": "text/x-rust",
"text": "fn main() {\n println!(\"Hello world!\");\n}",
"annotations": {
"audience": ["user", "assistant"],
"priority": 0.7,
"lastModified": "2025-05-03T14:30:00Z"
}
}
}
嵌入式资源支持与常规资源相同的资源注解,以帮助客户端理解如何使用它们。
结构化内容
结构化内容以 JSON 对象的形式在结果的 structuredContent
字段中返回。 为了向后兼容,返回结构化内容的工具也应该 (SHOULD) 在 TextContent 块中返回序列化后的 JSON。输出模式
工具还可以提供一个输出模式用于验证结构化结果。如果提供了输出模式
- 服务器必须 (MUST) 提供符合此模式的结构化结果。
- 客户端应当 (SHOULD) 根据此模式验证结构化结果。
带输出模式的工具示例
{
"name": "get_weather_data",
"title": "Weather Data Retriever",
"description": "Get current weather data for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
},
"outputSchema": {
"type": "object",
"properties": {
"temperature": {
"type": "number",
"description": "Temperature in celsius"
},
"conditions": {
"type": "string",
"description": "Weather conditions description"
},
"humidity": {
"type": "number",
"description": "Humidity percentage"
}
},
"required": ["temperature", "conditions", "humidity"]
}
}
此工具的有效响应示例
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"content": [
{
"type": "text",
"text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\", \"humidity\": 65}"
}
],
"structuredContent": {
"temperature": 22.5,
"conditions": "Partly cloudy",
"humidity": 65
}
}
}
提供输出模式有助于客户端和 LLM 理解并正确处理结构化的工具输出,通过:
- 对响应进行严格的模式验证
- 提供类型信息以便更好地与编程语言集成
- 指导客户端和 LLM 正确解析和利用返回的数据
- 支持更好的文档和开发者体验
错误处理
工具使用两种错误报告机制
-
协议错误:标准的 JSON-RPC 错误,用于处理以下问题
-
工具执行错误:在工具结果中以
isError: true
报告
协议错误示例
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32602,
"message": "Unknown tool: invalid_tool_name"
}
}
工具执行错误示例
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{
"type": "text",
"text": "Failed to fetch weather data: API rate limit exceeded"
}
],
"isError": true
}
}
安全注意事项
-
服务器必须 (MUST)
- 验证所有工具输入
- 实施适当的访问控制
- 对工具调用进行速率限制
- 清理工具输出
-
客户端**应该**
- 对敏感操作提示用户确认
- 在调用服务器前向用户显示工具输入,以避免恶意或意外的数据泄露
- 在将工具结果传递给 LLM 前进行验证
- 为工具调用实施超时机制
- 记录工具使用情况以供审计