Model Context Protocol (MCP) 允许服务器暴露可供语言模型调用的工具。工具使模型能够与外部系统交互,例如查询数据库、调用API或执行计算。每个工具通过唯一的名称标识,并包含描述其模式的元数据。
用户交互模型
MCP中的工具被设计为模型控制的,这意味着语言模型能够根据其上下文理解与用户提示,自动发现并调用工具。
然而,实现可以自由通过任何适合其需求的接口模式来暴露工具——协议本身并不强制任何特定的用户交互模式。
为了信任、安全性和风险控制,应当始终保持人类在循环中,并具备拒绝工具调用的能力。应用程序应当:
- 提供用户界面,清晰展示哪些工具正在暴露给AI模型
- 调用工具时插入清晰的可视化指示器
- 向用户展示操作确认提示,以确保人工参与其中
功能特性
支持工具的服务器 必须 声明 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"
}
]
}
],
"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: 功能的人类可读描述
inputSchema: JSON模式定义预期参数
outputSchema: 可选,用于定义预期输出结构的JSON模式
annotations: 可选属性,用于描述工具行为
为确保信任、安全与保障,客户必须考虑工具注释不被信任,除非它们来自可信服务器。
工具结果可能包含 结构化 或 非结构化 内容。
非结构化 内容被返回到结果的 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"
}
资源链接
一个工具可以返回指向Resources的链接,以提供额外的上下文或数据。这种情况下,该工具将返回客户端可订阅或获取的URI:
{
"type": "resource_link",
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"description": "Primary application entry point",
"mimeType": "text/x-rust"
}
资源链接支持与常规资源相同的资源注释,以帮助客户端理解如何使用它们。
工具返回的资源链接无法保证会出现在resources/list请求的结果中。
嵌入资源
Resources 可以 通过嵌入来使用合适的 URI scheme 提供附加上下文或数据。使用嵌入式资源的服务端 应该 实现 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字段。
为保持向后兼容性,返回结构化内容的工具也应当在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
}
}
}
提供一个输出模式有助于客户端和LLMs通过以下方式理解和正确处理结构化工具的输出:
- 开启响应的严格模式架构验证
- 提供类型信息以便更好地与编程语言集成
- 引导客户端与LLMs正确解析并利用返回数据
- 支持更好的文档和开发者体验
错误处理
工具使用两种错误报告机制:
-
协议错误: 标准JSON-RPC错误类型,适用于以下问题:
-
工具执行错误: Reported in tool results with
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
}
}
安全考量
-
Servers 必需:
- 验证所有工具输入
- 实施恰当的访问控制
- 限制工具调用频率
- 净化工具输出内容
-
客户端应该 (SHOULD):
- 在敏感操作上提示用户确认
- 在调用服务器之前向用户显示工具输入,避免恶意或意外的数据泄露
- 在传递给大语言模型LLM之前验证工具结果
- 为工具调用实现超时机制
- 记录工具使用情况以便审计