跳到主要内容

MCP 提示模板

提示(Prompts)是 MCP 提供的一种服务器端模板机制,允许服务器定义可重用的提示模板,帮助用户快速启动特定的工作流程。提示模板可以包含参数,使其能够适应不同的使用场景。

什么是提示模板?

提示模板是服务器预定义的提示内容,可以:

  • 标准化常见工作流程
  • 提供结构化的任务模板
  • 引导 LLM 按照特定方式处理问题
  • 减少用户重复输入相似内容

与普通提示的区别

特性普通提示提示模板
来源用户输入服务器定义
可复用性
参数化支持
一致性依赖用户标准化

提示结构

每个提示模板包含以下字段:

from mcp.types import Prompt, PromptArgument

Prompt(
name="code_review", # 唯一标识符(必需)
description="代码审查助手", # 功能描述(必需)
arguments=[ # 参数列表(可选)
PromptArgument(
name="language",
description="编程语言",
required=False,
default="python"
)
]
)

字段说明

字段类型必需说明
namestring提示模板的唯一标识符
descriptionstring功能描述,帮助用户理解用途
argumentsarray参数定义列表

参数定义

PromptArgument(
name="file_path", # 参数名称
description="要审查的文件路径", # 参数描述
required=True, # 是否必需
default=None # 默认值(仅对非必需参数)
)

协议消息

列出提示模板

客户端通过 prompts/list 获取可用的提示模板:

{
"jsonrpc": "2.0",
"id": "prompts-1",
"method": "prompts/list"
}

服务器响应:

{
"jsonrpc": "2.0",
"id": "prompts-1",
"result": {
"prompts": [
{
"name": "code_review",
"description": "代码审查助手",
"arguments": [
{
"name": "language",
"description": "编程语言",
"required": false
}
]
}
]
}
}

获取提示内容

客户端通过 prompts/get 获取具体的提示内容:

{
"jsonrpc": "2.0",
"id": "get-1",
"method": "prompts/get",
"params": {
"name": "code_review",
"arguments": {
"language": "python"
}
}
}

服务器响应:

{
"jsonrpc": "2.0",
"id": "get-1",
"result": {
"description": "代码审查助手",
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "请对以下代码进行全面审查..."
}
}
]
}
}

提示列表变更通知

当提示模板列表发生变化时,服务器发送通知:

{
"jsonrpc": "2.0",
"method": "notifications/prompts/list_changed"
}

Python 实现

使用底层 Server 类

from mcp.server import Server
from mcp.types import Prompt, PromptArgument, TextContent

app = Server("prompt-server")

@app.list_prompts()
async def list_prompts() -> list[Prompt]:
"""返回可用的提示模板列表"""
return [
Prompt(
name="code_review",
description="对代码进行全面的安全、性能和风格审查",
arguments=[
PromptArgument(
name="language",
description="编程语言,如 python、javascript、java",
required=False,
default="python"
),
PromptArgument(
name="focus",
description="审查重点:security、performance、readability、bugs",
required=False,
default="all"
),
PromptArgument(
name="file_path",
description="要审查的文件路径",
required=True
)
]
),
Prompt(
name="write_tests",
description="为代码生成单元测试",
arguments=[
PromptArgument(
name="framework",
description="测试框架,如 pytest、jest、junit",
required=True
),
PromptArgument(
name="coverage_target",
description="目标覆盖率百分比",
required=False,
default="80"
)
]
),
Prompt(
name="explain_error",
description="解释错误信息并提供修复建议",
arguments=[
PromptArgument(
name="error_message",
description="完整的错误信息",
required=True
)
]
)
]

@app.get_prompt()
async def get_prompt(
name: str,
arguments: dict | None
) -> list[TextContent]:
"""返回提示模板的具体内容"""
if arguments is None:
arguments = {}

if name == "code_review":
lang = arguments.get("language", "python")
focus = arguments.get("focus", "all")
file_path = arguments.get("file_path", "")

prompt_text = f"""请对以下 {lang} 代码进行全面审查。

审查文件:{file_path}
重点关注:{focus}

请按以下结构提供审查报告:

## 1. 总体评估
- 代码质量总体评分(1-10)
- 主要优点
- 主要问题

## 2. 详细分析

### 安全性
- 潜在安全风险
- 敏感数据处理
- 输入验证

### 性能
- 性能瓶颈
- 优化建议
- 资源使用

### 可读性
- 代码结构
- 命名规范
- 注释质量

### 潜在缺陷
- 边界条件
- 异常处理
- 并发问题

## 3. 修复建议
请提供具体的代码修改建议,包括修改前后的对比。
"""
return [TextContent(type="text", text=prompt_text)]

elif name == "write_tests":
framework = arguments.get("framework", "pytest")
coverage = arguments.get("coverage_target", "80")

