這是我們構建 MCP 服務器的四部分教程的第三部分。在第一部分中,我們使用基本資源創建了第一個MCP 服務器;在第二部分中,我們添加了資源模板并改進了代碼組織。現在,我們將進一步重構代碼并添加提示功能。
什么是 MCP 提示?
MCP 中的提示符是服務器提供的結構化模板,用于標準化與語言模型的交互。與提供數據的資源或執行操作的工具不同,提示符定義了可重用的消息序列和工作流,有助于以一致、可預測的方式指導 LLM 行為。它們可以接受參數來自定義交互,同時保持標準化的結構。如果您曾經研究過提示符工程,那么您可能對提示符的概念已經有了相當的了解。在 MCP 服務器中創建這些提示符,使我們能夠為我們認為最有用的提示符創建一個空間,使其易于重用甚至共享。想象一下去餐廳,提示符就像一個菜單項,您可以從中挑選并提供給服務員。有時,您可以通過要求添加或刪除某些菜品或以特定方式烹飪來自定義菜單項。以這種方式提供的提示符具有類似的功能。
為什么要使用提示?
提示有助于為 LLM 交互創建一致、可重復使用的模式。以下是一些實際示例:
代碼審查提示
"name" -> code-review
Please review the following {{language}} code focusing on {{focusAreas}} for the following block of code:
```{{language}}
{{codeBlock}}
```
用戶:請檢查以下關注安全性和性能的 Python 代碼:
“Python
...代碼
”
數據分析提示
"name" -> analyze-sales-data
Analyze {{timeframe}} sales data focusing on {{metrics}}User: Analyze Q1 sales data focusing on revenue and growth
內容生成提示
"name" -> generate-email
Generate a {{tone}} {{type}} email for {{context}}
用戶:生成一封正式的支持電子郵件,以向 Bob's Barbecue LLC 提出退款請求。
代碼組織
在第二部分中,我們從 index.ts 中抽象出了處理程序代碼,并將其放入 handlers.ts 文件中。這個文件可能會變得過大。我們應該將處理程序代碼組織到各個模塊中:
// src/resources.ts
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
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);
};
更新我們的處理程序:
// src/handlers.ts
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 => {// List available resources when clients request themserver.setRequestHandler(ListResourcesRequestSchema,() => ({ resources }),);// Resource Templatesserver.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({resourceTemplates,}));// Return resource content when clients request itserver.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");});
};
添加提示
現在添加我們的新提示功能:
// src/prompts.ts
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}.`,},},],};},
};
將我們的新提示處理程序添加到處理程序文件中:
// src/handlers.ts
import {GetPromptRequestSchema,ListPromptsRequestSchema,// ... other imports
} from "@modelcontextprotocol/sdk/types.js";
// ... other imports
import { promptHandlers, prompts } from "./prompts.js";export const setupHandlers = (server: Server): void => {// ... Other resource handlers here// Promptsserver.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
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: {}, // <-- Add promptsresources: {},},},
);setupHandlers(server);// ... remaining code
理解代碼
模塊組織
- 資源和模板已放置在各自的模塊中
- 提示清晰地分開
- 處理程序現在充當路由層
提示結構
- 每個提示都有名稱、描述和參數(如果需要)
- 參數描述提示的預期輸入
- 處理程序生成結構化消息以提示目標 AI
消息序列
- 提示返回消息數組
- 消息具有角色(“用戶”或“助手”)
- 內容可以包括多步驟工作流的初始請求和后續響應(請注意,目前多步驟工作流的支持有限)
使用檢查器進行測試
啟動檢查器:
npx @modelcontextprotocol/inspector node build/index.js
測試提示:
- 點擊“提示”選項卡
- 找到“create-greeting”
- 嘗試不同的參數組合:
名字:“愛麗絲”,風格:“興奮”
{"messages": [{"role": "user","content": {"type": "text","text": "Please generate a greeting in excited style to Alice."}}]
}
使用 Claude Desktop 進行測試
嘗試以下示例:
基本提示:
1:打開Claude桌面
假設:
- 您已經構建了服務器(
npx tsc
)并設置了 Claude Desktop來使用它。
2:與我們添加資源的方式類似,點擊“從 MCP 附加”
3:在模態彈出窗口中,點擊“選擇并集成”,然后從“hello-mcp”下的列表中選擇“create-greeting”提示
4:現在,只需輸入姓名即可進行測試。在姓名字段中輸入類似“John”的內容,然后點擊“提交”。
5:您將看到一個“create-greeting”附件。點擊它查看其中的內容。
6:您將看到這里有一個給克勞德的提示,上面寫著“請向約翰致以隨意的問候”。
7:無需輸入任何其他提示,只需單擊聊天框右上角的提交箭頭即可
8:您將看到類似“嗨,約翰!你今天過得怎么樣?”的回復。
樣式提示:
1:現在,嘗試使用不同的特定樣式創建問候語。打開“從 MCP 附加”對話框,然后再次選擇“創建問候語”提示。這次,我們可以添加名稱“Alice”和樣式“正式”,然后提交聊天。再次使用箭頭鍵,或者直接按 Enter 鍵也可以,我還沒試過。
2:這一次,您可能會看到返回如下消息:
親愛的愛麗絲,
祝您一切安好。謹致以最誠摯的問候。
謹致問候,
克勞德
下一步是什么?
在第 4 部分中,我們將:
- 了解MCP 工具及其與提示的區別
- 為我們的服務器添加工具功能
- 了解工具如何提供動態功能
- 使用所有主要的 MCP 功能完成我們的問候服務器
資料來源及其他閱讀材料:
- Prompts - Model Context Protocol
- GitHub - amidabuddha/unichat-mcp-server
- Prompt engineering overview - Anthropic
- 10 Prompt Engineering Best Practices - DEV Community
- https://promptingguide.ai