首页 › tutorials › 工具之外:MCP资源与提示词开发

工具之外:MCP资源与提示词开发

概述

绝大多数 Claude Code 的 MCP 教程都只教一件事:用 @mcp.tool() 暴露一个函数给 AI 调用。但 MCP 协议其实定义了三大原语——Tools(工具)、Resources(资源)、Prompts(提示词)。本教程聚焦被严重低估的 Resources 与 Prompts,带你搞清楚三者本质区别、控制层级的差异,并通过一个可运行的"团队周报知识库 MCP"实战项目,掌握何时该用工具、何时该用资源、何时该用提示词。适合已经能写出基本 Tool 类 MCP、想进阶理解协议全貌的开发者。

前置条件

一、核心认知:MCP 不止有工具

打开任何一篇"如何写第一个 MCP 服务器"的教程,你大概率会看到这样的代码:

@mcp.tool()
def get_weather(city: str) -> str:
    return f"{city} 今天晴"

这给你一个错觉:MCP = 给 AI 一堆可调用的函数。这只说对了三分之一。

MCP(Model Context Protocol,模型上下文协议)定义的服务器能力其实分三类,每类的控制方不同,这是整个协议最精妙的设计——也是新手最容易忽视的地方:

原语 英文 控制方 本质 典型用途
工具 Tools 模型(AI) 可执行的动词,有副作用 查数据库、发请求、写文件
资源 Resources 应用 / 用户 只读的名词,提供上下文 暴露文件、配置、文档全文
提示词 Prompts 用户 结构化交互模板 代码评审、周报复盘等固定流程

关键洞察:"谁决定用它"决定了它应该设计成哪一类原语。

这个三方划分不是为了炫技,而是为了权限边界:你不希望 AI 自己决定把整个数据库 dump 进上下文(那应该用 Resource 由你控制),也不希望它自动执行写操作而不经你确认(Tool 的副作用需要审慎)。

flowchart LR
    U([用户]) -->|"选用 Prompt"| P[Prompt 模板]
    U -->|"挂载 Resource"| R[Resource 数据]
    CC[Claude Code 宿主]
    R --> CC
    AI[AI 模型] -->|"自主调用"| T[Tool 工具]
    T -->|执行/副作用| W[(外部系统)]
    CC -->|上下文| AI
    P -->|注入指令| CC
    style T fill:#ffe4e1,stroke:#c44
    style R fill:#e1f0ff,stroke:#248
    style P fill:#e8ffe1,stroke:#282

二、三种原语的本质区别(决策树)

写 MCP 服务器前,先问自己三个问题,决定用哪种原语:

flowchart TD
    Start([要暴露一个能力]) --> Q1{AI 需要执行<br/>有副作用的动作吗?}
    Q1 -->|是| Tool[✅ 用 Tool]
    Q1 -->|否| Q2{它是一段只读数据,<br/>希望按需注入上下文?}
    Q2 -->|是| Resource[✅ 用 Resource]
    Q2 -->|否| Q3{它是一套固定的<br/>提问/工作流模板?}
    Q3 -->|是| Prompt[✅ 用 Prompt]
    Q3 -->|否| Rethink[重新审视需求]
    style Tool fill:#ffe4e1,stroke:#c44
    style Resource fill:#e1f0ff,stroke:#248
    style Prompt fill:#e8ffe1,stroke:#282

一个反直觉的结论:不要把所有东西都做成 Tool。 很多人把"读取配置文件"做成 @mcp.tool(),这是典型的滥用——配置是只读数据,AI 每次"调用工具"读取都浪费一次往返,而且无法被宿主预加载或缓存。正确的做法是做成 Resource,让 Claude Code 在需要时一次性挂载。

三、步骤一:搭建 FastMCP 骨架

我们用 FastMCP——这是 2026 年 Python 生态构建 MCP 服务器的事实标准,语法风格类似 FastAPI。它同时被官方 MCP Python SDK 作为高层封装集成。

创建项目目录并安装依赖:

mkdir weekly-kb-mcp && cd weekly-kb-mcp
python -m venv .venv && source .venv/bin/activate
pip install fastmcp

创建 server.py,先写最简骨架:

from fastmcp import FastMCP

# 服务器名称会显示在 Claude Code 的 /mcp 列表中
mcp = FastMCP("weekly-kb")

