背景介绍:
- 这是一个四部分教程的第三部分,讲的是如何在 MCP(Model Context Protocol)服务器中添加 Prompt(提示词)功能。
- 前两部分已经完成了基本的服务器搭建、资源(resources)和资源模板(resource templates)的管理。
- 本部分重点是:引入 Prompt,优化代码组织。
什么是 MCP Prompts?
- Prompt 是一种标准化的结构化模板,用来统一 LLM(大模型)交互的方式。
- 与 resource(提供数据)或 tool(执行动作)不同,prompt 是可重复使用的消息序列模板,可以带参数定制。
- 类比餐厅菜单:Prompt 就像菜单上的菜品,你可以点菜并定制做法。
为什么要使用 Prompts?
-
标准化 和可重复使用:提高与大模型交互的一致性和效率。
-
例子:
代码审查 Prompts
-
名称 :
code-review
-
模板内容:
cssPlease review the following {{language}} code focusing on {{focusAreas}} for the following block of code: ```{{language}} {{codeBlock}}
-
示例使用:
用户输入:
lessPlease review the following Python code focusing on security and performance: ```Python ... code
数据分析 Prompts
-
名称 :
analyze-sales-data
-
模板内容:
csharpAnalyze {{timeframe}} sales data focusing on {{metrics}}
-
示例使用:
用户输入:
csharpAnalyze Q1 sales data focusing on revenue and growth
内容生成 Prompts
-
名称 :
generate-email
-
模板内容:
arduinoGenerate a {{tone}} {{type}} email for {{context}}
-
示例使用:
用户输入:
cssGenerate a formal support email for a refund request to Bob's Barbecue LLC.
明白了!你的要求是:
- 整体内容翻译成中文 ✅
- 代码部分、Prompt内容、示例内容原样保留英文,不要翻译 ✅
- 保持清晰、有条理的结构 ✅
下面是根据你的要求整理和翻译后的版本:
Code Organization
在 Part 2 中,我们已经把 index.ts
中的 handler 逻辑抽离到了 handlers.ts
文件中。
但是随着功能增加,handlers.ts
会变得过大,因此需要进一步模块化:
src/resources.ts
arduino
export const resources = [
{
uri: "hello://world",
name: "Hello World Message",
description: "A simple greeting message",
mimeType: "text/plain",
},
];
export const resourceHandlers = {
"hello://world": () => ({
contents: [
{
uri: "hello://world",
text: "Hello, World! This is my first MCP resource.",
},
],
}),
};
src/resource-templates.ts
ini
export const resourceTemplates = [
{
uriTemplate: "greetings://{name}",
name: "Personal Greeting",
description: "A personalized greeting message",
mimeType: "text/plain",
},
];
const greetingExp = /^greetings://(.+)$/;
const greetingMatchHandler =
(uri: string, matchText: RegExpMatchArray) => () => {
const name = decodeURIComponent(matchText[1]);
return {
contents: [
{
uri,
text: `Hello, ${name}! Welcome to MCP.`,
},
],
};
};
export const getResourceTemplate = (uri: string) => {
const greetingMatch = uri.match(greetingExp);
if (greetingMatch) return greetingMatchHandler(uri, greetingMatch);
};
更新 handlers 文件:src/handlers.ts
typescript
import {
ListResourcesRequestSchema,
ListResourceTemplatesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { type Server } from "@modelcontextprotocol/sdk/server/index.js";
import { resourceHandlers, resources } from "./resources.js";
import {
getResourceTemplate,
resourceTemplates,
} from "./resource-templates.js";
export const setupHandlers = (server: Server): void => {
// 列出所有可用资源
server.setRequestHandler(
ListResourcesRequestSchema,
() => ({ resources }),
);
// 列出所有资源模板
server.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({
resourceTemplates,
}));
// 返回特定资源内容
server.setRequestHandler(ReadResourceRequestSchema, (request) => {
const { uri } = request.params ?? {};
const resourceHandler =
resourceHandlers[uri as keyof typeof resourceHandlers];
if (resourceHandler) return resourceHandler();
const resourceTemplateHandler = getResourceTemplate(uri);
if (resourceTemplateHandler) return resourceTemplateHandler();
throw new Error("Resource not found");
});
};
添加 Prompts(Adding Prompts)
新增一个管理 prompts 的模块:
src/prompts.ts
typescript
export const prompts = {
"create-greeting": {
name: "create-greeting",
description: "Generate a customized greeting message",
arguments: [
{
name: "name",
description: "Name of the person to greet",
required: true,
},
{
name: "style",
description: "The style of greeting, such a formal, excited, or casual. If not specified casual will be used"
}
],
},
};
export const promptHandlers = {
"create-greeting": ({ name, style = "casual" }: { name: string, style?: string }) => {
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Please generate a greeting in ${style} style to ${name}.`,
},
},
],
};
},
};
更新 handlers 文件,支持 prompts
继续修改 src/handlers.ts
,引入 prompts 相关逻辑:
typescript
import {
GetPromptRequestSchema,
ListPromptsRequestSchema,
// ... 其他导入
} from "@modelcontextprotocol/sdk/types.js";
// ... 其他导入
import { promptHandlers, prompts } from "./prompts.js";
export const setupHandlers = (server: Server): void => {
// ... 其他 resource handler
// Prompts
server.setRequestHandler(ListPromptsRequestSchema, () => ({
prompts: Object.values(prompts),
}));
server.setRequestHandler(GetPromptRequestSchema, (request) => {
const { name, arguments: args } = request.params;
const promptHandler = promptHandlers[name as keyof typeof promptHandlers];
if (promptHandler) return promptHandler(args as { name: string, style?: string });
throw new Error("Prompt not found");
});
};
更新服务器初始化:src/index.ts
javascript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { setupHandlers } from "./handlers.js";
const server = new Server(
{
name: "hello-mcp",
version: "1.0.0",
},
{
capabilities: {
prompts: {}, // <-- 新增 prompts
resources: {},
},
},
);
setupHandlers(server);
// 其他代码...
理解代码结构(Understanding the Code)
模块组织(Module Organization)
- 资源(resources)、资源模板(templates)、prompts 分模块存放。
handlers.ts
只负责路由分发,保持简洁。
Prompt 结构(Prompt Structure)
- 每个 prompt 包含:名字(name)、描述(description)、参数(arguments)。
- 参数描述了 prompt 所需输入。
消息序列(Message Sequences)
- prompt 生成消息数组(messages)。
- 消息有角色(role:
user
或assistant
)。 - 内容可以是单步请求或多步流程(多步流程目前支持有限)。
测试方法(Testing)
使用 MCP Inspector 测试:
-
启动:
bashnpx @modelcontextprotocol/inspector node build/index.js
-
测试 Prompts:
-
点击 Prompts 标签页
-
找到
create-greeting
-
尝试不同参数:
json{ "name": "Alice", "style": "excited" }
-
返回示例:
json{ "messages": [ { "role": "user", "content": { "type": "text", "text": "Please generate a greeting in excited style to Alice." } } ] }
-
使用 Claude Desktop 测试:
-
打开 Claude Desktop
-
点击聊天输入框右下角的插件图标(Attach from MCP)
-
弹出框里选择 "create-greeting"
-
填写
name
(如 John),提交 -
会生成一个附加的 prompt:"Please generate a casual greeting to John."
-
提交后,Claude 回复类似:
sqlHi John! How are you doing today?
进阶:更改风格
-
重新选择 "create-greeting" prompt
-
填写:
makefilename: Alice style: formal
-
Claude 返回:
cssDear Alice, I hope this message finds you well. I am writing to extend my warmest greetings. Best regards, Claude
下一步(What's Next)
在 Part 4 中,将:
- 了解 MCP 中的 Tools(工具)及其与 Prompts 的区别
- 给服务器添加 Tool 支持
- 让服务器可以提供更动态的功能
- 完成包含全部核心功能的 MCP 服务器
参考资料(Sources)
- Model Context Protocol - Prompts 概念文档
- unichat-mcp-server 示例项目
- Anthropic 官方 Prompt 工程文档
- 10条 Prompt 工程最佳实践
- Prompt Engineering 指南