prompt_text = f"""请为以下代码编写 {framework} 单元测试。

目标测试覆盖率:{coverage}%

测试编写要求:

1. **测试结构**
- 每个测试函数专注单一功能
- 使用清晰的测试命名
- 遵循 AAA 模式(Arrange-Act-Assert)

2. **测试覆盖**
- 正常情况测试
- 边界条件测试
- 异常情况测试
- 输入验证测试

3. **最佳实践**
- 使用 fixture 复用测试数据
- 使用 mock 隔离外部依赖
- 参数化测试覆盖多组数据

请提供完整的测试代码,包括必要的导入和 fixture 定义。
"""
return [TextContent(type="text", text=prompt_text)]

elif name == "explain_error":
error_msg = arguments.get("error_message", "")

prompt_text = f"""请分析以下错误信息,提供详细的解释和修复建议。

错误信息:
{error_msg}

请提供:

1. **错误类型识别**
- 这是什么类型的错误?
- 错误发生在哪个层级(编译/运行时/逻辑)?

2. **根本原因分析**
- 错误的根本原因是什么?
- 可能的触发条件有哪些?

3. **修复方案**
- 提供具体的修复代码
- 解释修复的原理
- 是否有其他替代方案?

4. **预防措施**
- 如何避免类似错误?
- 有哪些最佳实践可以遵循?
"""
return [TextContent(type="text", text=prompt_text)]

raise ValueError(f"Unknown prompt: {name}")

使用 FastMCP

FastMCP 提供了更简洁的提示定义方式:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("prompt-server")

@mcp.prompt()
def code_review(
language: str = "python",
focus: str = "all",
file_path: str = ""
) -> str:
"""代码审查助手

对代码进行全面的安全、性能和风格审查。

Args:
language: 编程语言,如 python、javascript、java
focus: 审查重点:security、performance、readability、bugs
file_path: 要审查的文件路径
"""
return f"""请对 {file_path} 中的 {language} 代码进行审查。
重点关注:{focus}

请提供:
1. 安全性分析
2. 性能评估
3. 代码质量评分
4. 具体改进建议
"""

@mcp.prompt()
def write_tests(framework: str, coverage_target: int = 80) -> str:
"""生成单元测试

为代码生成完整的单元测试套件。

Args:
framework: 测试框架(pytest、jest、junit)
coverage_target: 目标覆盖率百分比
"""
return f"""请使用 {framework} 编写单元测试,目标覆盖率 {coverage_target}%。"""

@mcp.prompt()
def explain_error(error_message: str) -> str:
"""解释错误信息

分析错误并提供修复建议。

Args:
error_message: 完整的错误信息
"""
return f"""请分析以下错误并提供修复方案:\n{error_message}"""

多消息提示

提示可以返回多条消息,构建完整的对话上下文:

from mcp.types import TextContent, ImageContent

@app.get_prompt()
async def get_prompt(name: str, arguments: dict | None):
if name == "analyze_screenshot":
screenshot_path = arguments.get("screenshot_path")

# 读取图像并编码
image_data = read_and_encode_image(screenshot_path)

# 返回多条消息
return [
TextContent(
type="text",
text="请分析以下截图,识别 UI 元素并提供改进建议。"
),
ImageContent(
type="image",
data=image_data,
mimeType="image/png"
),
TextContent(
type="text",
text="""
请提供以下分析:

1. **UI 元素识别**
- 列出所有可见的 UI 组件
- 标注组件类型和位置

2. **设计评估**
- 布局合理性
- 颜色搭配
- 字体可读性

3. **可访问性检查**
- 对比度是否足够
- 是否支持屏幕阅读器

4. **改进建议**
- 具体的优化方案
"""
)
]

动态提示生成

提示内容可以根据运行时状态动态生成:

# 存储项目状态
project_state = {
"language": None,
"framework": None,
"test_coverage": None
}

@app.get_prompt()
async def get_prompt(name: str, arguments: dict | None):
if name == "project_summary":
# 根据项目状态生成提示
lang = project_state.get("language", "未知")
framework = project_state.get("framework", "未知")
coverage = project_state.get("test_coverage", "未知")

prompt = f"""请为当前项目生成一份总结报告。

项目信息:
- 编程语言:{lang}
- 框架:{framework}
- 当前测试覆盖率:{coverage}

请包含:
1. 项目结构概述
2. 主要功能模块
3. 技术债务清单
4. 改进优先级建议
"""
return [TextContent(type="text", text=prompt)]

条件提示

根据条件返回不同的提示内容:

@app.get_prompt()
async def get_prompt(name: str, arguments: dict | None):
if name == "debug":
error_type = arguments.get("error_type", "general")

