在 MCP 协议中,工具定义(Tool Definition)本质上就是一段符合 JSON Schema 标准的 JSON 数据。

它的作用非常明确:它是 AI 的“产品说明书”AI 看不懂你的 Python 代码,它只能通过这段 JSON 知道:“哦,我有这个工具,它叫什么,能干什么,以及我需要给它什么参数。”

下面我为你详细拆解这个 JSON 格式的每一个字段,并提供一个完整的实战示例。

🧩 核心结构详解

一个标准的 MCP 工具定义 JSON 通常包含三个顶级字段:namedescription 和 inputSchema

1. 基础信息

表格

字段名 类型 说明 对应 Python 代码
name 字符串 工具的唯一标识符AI 调用时会使用这个名字。通常使用下划线命名法(如 get_weather)。 def get_weather(...) 中的函数名
description 字符串 工具的功能描述。这是 AI 决定是否调用该工具的关键依据。描述越清晰,AI 调用越准确。AI使用自然语言进行模糊匹配,因此描述得越准确,匹配度越高!!! 函数顶部的 """文档字符串"""
2. 输入模式 (inputSchema)

这是最复杂也最重要的部分,它遵循 JSON Schema 规范,用来告诉 AI 参数的格式。

  • type: 固定为 "object",表示参数是一个对象键值对集合,key:value)。
  • properties: 定义具体参数的“字典”
    • 键名(如 city):对应参数名。
    • 键值(如 {"type": "string", "description": "..."}):定义该参数的类型和描述
  • required: 一个字符串数组,列出必须提供的参数名。如果 AI 没提供这些参数,调用就会失败。

📝 完整示例:天气查询工具

假设我们有一个 Python 函数,用来查询天气。

Python 代码:

python

def get_weather(city: str, unit: str = "celsius") -> str:
    """
    查询指定城市的当前天气。
    
    Args:
        city: 城市名称,例如 "Beijing" 或 "Shanghai"
        unit: 温度单位,"celsius" 表示摄氏度,"fahrenheit" 表示华氏度
    """
    # ... 具体逻辑 ...
    return f"{city} 的天气是晴天,25{unit}"

对应的 MCP 工具定义 JSON:

json

{
  "name": "get_weather",
  "description": "查询指定城市的当前天气情况,支持选择温度单位。",
  "inputSchema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称,例如 'Beijing' 或 'Shanghai'"
      },
      "unit": {
        "type": "string",
        "description": "温度单位,可选值为 'celsius' (摄氏度) 或 'fahrenheit' (华氏度)",
        "enum": ["celsius", "fahrenheit"]
      }
    },
    "required": ["city"]
  }
}

🔍 字段深度解读

让我们逐行看看这个 JSON 是怎么“翻译” Python 代码的:

1. name 和 description
  • "name": "get_weather": 直接对应函数名。
  • "description": "...": 这里我们把 Python 的文档字符串提炼了一下。注意,这里不要写太复杂的代码逻辑,要用自然语言告诉 AI “这个工具能解决什么问题”
2. properties 中的类型映射

MCP 使用 JSON Schema 的类型系统,与 Python 类型的对应关系如下:

表格

Python 类型 JSON Schema 类型 示例
str "string" "hello"
int / float "number" 1233.14
bool "boolean" truefalse
list / array "array" ["a", "b"]
dict "object" {"key": "value"}
3. required (必填项)
  • "required": ["city"]:
    • 在 Python 函数中,city 没有默认值,所以是必填的。
    • unit 有默认值 "celsius",所以它是选填的。
    • 规则:只有当参数在 required 列表中时,AI 才会被强制要求提供该参数;否则 AI 可以选择不传(此时函数会使用默认值)。
4. 高级技巧:enum (枚举)
  • 注意看 unit 参数里多了一个 "enum": ["celsius", "fahrenheit"]
  • 作用这限制了 AI 只能从这两个词里选。这非常有用,可以防止 AI 瞎编参数(比如传了 "kelvin" 或 "度"),保证程序的稳定性。

🚀 调用流程演示

当这段 JSON 被发送给 AI 后,流程是这样的:

  1. 用户提问:“帮我查查上海现在的天气,用华氏度。”
  2. AI 思考
    • 看到工具 get_weather
    • 阅读 description,确认是查天气的。
    • 检查 inputSchema,发现需要 city (必填) 和 unit (可选)。
    • 从用户的话里提取:city = "Shanghai",unit = "fahrenheit"。
  3. AI 发出调用请求 (JSON-RPC):json

    {
      "jsonrpc": "2.0",
      "id": 123,
      "method": "tools/call",
      "params": {
        "name": "get_weather",
        "arguments": {
          "city": "Shanghai",
          "unit": "fahrenheit"
        }
      }
    }
  4. 你的 Server 执行:Python 函数接收到参数,执行代码,返回结果。

💡 避坑指南

  1. 描述太简略:不要只写 "Get weather"。要写 "获取指定城市的实时天气数据,包括温度、湿度和风力等级"。描述越丰富,AI 越智能。AI就靠这个进行自然语言的匹配。
  2. 类型不匹配:如果你在 Python 里要的是 int,但 JSON 里写成了 "type": "string",AI 可能会传 "100" 而不是 100,导致你的代码报错。
  3. 忘记 required:如果你的函数逻辑强依赖某个参数,一定要把它加到 required 列表里,否则 AI 可能会偷懒不传
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