Tools / Resources / Prompts:MCP 三类能力详解

MCP Server 可以暴露三类能力,很多人只知道 Tools,而忽略了 Resources 和 Prompts。三者设计意图完全不同。


对比总览

能力谁发起有无副作用类比适用场景
ToolsAI 自主决定有(写操作)函数调用发邮件、查天气、创建订单
ResourcesAI 按需读取无(只读)文件系统读取文档、查询数据库
Prompts用户主动触发斜杠命令代码审查模板、学习计划生成

Tools:AI 执行动作的能力

核心机制

Tool 是 MCP 最核心的能力。AI 决定是否调用、填什么参数,代码执行真实操作。

# Server 侧定义一个 Tool
@mcp.tool()
def search_notes(query: str, limit: int = 10) -> list[dict]:
    """
    搜索本地 Markdown 笔记。
    [何时用] 用户需要查找特定主题的笔记时。
    [何时不用] 如果已知文件路径,用 read_file 更直接。
    [返回] 匹配的文件列表,含路径和摘要
    """
    # 真实的搜索逻辑
    return search_filesystem(query, limit)

Tool Description 是质量瓶颈

MCP 标准化了接口格式,但无法标准化 description 的质量。AI 选错 Tool 的根本原因几乎都是 description 写得不好

高质量 description 的结构:

[何时用]    明确的触发场景
[何时不用]  边界说明(防止和其他 Tool 混淆)
[输入]      参数的语义解释,不只是类型
[输出]      返回什么,格式是什么
[副作用]    会修改什么数据,发什么通知
[失败处理]  出错时返回什么,AI 应该怎么处理

Resources:AI 按需读取数据

核心机制

Resource 是”数据地图 + 按需取数”。AI 先看目录(list),再精确读取需要的数据(read),不是一次性全部塞入 context。

# AI 的决策过程
list_resources()
→ file://src/auth.py      "用户认证模块"
→ file://src/db.py        "数据库连接层"
→ ... 共 500 个文件

# AI 自主判断只需要看 2 个文件
read_resource("file://src/auth.py")    # 消耗 ~1.5k tokens
read_resource("file://src/db.py")      # 消耗 ~1k tokens
# 总计: ~2.5k tokens(而非 500 个文件的 800k tokens)

大数据场景:Resource vs Tool 的选择原则

当数据量超过 10k tokens 时,优先用 Resource 而不是 Tool 返回值。

❌ Tool 方式(一次性塞入)
call_tool("get_codebase") → 返回全部 500 个文件 → 超出 context 限制

✅ Resource 方式(按需读取)
list_resources() → AI 判断只需要 3 个文件 → 精确读取

典型大数据场景的设计:

场景Resource 设计
代码库分析每个文件一个 Resource,URI = 文件路径
企业知识库每篇文档一个 Resource,Tool 做语义搜索返回 URI 列表
数据库查询表 schema 是 Resource,实际查询是 Tool
长文档处理按章节拆成多个 Resource,目录是单独的 Resource

URI 寻址机制

每个 Resource 有一个唯一 URI,AI 可以精确请求:

file://project/src/auth.py
db://users/user_id_123
api://salesforce/opportunity/SF-001
log://app/2025-03-19/error

Prompts:用户触发的模板能力

核心机制

Prompts 是三类能力里最容易被忽视的,但对产品化最有价值。

区别于 Tools 和 Resources 的关键:Prompts 是用户主动触发的,AI 是被动的。

触发路径:

Server 声明 Prompt 模板
    ↓
Host 展示为 "/" 斜杠命令(就像 Slack 的 slash command)
    ↓
用户选择并填入参数
    ↓
Host 调用 Server 展开模板(自动注入相关 Resource)
    ↓
完整 prompt 发给 AI,AI 开始执行

具体例子:代码审查模板

@mcp.prompt()
def code_review(file_path: str, focus: str = "general") -> str:
    """
    对指定文件进行代码审查。
    focus 可选值: security / performance / style / general
    """
    file_content = read_file(file_path)
    
    focus_map = {
        "security": "重点检查:SQL注入、输入验证、权限控制、敏感数据处理、认证漏洞",
        "performance": "重点检查:N+1查询、内存泄漏、不必要的循环、缓存缺失",
        "style": "重点检查:命名规范、函数长度、注释质量、代码重复",
        "general": "全面审查代码质量、安全性、可维护性"
    }
    
    return f"""请对以下代码进行审查:
 
文件路径:{file_path}
审查重点:{focus_map.get(focus, focus_map['general'])}
 
代码内容:
{file_content}
 
请按以下格式输出:
1. 发现的问题(按严重程度排序)
2. 具体修改建议
3. 整体评估"""

用户在 Claude Desktop 输入 /code_review,填入 file_pathfocus 两个参数,就能得到标准化的专家级代码审查——不需要用户自己会写好 prompt。

Prompts 的产品价值

把”专家用法”产品化:普通用户填参数就能得到专家级结果,质量稳定可复用。

对比:

用户直接打字使用 Prompt 模板
”帮我看下 auth.py 的安全问题”/code_review,填 file_path + focus
AI 不知道要检查哪些维度模板自动展开成含完整检查清单的专家 prompt
质量取决于用户描述能力质量稳定,Server 开发者保证

Schema:参数定义规范

Schema 是参数结构的”说明书”——告诉 AI 这个参数是什么类型、什么含义、哪些必填、取值范围是什么。

{
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词,支持姓名/邮件/手机号,最少2个字符"
      },
      "limit": {
        "type": "integer",
        "description": "返回结果数量上限",
        "minimum": 1,
        "maximum": 100,
        "default": 20
      },
      "status": {
        "type": "string",
        "enum": ["active", "inactive", "pending"],
        "description": "客户状态筛选"
      }
    },
    "required": ["query"]
  }
}

Schema 中每个关键字的作用:

关键字作用AI 如何使用
type字段数据类型确保生成正确格式的参数值
description语义解释理解何时用、填什么值
required必填字段列表调用时确保必填字段有值
enum枚举值列表只从列表中选择,不自由发挥
minimum/maximum数值范围生成的数值在合法范围内
default默认值用户未提供时使用此值

一句话总结:AI 读 description 知道”要不要调这个 Tool”,读 Schema 知道”参数怎么填”。两者缺一不可。