# 内嵌示例数据,让代码复制即可运行(真实场景改为读文件/数据库)
REPORTS = {
    "week-28": {
        "author": "张三",
        "content": "# 第28周周报\n\n- 完成 MCP 资源模块开发\n- 修复 3 个 SQL 探针 bug\n- 重构日志诊断模块",
    },
    "week-29": {
        "author": "张三",
        "content": "# 第29周周报\n\n- 上线周报知识库 MCP\n- 编写三原语文档\n- Code Review 5 次",
    },
}

if __name__ == "__main__":
    # 默认以 stdio 传输运行,适合 Claude Code 本地接入
    mcp.run()

预期结果:python server.py 启动后挂起等待,无报错。stdio 传输意味着 Claude Code 会把它作为子进程拉起,通过标准输入输出通信。

常见问题: - ModuleNotFoundError: No module named 'fastmcp'——确认激活了虚拟环境(source .venv/bin/activate)。 - 端口占用——mcp.run() 默认 stdio 不占端口;若你误传了 transport="http" 才会监听端口。

四、步骤二:实现 Tools(快速回顾)

工具是最熟悉的一类,这里只放对比用的实现——一个带副作用/计算的能力:

@mcp.tool()
def summarize_author(author: str) -> str:
    """统计某人在所有周报中的出现情况并返回汇总。

    Args:
        author: 作者姓名
    """
    hits = [wk for wk, r in REPORTS.items() if r["author"] == author]
    return f"{author} 共提交 {len(hits)} 篇周报:{', '.join(hits)}"

注意工具的标志:它有计算逻辑、有结构化返回,且 AI 会自主决定何时调用它(比如你问"张三这阵子都干了啥",AI 自己判断要调这个工具)。

五、步骤三:实现 Resources(重点之一)

资源是把只读数据通过 URI 暴露出去。这是本教程的核心增量。

1. 静态资源:一个 URI 对应一份数据

@mcp.resource("kb://latest")
def latest_report() -> str:
    """最新一篇周报全文"""
    last_week = list(REPORTS.keys())[-1]
    return REPORTS[last_week]["content"]

2. 模板资源(动态 URI):参数化路径

这是资源最强大的特性——用 {占位符} 声明 URI 模板,FastMCP 会自动注册成可变资源:

@mcp.resource("report://2026/{week}")
def get_report(week: str) -> str:
    """获取指定周次的周报全文。

    Args:
        week: 周次标识,如 week-28
    """
    if week not in REPORTS:
        raise ValueError(f"未找到周报: {week}")
    return REPORTS[week]["content"]

声明后,Claude Code 会识别出 report://2026/week-28、report://2026/week-29 等所有合法实例。FastMCP 会自动从函数签名和 docstring 推断参数类型,无需手写 schema。

3. 资源在 Claude Code 中如何使用

这是 Resources 与 Tools 体验差异最大的地方:

常见问题: - 资源不显示在 @ 列表——检查 URI scheme 是否合法(必须是 scheme://path 形式,如 report://、config://、file://)。 - 模板资源参数推断失败——给函数参数加上类型注解(week: str),并在 docstring 里写清楚含义。 - 想返回富文本——返回类型可声明为带 MIME 的字符串,FastMCP 支持指定 text/markdown 等。

六、步骤四:实现 Prompts(重点之二)

提示词是预制的工作流模板,由用户主动选用。它把"怎么提问"标准化,避免每次手敲长指令。

@mcp.prompt()
def performance_review(author: str, week: str = "week-29") -> str:
    """生成绩效复盘:阅读指定周报,总结贡献并给出改进建议。

    使用方式:在 Claude Code 斜杠命令中选用此 prompt,填入作者与周次。
    """
    return f"""请扮演资深技术管理者,对以下信息做绩效复盘:

1. 先读取资源 report://2026/{week}
2. 重点评估 {author} 在该周的产出
3. 输出三段:本周亮点、风险事项、下周建议

要求语气客观,用 bullet 列点,避免空话套话。"""

注意这个 Prompt 内部引用了前面定义的 Resource(report://2026/{week})——这正是三原语协同的威力:Prompt 是工作流编排,它指挥 Claude 去读 Resource、必要时调 Tool。

Prompt 在 Claude Code 中的使用

MCP prompts 在 Claude Code 里会以斜杠命令形式出现,命名规则是 /mcp__<服务器名>__<prompt名>。所以上面的 prompt 会显示为:

/mcp__weekly-kb__performance_review

输入它会弹出参数表单(author、week),填好后整段模板被注入为新对话的起始指令。这就是"user-controlled"——只有你主动选用,它才会触发,AI 不会自作主张套用模板。

常见问题: - 斜杠命令不出现——确认服务器已成功加载(/mcp 查看状态),且 prompt 函数无语法错误。 - 参数表单没字段——FastMCP 依赖类型注解和默认值推断;给参数加 : str 和默认值。 - 想返回多轮消息——@mcp.prompt() 也支持返回消息列表(list[dict]),可构造 system + user 多条消息。

七、步骤五:在 Claude Code 中配置并使用

在项目根目录创建 .mcp.json(团队共享)或用命令行添加(个人):

claude mcp add weekly-kb -- python /绝对路径/weekly-kb-mcp/server.py

或编辑 .mcp.json:

{
  "mcpServers": {
    "weekly-kb": {
      "command": "python",
      "args": ["/绝对路径/weekly-kb-mcp/server.py"]
    }
  }
}

注意:command 用绝对路径更稳妥;若用虚拟环境,写成 .venv/bin/python 可避免依赖缺失。

验证连接:在 Claude Code 中输入 /mcp,应看到 weekly-kb 状态为 connected,并展开显示其暴露的 tools、resources、prompts 三类能力。

三种典型用法对照:

你想做的事 在 Claude Code 里的操作 触发的原语
看最新周报内容 输入 @ 选 kb://latest Resource
看 28 周详情 输入 @ 选 report://2026/week-28 Resource(模板)
让 AI 统计张三产出 直接问"张三提交了几篇周报" Tool(AI 自主调用)
做一次绩效复盘 输入 /mcp__weekly-kb__performance_review Prompt

八、步骤六:用 MCP Inspector 调试

调试时不要每次都开 Claude Code,用 Inspector 可视化测试三类原语最快:

# 方式一:FastMCP 内置(推荐)
fastmcp dev server.py

# 方式二:官方 Inspector
npx @modelcontextprotocol/inspector python server.py

Inspector 会打开一个网页,左侧列出该服务器的 Tools / Resources / Prompts / Templates 四个标签页:

这是排查"为什么我的资源/提示词没出现在 Claude Code 里"最快的工具——如果 Inspector 里能看到,说明服务器没问题,问题在配置或缓存(试试重启 Claude Code)。

九、实战案例:完整的团队周报知识库 MCP

下面是整合三种原语的完整 server.py,复制即可运行。它演示了一个真实知识库 MCP 该有的分层:数据层(Resources)、计算层(Tools)、工作流层(Prompts)。

from fastmcp import FastMCP

mcp = FastMCP("weekly-kb")

# ============ 数据源(真实场景替换为读文件 / 查 DB)============
REPORTS = {
    "week-28": {"author": "张三", "tags": ["mcp", "bugfix"],
                "content": "# 第28周周报\n- 完成 MCP 资源模块\n- 修复 SQL 探针 3 个 bug\n- 重构日志诊断模块"},
    "week-29": {"author": "张三", "tags": ["mcp", "doc", "review"],
                "content": "# 第29周周报\n- 上线周报知识库 MCP\n- 编写三原语文档\n- Code Review 5 次"},
    "week-29-lisi": {"author": "李四", "tags": ["frontend", "perf"],
                "content": "# 第29周周报\n- 优化首屏加载\n- 修复白屏问题\n- 引入懒加载"},
}

# ============ Resource:只读数据层(application/user-controlled)============
@mcp.resource("kb://latest")
def latest_report() -> str:
    """最新一篇周报全文"""
    return REPORTS["week-29"]["content"]

@mcp.resource("report://2026/{week}")
def get_report(week: str) -> str:
    """获取指定周次的周报全文"""
    if week not in REPORTS:
        raise ValueError(f"未找到: {week}")
    return REPORTS[week]["content"]

# ============ Tool:计算/聚合层(model-controlled,有副作用语义)============
@mcp.tool()
def search_by_tag(tag: str) -> str:
    """按标签搜索周报,返回匹配的周次列表。

    Args:
        tag: 标签名,如 mcp / frontend / bugfix
    """
    hits = [wk for wk, r in REPORTS.items() if tag in r["tags"]]
    if not hits:
        return f"没有周报包含标签 {tag}"
    return f"标签 [{tag}] 命中:{', '.join(hits)}"

@mcp.tool()
def count_by_author(author: str) -> str:
    """统计某人提交的周报数量"""
    n = sum(1 for r in REPORTS.values() if r["author"] == author)
    return f"{author} 共提交 {n} 篇周报"

# ============ Prompt:工作流层(user-controlled,斜杠命令)============
@mcp.prompt()
def performance_review(author: str, week: str = "week-29") -> str:
    """绩效复盘:读周报 → 评估贡献 → 给建议"""
    return f"""请扮演技术管理者做绩效复盘:
1. 读取资源 report://2026/{week}
2. 评估 {author} 的产出
3. 输出:本周亮点 / 风险事项 / 下周建议
语气客观,bullet 列点。"""

@mcp.prompt()
def weekly_digest() -> str:
    """生成全员本周摘要:先按标签搜索,再汇总"""
    return """生成本周全员工作摘要:
1. 用 search_by_tag 逐个查找 mcp / frontend / bugfix 标签
2. 汇总各人产出,按人分组
3. 用一段话总结本周团队重心"""

if __name__ == "__main__":
    mcp.run()

这个设计的精髓在于职责清晰:

sequenceDiagram
    participant U as 用户
    participant CC as Claude Code
    participant AI as AI 模型
    participant S as weekly-kb MCP
    U->>CC: /mcp__weekly-kb__performance_review(张三, week-29)
    Note over CC: Prompt 被注入为指令<br/>(user-controlled)
    CC->>AI: 携带指令开始对话
    AI->>S: 读取 Resource report://2026/week-29
    S-->>AI: 返回周报全文(application-controlled 数据)
    AI->>S: 调用 Tool count_by_author(张三)
    Note over AI: model-controlled,<br/>AI 自主决定是否调
    S-->>AI: 返回 "张三共提交 2 篇"
    AI-->>U: 输出绩效复盘(亮点/风险/建议)

十、常见问题与最佳实践

Q:一个能力该做成 Tool 还是 Resource? A:有副作用、需要计算/聚合 → Tool;纯只读、希望按需注入 → Resource。记住:把"读文件"做成 Tool 是最常见的反模式。

Q:Prompt 和 CLAUDE.md 里写指令有什么区别? A:CLAUDE.md 是常驻的全局指令,永远在上下文里;Prompt 是按需触发的工作流模板,只在用户主动选用时注入。频繁流程用 Prompt,长期规则用 CLAUDE.md。

Q:模板资源 {week} 和 Tool 参数 week 有何不同? A:模板资源是宿主预先枚举成多个独立 URI,适合有限、稳定的命名空间(周次、ID);Tool 参数是运行时动态传入,适合开放查询(搜索关键词)。前者可被 @ 选择器列出,后者不能。

Q:发布给别人用时,stdio 还是 HTTP 传输? A:本地命令行用 stdio(mcp.run());要部署成云端服务供多人/多客户端连接,用 mcp.run(transport="http") 跑 Streamable HTTP,并配合鉴权。

延伸阅读

训练营适用性评估

参考来源

  1. Connect Claude Code to tools via MCP — Claude Code Docs — Claude Code 官方 MCP 接入文档,含 .mcp.json 配置与 claude mcp add 命令说明。
  2. MCP Server Patterns: Tools vs Resources vs Prompts (When to Use Each) — DEV Community — 深入对比三种原语的本质区别与使用场景,本文决策树的主要依据。
  3. MCP Tools vs Resources vs Prompts — RapidDev Tutorial — 明确指出 Tools 为 model-controlled、Resources 为 application-controlled、Prompts 为 user-controlled 的控制层级划分。
  4. MCP Server Setup — Learn to Prompt — 面向 Claude Code 等 CLI Agent 的 MCP 服务器搭建指南,覆盖 Tools/Resources/Prompts 三原语配置。
  5. MCP Developer Guide 2026: Build, Deploy & Secure AI Tool Integrations — 2026 年 MCP 开发者全景指南,含架构、部署与安全实践。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入