首页 › tutorials › 造MCP提示词库:高频Prompt固化成可复用模板

造 MCP 提示词库:把高频 Prompt 固化成可复用模板

概述

本教程带你构建一个以 Prompts 原语为核心的 MCP 服务器。MCP 有三原语——Tools(工具)、Resources(资源)、Prompts(提示词),但绝大多数教程只讲前两个。Prompts 才是把团队高频提示词"产品化"的关键:客户端能自动列出、自动渲染参数表单、自动拼好 system/user/assistant 消息。学完你能造一个研发提示词库 MCP,让 Claude Desktop、Inspector、任意 MCP 客户端一键调用规范化的代码审查、提交信息、调试提示。适合已用过 FastMCP 写过 Tool、想补齐全三原语的开发者。


一、为什么是 Prompts:被忽视的第三原语

很多人写 MCP 服务器只会写 @mcp.tool(),把所有逻辑塞进工具里。这其实浪费了 MCP 设计中最优雅的部分。三原语各司其职:

原语 本质 谁主动 触发方式
Tools 模型可调用的函数 模型自主决定调用 模型在生成中触发
Resources 模型可读取的数据 客户端/用户注入上下文 客户端挂载到上下文
Prompts 预制的、带参数的消息模板 用户主动选择 用户在客户端点击/输入触发

关键区别在于 Prompts 是面向"人"的入口。它对应那些你每天都要重复打、每次只改几个变量的高频提示。比如:

这些提示词,你手敲一年会敲出十几个变体,团队成员各敲各的、质量参差。把它们固化成 MCP Prompt 之后会发生三件事:

  1. 可发现——客户端自动列出所有提示词,像命令面板一样供用户挑选,不用记。
  2. 可参数化——客户端根据 arguments 定义自动渲染表单,填空即用。
  3. 可规范化——system 角色约束、输出格式、few-shot 示例统一封装,团队输出质量对齐。

这就是 Prompts 的价值:它不是"更弱的工具",而是面向人类工作流的标准化入口。

flowchart LR
    User[用户] -->|点击提示词| Client[MCP 客户端]
    Client -->|prompts/list| Server[MCP 服务器]
    Server -->|返回名称+参数表| Client
    Client -->|渲染表单让用户填参| User
    User -->|提交参数| Client
    Client -->|prompts/get 带参数| Server
    Server -->|渲染好的 messages| Client
    Client -->|注入对话| Model[大模型]
    Model -->|高质量结构化回答| User

二、前置条件

开始前你需要:

不需要预先安装 mcp——下面会用 uv 一键拉起隔离环境。


三、第一步:搭起项目骨架

新建目录并用 uv 初始化:

mkdir prompt-library && cd prompt-library
uv init --python 3.12
uv add "mcp[cli]"

mcp[cli] 是官方 Python SDK,附带 mcp 命令行工具(用于 mcp dev / mcp run)。它内置的 FastMCP 是写 MCP 服务器最省事的方式。

创建 server.py:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("prompt-library")

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

预期结果:四行代码,一个能跑的 MCP 服务器骨架。FastMCP("prompt-library") 里的名字会作为服务器的 serverInfo 暴露给客户端。

常见问题: - mcp run 找不到命令?确认装的是 mcp[cli] 而非裸 mcp。 - 报 uvloop 相关错?Windows 下换 uv add asyncio 或忽略,stdio 传输不依赖它。


四、第二步:写第一个 Prompt——代码审查

在 server.py 的 mcp = FastMCP(...) 之后加:

@mcp.prompt()
def code_review(code: str) -> str:
    """审查代码,找出 bug 和改进建议。"""
    return (
        "请审查下面这段代码,按【Bug】【安全】【性能】【可读性】四类给出问题,"
        "每类若无问题就写'无'。最后给一段重构后的代码。\n\n"
        f"```\n{code}\n```"
    )

这就是一个完整的 Prompt。注意几个要点:

启动 Inspector 看效果:

mcp dev server.py

