<!-- title: 造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 是面向"人"的入口**。它对应那些你每天都要重复打、每次只改几个变量的高频提示。比如：

- "帮我审查这段代码有没有 bug 和改进点：`<贴代码>`"
- "根据这个 diff 生成符合 Conventional Commits 规范的提交信息：`<贴 diff>`"
- "帮我把这个报错拆成 可能原因 / 排查步骤 / 修复建议 三段：`<贴报错>`"

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

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

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

```mermaid
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
```

---

## 二、前置条件

开始前你需要：

- **Python 3.10+**（建议 3.11/3.12）
- **uv**（推荐的 Python 包管理与运行工具）。没有就装：
  ```bash
  curl -LsSf https://astral.sh/uv/install.sh | sh
  ```
- **Node.js 18+**（仅在使用 `mcp dev` 的 Inspector 网页调试时需要）
- 基础：会写 Python 函数、用过装饰器、知道 MCP 是什么（看过任一 Tool 教程即可）

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

---

## 三、第一步：搭起项目骨架

新建目录并用 `uv` 初始化：

```bash
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`：

```python
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(...)` 之后加：

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

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

- **装饰器 `@mcp.prompt()`** 注册函数为提示词。函数名 `code_review` 成为提示词的 `name`。
- **docstring** 自动变成提示词的 `description`，客户端会展示给用户看。
- **参数 `code: str`** 自动成为提示词的必填 argument，类型注解会指导客户端渲染输入框。
- **返回字符串** 时，FastMCP 自动包装成一条 `role=user` 的消息。

启动 Inspector 看效果：

```bash
mcp dev server.py
```

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

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

点进去，右侧渲染出一个参数表单：

```
code  [_____________]
```

填入 `print("x")`，点 **Run Prompt**，下方返回：

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

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

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

---

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

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

```python
@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 角色给数据**。返回消息列表即可：

```python
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 的提示：

```python
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`：

```python
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())
```

运行：

```bash
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`：

```python
"""研发提示词库 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
```

一键运行验证：

```bash
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/`）：

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

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

**Claude Code**——用 CLI 注册服务器：

```bash
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` 渲染好消息再喂给模型。

```mermaid
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 官方规范 - Prompts**：`modelcontextprotocol.io/specification/2025-06-18/server/prompts`，协议层 `prompts/list` 与 `prompts/get` 的权威定义。
- **官方 Python SDK**：`github.com/modelcontextprotocol/python-sdk`，FastMCP 的源码与示例。
- **FastMCP 文档 - Prompts**：`fastmcp.wiki/en/servers/prompts`，`@mcp.prompt` 装饰器的进阶用法（嵌入资源、多模态消息）。
- **MCP C# SDK - Prompts 概念页**：`csharp.sdk.modelcontextprotocol.io/concepts/prompts`，跨语言对照理解。
- **Composio 2026 MCP 构建指南**：`composio.dev/content/mcp-server-step-by-step-guide-to-building-from-scratch`，从零构建的完整流程。

---

## 训练营适用性评估

**适合的训练营类型**：

- **MCP 进阶训练营（2-3 天）**：作为"补齐三原语"专题的下半场。上半场讲 Tools+Resources，本教程承接讲 Prompts，形成完整闭环。建议课时 **3 小时**（1 小时讲解 + 1.5 小时动手造 5 个提示词 + 0.5 小时接入客户端联调）。
- **研发效能训练营（1 天）**：把提示词库当作"团队 AI 工程化"的落地产物。学员造完即可在自己项目里用上，成果可带走。课时 **2-3 小时**。
- **企业 AI 标准化工作坊**：适合作为"提示词治理"议题的实践环节——把散落在各处的提示词收敛成一个版本化 MCP，统一质量基线。

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

**难度**：⭐⭐⭐（中等偏低），门槛在概念转变（从"工具思维"到"提示词入口思维"），代码量极小。

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

---

## 参考来源

1. [Prompts - Model Context Protocol 官方规范](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) — MCP Prompts 原语的协议层权威定义（prompts/list、prompts/get、message role 规范）。
2. [Prompts - FastMCP 文档](https://fastmcp.wiki/en/servers/prompts) — `@mcp.prompt` 装饰器用法、参数序列化、多消息与资源嵌入示例。
3. [Define Prompts in MCP Server | RapidDev 教程](https://www.rapidevelopers.com/mcp-tutorial/how-to-define-prompts-in-mcp-server) — 用 `registerPrompt`(TS) / `@mcp.prompt`(Py) 注册提示词模板的分步教程。
4. [GitHub - sparesparrow/mcp-prompts](https://github.com/sparesparrow/mcp-prompts) — 开源的提示词管理与存储 MCP 服务器，可参考其模板设计思路。
5. [MCP Server step-by-step guide (2026) | Composio](https://composio.dev/content/mcp-server-step-by-step-guide-to-building-from-scratch) — 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学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