# 根据错误类型选择不同的提示模板
templates = {
"memory": """内存问题调试指南:

1. 检查内存泄漏
- 使用 memory_profiler 分析
- 查找未关闭的资源

2. 优化内存使用
- 减少大对象创建
- 使用生成器替代列表

3. 监控建议
- 设置内存限制
- 添加内存使用日志
""",
"performance": """性能问题调试指南:

1. 性能分析
- 使用 cProfile 定位瓶颈
- 分析函数调用频率

2. 优化策略
- 缓存计算结果
- 使用更高效的数据结构

3. 监控建议
- 添加性能指标
- 设置性能告警
""",
"general": """通用调试指南:

1. 问题复现
- 记录复现步骤
- 收集相关日志

2. 问题定位
- 二分法排查
- 添加调试日志

3. 解决验证
- 验证修复效果
- 添加回归测试
"""
}

prompt = templates.get(error_type, templates["general"])
return [TextContent(type="text", text=prompt)]

提示使用流程

提示与工具的区别

理解提示和工具的区别对于正确设计 MCP 服务器至关重要:

特性提示 (Prompts)工具 (Tools)
方向服务器 → 客户端 → LLMLLM → 客户端 → 服务器
用途提供模板,引导思考执行具体操作
主动性被动(用户选择)主动(LLM 决定)
返回内容文本模板执行结果
副作用可能有

选择指南

  • 如果要引导 LLM 按特定方式思考 → 使用提示
  • 如果要执行实际操作或获取数据 → 使用工具
  • 如果要提供可选的工作流程模板 → 使用提示

最佳实践

1. 清晰的描述

每个提示都要有清晰的描述,帮助用户理解其用途:

# ❌ 差:描述不清
Prompt(name="review", description="审查代码")

# ✅ 好:描述详细
Prompt(
name="code_review",
description="""
对代码进行全面的审查,包括:
- 安全漏洞检测
- 性能瓶颈分析
- 代码风格检查
- 最佳实践建议
"""
)

2. 合理的参数设计

只暴露必要的参数,避免过度复杂:

# ❌ 差:参数过多
Prompt(
name="review",
arguments=[
PromptArgument(name="lang"),
PromptArgument(name="style"),
PromptArgument(name="max_lines"),
PromptArgument(name="output_format"),
PromptArgument(name="severity_threshold"),
# ... 太多参数
]
)

# ✅ 好:参数精简
Prompt(
name="review",
arguments=[
PromptArgument(name="language", required=False, default="auto"),
PromptArgument(name="focus", required=False, default="all")
]
)

3. 提供默认值

为可选参数设置合理的默认值:

PromptArgument(
name="coverage_target",
description="目标覆盖率",
required=False,
default="80" # 行业标准默认值
)

4. 结构化输出指导

在提示中引导 LLM 生成结构化的输出:

prompt = """请分析代码并提供报告,使用以下结构:

## 总体评估
[评分和概述]

## 发现的问题
| 问题类型 | 严重程度 | 位置 | 描述 |
|---------|---------|------|------|
| 安全 || L15 | ... |

## 修复建议
```python
# 修复代码

"""


### 5. 模板保持简洁

提示模板不应过长,保持聚焦:

```python
# ✅ 好:简洁聚焦
prompt = """请审查以下代码的安全性:

{code}

请列出发现的安全问题及其修复建议。
"""

# ❌ 差:过于冗长
prompt = """请审查以下代码,首先检查安全性,然后检查性能,
然后检查可读性,然后检查...(继续冗长内容)
"""

典型应用场景

1. 代码审查工作流

@mcp.prompt()
def review_pr(pr_number: int, focus: str = "all") -> str:
"""审查 Pull Request

Args:
pr_number: PR 编号
focus: 审查重点
"""
return f"""请审查 PR #{pr_number},重点关注 {focus}

审查清单:
- [ ] 代码逻辑正确性
- [ ] 测试覆盖率
- [ ] 文档完整性
- [ ] 向后兼容性
"""

2. 问题诊断模板

@mcp.prompt()
def diagnose_issue(
symptoms: str,
environment: str = "production"
) -> str:
"""诊断问题

Args:
symptoms: 问题症状描述
environment: 环境类型
"""
return f"""问题诊断报告

环境:{environment}
症状:{symptoms}

请按以下步骤诊断:
1. 可能原因分析(按可能性排序)
2. 验证步骤
3. 解决方案
"""

3. 文档生成模板

@mcp.prompt()
def generate_docs(
module_name: str,
doc_style: str = "google"
) -> str:
"""生成模块文档

Args:
module_name: 模块名称
doc_style: 文档风格(google、numpy、sphinx)
"""
return f"""请为 {module_name} 生成 {doc_style} 风格的文档。

包含:
- 模块概述
- 类和函数说明
- 使用示例
- 注意事项
"""

下一步