浏览器打开终端打印的本地地址(通常是 http://localhost:5173),左侧连接成功后点 Prompts 标签页,你会看到:

code_review   审查代码,找出 bug 和改进建议。

点进去,右侧渲染出一个参数表单:

code  [_____________]

填入 print("x"),点 Run Prompt,下方返回:

{
  "messages": [
    {
      "role": "user",
      "content": { "type": "text", "text": "请审查下面这段代码...```...```" }
    }
  ]
}

这就是 Prompts 的魔法:你没有写任何 UI 代码,客户端完全靠协议字段自动渲染了表单、自动拼好了消息。

常见问题: - 表单里参数框没出现?检查函数参数是否有类型注解——没有注解的参数 SDK 无法推断,会被忽略。 - Inspector 里看不到 Prompts 标签?说明连接失败或服务器崩了,看终端 stderr。


五、第三步:参数进阶——必填、可选、默认值

现实中的提示词往往有多个参数。加一个"生成提交信息"的提示,演示可选参数:

@mcp.prompt()
def commit_message(diff: str, scope: str = "", breaking: bool = False) -> str:
    """根据 git diff 生成 Conventional Commits 规范的提交信息。

    Args:
        diff: git diff 的输出文本
        scope: 影响范围,如 auth、api(可留空)
        breaking: 是否包含破坏性变更
    """
    flag = "(标注 BREAKING CHANGE)" if breaking else ""
    return (
        f"你是 Git 提交信息专家。根据下面的 diff 生成一条 Conventional Commits 规范的提交信息。"
        f"范围 scope={scope or '未指定'}{flag}。只输出三行:type、可选 scope、简短描述,"
        f"再附一段正文说明动机。\n\n"
        f"```diff\n{diff}\n```"
    )

预期结果:Inspector 里这个 prompt 的参数表单会变成:

diff       [___________]   (必填,文本域)
scope      [___________]   (选填,默认空)
breaking   [  ]            (选填,勾选框,默认 false)

带默认值的参数自动变成可选 argument(required: false),无默认值的参数是必填(required: true)。布尔类型在友好客户端里会渲染成勾选框。

为什么把 Args 写在 docstring 里:FastMCP 会解析 Google 风格 docstring,把每个参数的描述喂给客户端,帮用户理解每个框该填什么。这比裸参数名 breaking 友好得多。

常见问题: - 默认值是可变对象(如 items: list = [])?用 None 兜底后在函数体内处理,避免 Python 可变默认值陷阱。 - 复杂类型(dataclass、Pydantic model)作参数?SDK 也能处理,但为了"填表"友好,提示词参数尽量用 str/int/bool 这类标量。


六、第四步:多消息返回——注入 system 人设

单个字符串只能产出一条 user 消息。但真正的提示词工程常常需要 system 角色定调 + user 角色给数据。返回消息列表即可:

from mcp.server.fastmcp.prompts import base

@mcp.prompt()
def debug_error(error: str, language: str = "python") -> list[base.Message]:
    """把报错拆成 可能原因 / 排查步骤 / 修复建议 三段输出。"""
    return [
        base.UserMessage(
            "你是一名资深排障工程师,回答永远分三段:"
            "**可能原因**、**排查步骤**、**修复建议**。"
            "每段用项目符号,排查步骤要可执行。"
        ),
        base.AssistantMessage("明白,我会严格按三段格式输出,步骤可执行。"),
        base.UserMessage(f"这是 {language} 报错,帮我拆解:\n\n```\n{error}\n```"),
    ]

预期结果:prompts/get 返回三条消息——两轮 user、一轮 assistant。base.UserMessage / base.AssistantMessage 是官方 SDK 提供的便捷类,等价于 base.Message(role="user", content=...)。

这种"system 用 user 角色伪装 + assistant 预先确认"的 few-shot 写法,是因为标准 MCP Prompts 协议的 message.role 只规范了 user 和 assistant 两种,把人设约束塞进第一条 user 消息是跨客户端最稳的做法。预置的 assistant 回复起到了"格式锚定"作用,模型会模仿这个结构继续输出。

常见问题: - 返回的消息顺序很重要,最后一条通常是 user(这样模型有内容可响应)。 - 别忘了 from mcp.server.fastmcp.prompts import base,否则 UserMessage 找不到。


七、第五步:动态生成与资源嵌入

提示词不一定要返回静态拼接的字符串——它可以先跑代码、读文件、查数据库,再把结果嵌进消息。这是它比"存一个文本模板"强的地方。加一个读 Git 提交历史再生成 release notes 的提示:

import subprocess

@mcp.prompt()
def release_notes(since: str = "HEAD~5") -> str:
    """读取指定范围内的 git log,生成 release notes。"""
    try:
        log = subprocess.check_output(
            ["git", "log", "--pretty=%s", since],
            stderr=subprocess.DEVNULL,
            text=True,
        ).strip()
    except Exception:
        log = "(无法读取 git log,请确认在 git 仓库内运行)"

    return (
        "根据下面的提交记录,归类成【新功能】【修复】【重构】【其它】四组,"
        "生成中文 release notes,每组用项目符号,合并语义重复的条目。\n\n"
        f"{log}"
    )

预期结果:用户在客户端点 release_notes、填 since=HEAD~10、点运行——服务器当场执行 git log,把真实提交喂进提示词,返回一条已经上下文齐备的 user 消息。模型拿到后直接产出格式化 release notes。

这意味着 Prompts 是"带业务逻辑的提示词工厂":动态参数 → 服务器侧数据获取 → 渲染成规范消息,全程对模型透明、对用户零负担。

常见问题: - 提示词里跑外部命令要控制超时、处理异常,别让服务器卡死或崩溃导致客户端拿不到响应。 - 涉及敏感数据时,提示词函数里别把密钥直接拼进返回文本——会被注入上下文随对话一起发出去。


八、第六步:用客户端脚本验证(脱离 Inspector)

Inspector 适合交互式调试,但要写自动化测试或在 CI 里验证,需要一个客户端脚本。新建 test_client.py:

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


async def main():
    params = StdioServerParameters(command="python", args=["server.py"])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 1. 列出所有提示词
            listing = await session.list_prompts()
            print("=== 提示词清单 ===")
            for p in listing.prompts:
                args = [a.name for a in p.arguments] if p.arguments else []
                print(f"  {p.name}({', '.join(args)}) — {p.description}")

            # 2. 调用一个提示词,填参数
            result = await session.get_prompt(
                "commit_message",
                {"diff": "+def foo(): pass", "scope": "api", "breaking": "false"},
            )
            print("\n=== commit_message 渲染结果 ===")
            for msg in result.messages:
                print(f"[{msg.role}] {msg.content.text[:120]}...")


if __name__ == "__main__":
    asyncio.run(main())

运行:

uv run python test_client.py

预期结果:

=== 提示词清单 ===
  code_review(code) — 审查代码,找出 bug 和改进建议。
  commit_message(diff, scope, breaking) — 根据 git diff 生成...
  debug_error(error, language) — 把报错拆成 可能原因 / 排查步骤 / 修复建议 三段输出。
  release_notes(since) — 读取指定范围内的 git log,生成 release notes。

=== commit_message 渲染结果 ===
[user] 你是 Git 提交信息专家。根据下面的 diff 生成...

这就是协议层的全貌:客户端先 prompts/list 拿清单,再 prompts/get 带参数拿渲染好的 messages。

常见问题: - get_prompt 的参数值一律传字符串(即使原参数是 bool),由服务器侧反序列化。 - 客户端脚本和服务器要在同一工作目录,否则 release_notes 这种读 git 的提示会失败。


九、实战案例:完整研发提示词库 MCP

把前面所有片段整合成一个完整可运行的项目。再加两个提示词,凑齐团队研发日常五件套。最终 server.py:

"""研发提示词库 MCP 服务器。"""
import subprocess

from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.prompts import base

mcp = FastMCP("prompt-library")


# 1. 代码审查(单参数、字符串返回)
@mcp.prompt()
def code_review(code: str) -> str:
    """审查代码,按【Bug】【安全】【性能】【可读性】四类给问题与重构。"""
    return (
        "请审查下面这段代码,按【Bug】【安全】【性能】【可读性】四类给出问题,"
        "每类若无问题就写'无'。最后给一段重构后的代码。\n\n"
        f"```\n{code}\n```"
    )


# 2. 提交信息(必填+可选+布尔)
@mcp.prompt()
def commit_message(diff: str, scope: str = "", breaking: bool = False) -> str:
    """根据 git diff 生成 Conventional Commits 提交信息。"""
    flag = "(标注 BREAKING CHANGE)" if breaking else ""
    return (
        f"你是 Git 提交信息专家。根据下面的 diff 生成一条 Conventional Commits 规范提交信息。"
        f"scope={scope or '未指定'}{flag}。只输出三行 type、可选 scope、简短描述,再附正文。\n\n"
        f"```diff\n{diff}\n```"
    )


# 3. 报错排障(多消息、few-shot 锚定)
@mcp.prompt()
def debug_error(error: str, language: str = "python") -> list[base.Message]:
    """把报错拆成 可能原因 / 排查步骤 / 修复建议 三段。"""
    return [
        base.UserMessage(
            "你是资深排障工程师,回答分三段:**可能原因**、**排查步骤**、**修复建议**。"
        ),
        base.AssistantMessage("明白,严格按三段、步骤可执行。"),
        base.UserMessage(f"这是 {language} 报错,帮我拆解:\n\n```\n{error}\n```"),
    ]


# 4. 重构提取(可选默认值 + 引导输出 diff)
@mcp.prompt()
def refactor_extract(code: str, target: str = "函数") -> str:
    """把代码中可复用片段提取成独立单元,输出 before/after diff。"""
    return (
        f"请重构下面代码:把可复用逻辑提取成独立 {target},命名清晰、单一职责。"
        "输出格式:先解释抽取了什么、再给 before/after 代码块。\n\n"
        f"```\n{code}\n```"
    )


# 5. Release Notes(动态读取 git log)
@mcp.prompt()
def release_notes(since: str = "HEAD~5") -> str:
    """读取指定范围 git log,生成归类后的中文 release notes。"""
    try:
        log = subprocess.check_output(
            ["git", "log", "--pretty=%s", since],
            stderr=subprocess.DEVNULL,
            text=True,
        ).strip()
    except Exception:
        log = "(无法读取 git log,请确认在 git 仓库内运行)"
    return (
        "根据下面提交记录,归类成【新功能】【修复】【重构】【其它】,"
        "生成中文 release notes,合并语义重复条目。\n\n"
        f"{log}"
    )


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

目录结构:

prompt-library/
├── server.py          # 服务器,含 5 个提示词
├── test_client.py     # 客户端验证脚本
├── pyproject.toml     # uv 自动生成
└── .python-version

一键运行验证:

uv run python test_client.py   # 列清单 + 调用 commit_message
mcp dev server.py              # 交互式调试任意提示词

十、接入 Claude Desktop 与 Claude Code

服务器造好了,怎么在日常工具里用上?

Claude Desktop(Prompts 的最佳展示场)——编辑配置文件 claude_desktop_config.json(macOS 在 ~/Library/Application Support/Claude/):

{
  "mcpServers": {
    "prompt-library": {
      "command": "uv",
      "args": ["--directory", "/绝对路径/prompt-library", "run", "python", "server.py"]
    }
  }
}

重启 Claude Desktop 后,提示词会出现在输入框旁的 📎(附件/斜杠)菜单 里,点开看到 code_review、commit_message 等,填参数即注入对话。

Claude Code——用 CLI 注册服务器:

claude mcp add prompt-library -- uv --directory /绝对路径/prompt-library run python server.py

注册后用 claude mcp list 确认在线。在 Claude Code 会话里通过 /mcp 查看状态。提示词原语会被客户端加载,可在支持 prompts 入口的 MCP 客户端中调用;若想稳定地在自动化流程里用,推荐用前面的 test_client.py 脚本直接 prompts/get 渲染好消息再喂给模型。

flowchart TB
    subgraph 服务端["server.py(FastMCP)"]
        P1[code_review]
        P2[commit_message]
        P3[debug_error]
        P4[refactor_extract]
        P5[release_notes]
    end
    subgraph 客户端["MCP 客户端"]
        CD[Claude Desktop<br/>📎 菜单]
        CC[Claude Code<br/>claude mcp add]
        IN[Inspector<br/>mcp dev]
        SC[脚本客户端<br/>test_client.py]
    end
    CD -->|prompts/list + get| 服务端
    CC -->|prompts/list + get| 服务端
    IN -->|prompts/list + get| 服务端
    SC -->|prompts/list + get| 服务端
    服务端 -->|渲染 messages| 客户端

十一、上线前自检清单

把提示词库 MCP 推给团队前,逐条核对:

  1. 每个函数都有 docstring——它就是用户在菜单里看到的说明,没有就只剩一个干巴巴的函数名。
  2. 参数都有类型注解——code: str 而非裸 code,否则客户端不渲染输入框。
  3. 必填/可选设计合理——能给默认值的就给,降低用户填写负担。
  4. 动态逻辑有兜底——release_notes 读 git 失败要返回友好提示,不能抛异常让客户端拿空响应。
  5. 不泄露敏感信息——提示词返回的文本会随对话发给模型,别拼 token、密钥。
  6. 命名用 snake_case——code_review 而非 codeReview,符合 MCP 惯例,跨客户端兼容。

延伸阅读


训练营适用性评估

适合的训练营类型:

不适合:纯零基础、连 MCP Tool 都没写过的学员应先补 Tool 教程;本教程默认你理解 stdio 传输与 MCP 客户端概念。

难度:⭐⭐⭐(中等偏低),门槛在概念转变(从"工具思维"到"提示词入口思维"),代码量极小。

前置依赖:建议先有任意一篇 Tool/Resource 教程打底。


参考来源

  1. Prompts - Model Context Protocol 官方规范 — MCP Prompts 原语的协议层权威定义(prompts/list、prompts/get、message role 规范)。
  2. Prompts - FastMCP 文档 — @mcp.prompt 装饰器用法、参数序列化、多消息与资源嵌入示例。
  3. Define Prompts in MCP Server | RapidDev 教程 — 用 registerPrompt(TS) / @mcp.prompt(Py) 注册提示词模板的分步教程。
  4. GitHub - sparesparrow/mcp-prompts — 开源的提示词管理与存储 MCP 服务器,可参考其模板设计思路。
  5. MCP Server step-by-step guide (2026) | Composio — 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学通信知识星球海报-扫码加入