Model Context Protocol (MCP) 允许服务器暴露可由语言模型调用的工具。工具使模型能够与外部系统交互,例如查询数据库、调用 API 或执行计算。每个工具都由一个名称唯一标识,并包含描述其模式的元数据。
用户交互模型
MCP 中的工具旨在成为 模型控制 的,这意味着语言模型可以根据其上下文理解和用户的提示自动发现和调用工具。
然而,实现可以通过任何适合其需求的界面模式暴露工具——协议本身并不强制任何特定的用户交互模型。
为了信任、安全和安保,始终 应该 有人类在循环中,能够拒绝工具调用。应用程序 应该:
- 提供清晰显示哪些工具正暴露给 AI 模型的 UI
- 在调用工具时插入清晰的视觉指示器
- 向用户呈现操作确认提示,以确保人类在循环中
支持工具的服务器 必须 声明 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"]
},
"icons": [
{
"src": "https://example.com/weather-icon.png",
"mimeType": "image/png",
"sizes": ["48x48"]
}
],
"execution": {
"taskSupport": "optional"
}
}
],
"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 能力的服务器 应该 发送通知:
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}
消息流
数据类型
工具定义包括:
name:工具的唯一标识符
title:可选的人类可读工具名称,用于显示目的。
description:功能的人类可读描述
icons:可选的图标数组,用于用户界面显示
inputSchema:定义预期参数的 JSON Schema
- 遵循 JSON Schema 使用指南
- 如果不存在
$schema 字段,默认为 2020-12
- 必须 是有效的 JSON Schema 对象(不是
null)
- 对于没有参数的工具,使用以下有效方法之一:
{ "type": "object", "additionalProperties": false } - 推荐:显式仅接受空对象
{ "type": "object" } - 接受任何对象(包括带有属性的对象)
outputSchema:可选的 JSON Schema,定义预期输出结构
annotations:描述工具行为的可选属性
execution:描述执行相关属性的可选对象
taskSupport:指示此工具是否支持 任务增强执行。值:"forbidden"(默认)、"optional" 或 "required"
为了信任、安全和安保,客户端 必须 将工具注解视为不可信,除非它们来自受信任的服务器。
工具名称
- 工具名称 应该 长度在 1 到 128 个字符之间(包含)。
- 工具名称 应该 被视为区分大小写。
- 以下 应该 是唯一允许的字符:大写和小写 ASCII 字母 (A-Z, a-z)、数字 (0-9)、下划线 (_)、连字符 (-) 和点 (.)
- 工具名称 不应该 包含空格、逗号或其他特殊字符。
- 工具名称 应该 在服务器内唯一。
- 示例有效工具名称:
- getUser
- DATA_EXPORT_v2
- admin.tools.list
工具结果
工具结果可能包含 结构化 或 非结构化 内容。
非结构化 内容在结果的 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"
}
资源链接
工具 可以 返回指向 资源 的链接,以提供额外的上下文或数据。在这种情况下,工具将返回一个 URI,客户端可以订阅或获取该 URI:
{
"type": "resource_link",
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"description": "Primary application entry point",
"mimeType": "text/x-rust"
}
资源链接支持与常规资源相同的 资源注解,以帮助客户端理解如何使用它们。
工具返回的资源链接不保证出现在 resources/list 请求的结果中。
嵌入资源
资源 可以 被嵌入以使用合适的 URI 方案 提供额外的上下文或数据。使用嵌入资源的服务器 应该 实现 resources 能力:
{
"type": "resource",
"resource": {
"uri": "file:///project/src/main.rs",
"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"
}
}
}
嵌入资源支持与常规资源相同的 资源注解,以帮助客户端理解如何使用它们。
结构化内容
结构化 内容作为结果 structuredContent 字段中的 JSON 对象返回。
为了向后兼容,返回结构化内容的工具 应该 也在 TextContent 块中返回序列化的 JSON。
输出模式
工具还可以提供输出模式以验证结构化结果。
如果提供了输出模式:
- 服务器 必须 提供符合此模式的结构化结果。
- 客户端 应该 针对此模式验证结构化结果。
带有输出模式的示例工具:
{
"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 正确解析和利用返回的数据
- 支持更好的文档和开发者体验
模式示例
带有默认 2020-12 模式的工具:
{
"name": "calculate_sum",
"description": "Add two numbers",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
}
带有显式 draft-07 模式的工具:
{
"name": "calculate_sum",
"description": "Add two numbers",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
}
带有无参数的工具:
{
"name": "get_current_time",
"description": "Returns the current server time",
"inputSchema": {
"type": "object",
"additionalProperties": false
}
}
错误处理
工具使用两种错误报告机制:
-
协议错误:用于以下问题的标准 JSON-RPC 错误:
-
工具执行错误:在工具结果中报告,带有
isError: true:
- API 失败
- 输入验证错误(例如,日期格式错误、值超出范围)
- 业务逻辑错误
工具执行错误 包含可操作的反馈,语言模型可利用这些反馈进行自我纠正并使用调整后的参数重试。
协议错误 表明请求结构本身存在问题,模型不太可能修复这些问题。
客户端 应 向语言模型提供工具执行错误,以实现自我纠正。
客户端 可 向语言模型提供协议错误,尽管这些错误不太可能导致成功恢复。
协议错误示例:
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32602,
"message": "Unknown tool: invalid_tool_name"
}
}
工具执行错误示例(输入验证):
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{
"type": "text",
"text": "Invalid departure date: must be in the future. Current date is 08/08/2025."
}
],
"isError": true
}
}
安全注意事项
-
服务器 必须:
- 验证所有工具输入
- 实施适当的访问控制
- 限制工具调用速率
- 清理工具输出
-
客户端 应:
- 在敏感操作上提示用户确认
- 在调用服务器前向用户显示工具输入,以避免恶意或
意外数据泄露
- 在传递给大语言模型之前验证工具结果
- 为工具调用实施超时
- 记录工具使用情况以供审计