prompt-format-mcp
v1.1.1
Published
Simple prompt optimization MCP server with SiliconFlow API integration
Maintainers
Readme
🚀 MCP开发完整教程:从零构建AI提示词优化服务器
本教程将带你从零开始构建一个完整的MCP (Model Context Protocol) 服务器,实现AI提示词优化功能。通过详细的代码注释和原理解析,你将学会如何创建、发布和使用MCP服务器。
📖 目录
🎯 MCP概念介绍
什么是MCP?
Model Context Protocol (MCP) 是一个开放标准,用于连接AI助手与外部数据源和工具。它允许AI助手:
- 访问外部数据源
- 调用工具和函数
- 与各种服务集成
- 扩展AI能力
MCP的核心组件
- MCP服务器 - 提供工具和资源的服务端
- MCP客户端 - 使用工具和资源的客户端(如Cursor)
- 传输层 - 通信协议(stdio、HTTP等)
- 工具系统 - 可调用的函数接口
🏗️ 项目架构解析
prompt-format-mcp/
├── src/
│ ├── index.ts # 📍 入口文件 - 服务器启动和环境配置
│ ├── server.ts # 🔧 核心服务器 - MCP服务器实现和工具注册
│ ├── api/
│ │ └── siliconflow.ts # 🌐 API客户端 - 第三方AI服务集成
│ ├── types/
│ │ └── index.ts # 📝 类型定义 - TypeScript类型系统
│ └── utils/
│ └── helpers.ts # 🛠️ 工具函数 - 日志、重试等通用功能
├── package.json # 📦 依赖配置
├── tsconfig.json # ⚙️ TypeScript编译配置
└── README.md # 📖 本教程文档设计理念
- 模块化设计 - 每个文件职责单一,便于维护
- 类型安全 - 使用TypeScript确保代码质量
- 错误处理 - 完善的重试机制和错误处理
- 标准化 - 遵循MCP协议标准
📚 源码详解
下面我们逐个文件详细解析每行代码的作用和原理。
1. 入口文件 (src/index.ts)
#!/usr/bin/env node
// 📍 Shebang行:告诉操作系统使用node解释器执行此脚本
// 这使得该文件可以作为可执行文件直接运行
// 🔧 导入核心模块
import { PromptFormatMcpServer } from "./server.js"; // 导入我们的MCP服务器类
import { config } from "dotenv"; // 导入环境变量配置工具
import { resolve } from "path"; // 导入路径解析工具
import { Logger } from "./utils/helpers.js"; // 导入日志工具
// 🌐 环境变量加载
// 尝试从.env文件加载环境变量(如果存在)
// 在MCP场景下,环境变量通常由客户端(如Cursor)通过配置传递
try {
config({ path: resolve(process.cwd(), ".env") }); // 从当前工作目录加载.env文件
} catch (error) {
// 静默忽略.env文件不存在的错误
// 因为在MCP环境中,环境变量由客户端配置提供
}
// 🔒 环境变量验证
// 检查必需的API密钥是否存在
if (!process.env.SILICONFLOW_API_KEY) {
// 如果API密钥不存在,输出详细的错误信息和解决方案
console.error("错误: 请设置环境变量 SILICONFLOW_API_KEY");
console.error("在MCP服务器配置中,请确保在env字段中设置了此变量");
process.exit(1); // 以错误状态退出程序
}
/**
* 🚀 启动服务器函数
* 这是程序的主入口点,负责创建和启动MCP服务器
*/
export async function startServer(): Promise<void> {
try {
// 创建MCP服务器实例
const server = new PromptFormatMcpServer();
// 输出启动日志
Logger.log("启动 Prompt Format MCP 服务器...");
// 启动stdio传输模式的服务器
// stdio模式是MCP协议的标准传输方式,通过标准输入输出与客户端通信
await server.startStdio();
} catch (error) {
// 如果启动失败,记录错误并退出
Logger.error("服务器启动失败:", error);
process.exit(1);
}
}
// 🛡️ 全局异常处理
// 捕获未处理的异常,防止程序意外崩溃
process.on('uncaughtException', (error) => {
Logger.error('未捕获的异常:', error);
process.exit(1); // 异常退出
});
// 🎯 程序启动点
// 调用启动函数,开始运行服务器
startServer();关键点解析:
- Shebang行: 使文件可以直接执行
- 环境变量处理: 支持.env文件和客户端配置两种方式
- 错误处理: 完整的异常捕获和进程信号处理
- 启动流程: 简洁的服务器启动逻辑
2. 核心服务器 (src/server.ts)
这是MCP服务器的核心文件,展示了完整的MCP服务器实现:
// 🔧 导入MCP核心模块
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; // MCP服务器核心类
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; // stdio传输层
import { z } from "zod"; // 参数验证和类型定义库
/**
* 🎯 Prompt Format MCP 服务器类
* 这是整个MCP服务器的核心类,负责:
* 1. 创建和配置MCP服务器实例
* 2. 注册和管理工具
* 3. 处理客户端请求
* 4. 管理与AI API的通信
*/
export class PromptFormatMcpServer {
private server: McpServer; // MCP服务器实例
private apiClient: SiliconFlowClient; // AI API客户端实例
constructor() {
// 🔧 创建MCP服务器
// 这是MCP协议的核心,定义了服务器的基本信息和能力
this.server = new McpServer({
name: "prompt-format-mcp", // 服务器名称,客户端用此识别服务器
version: "1.0.11", // 服务器版本号
}, {
capabilities: {
tools: {}, // 声明此服务器支持工具功能
// 其他可能的能力:
// resources: {}, // 资源功能
// prompts: {}, // 提示词模板功能
// logging: {}, // 日志功能
},
});
// 📝 注册工具
this.registerTools();
}
/**
* 🛠️ 工具注册方法
* 这里注册所有MCP工具,每个工具都有特定的功能
*/
private registerTools() {
// 🔧 第一个工具:optimize-prompt
this.server.tool(
"optimize-prompt", // 工具名称,客户端调用时使用
"Optimize prompt for better AI model performance", // 工具描述
{
// 📋 参数模式定义
// 使用zod库定义参数的类型和验证规则
content: z.string().describe("Prompt content to optimize")
},
// 🎯 工具处理函数
async ({ content }) => {
// 🔄 使用重试机制调用AI API
const optimized = await retry(
() => this.apiClient.optimizePrompt(content),
3, // 最大重试次数
1000 // 每次重试间隔(毫秒)
);
// 🎯 返回MCP标准响应格式
return {
content: [
{
type: "text", // 内容类型:文本
text: optimized // 优化后的内容
}
]
};
}
);
}
/**
* 🚀 启动stdio服务器
* 这是MCP服务器的标准启动方法
*/
async startStdio(): Promise<void> {
// 🔌 创建stdio传输层
const transport = new StdioServerTransport();
// 🔗 连接服务器和传输层
await this.server.connect(transport);
Logger.log("MCP Server started on stdio");
}
}关键概念解析:
MCP服务器创建
const server = new McpServer({
name: "prompt-format-mcp", // 服务器标识
version: "1.0.11", // 版本号
}, {
capabilities: {
tools: {}, // 声明支持的功能
},
});工具注册机制
server.tool(
"tool-name", // 工具名称
"Tool description", // 工具描述
parameterSchema, // 参数验证模式
handlerFunction // 处理函数
);Studio模式通信
- stdio传输: 通过标准输入输出与客户端通信
- JSON-RPC协议: 使用JSON-RPC 2.0协议格式
- 异步处理: 支持异步工具调用
3. API客户端 (src/api/siliconflow.ts)
展示了如何封装第三方AI API:
export class SiliconFlowClient {
private apiKey: string; // API密钥
private baseUrl: string; // API基础URL
private modelName: string; // AI模型名称
/**
* 🔄 调用API的核心方法
* 包含完整的错误处理和重试逻辑
*/
private async callAPI(request: SiliconFlowRequest): Promise<SiliconFlowResponse> {
const maxRetries = 3;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
// 🌐 发送HTTP请求
const response = await axios.post(
`${this.baseUrl}/chat/completions`,
request,
{
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
timeout: 90000, // 90秒超时
validateStatus: (status) => status < 500 // 自定义状态码验证
}
);
return response.data;
} catch (error) {
// 🔍 错误分类处理
if (error.code === 'ECONNABORTED') {
// 超时错误 - 重试
if (attempt < maxRetries) {
await new Promise(resolve => setTimeout(resolve, 2000 * attempt));
continue;
}
}
// 其他错误处理...
}
}
}
}API设计要点:
- 重试机制: 自动重试失败的请求
- 错误分类: 区分不同类型的错误
- 超时处理: 设置合理的超时时间
- 状态码验证: 自定义HTTP状态码处理
4. 类型定义 (src/types/index.ts)
/**
* 🤖 SiliconFlow API响应类型
* 符合OpenAI兼容的API响应格式
*/
export interface SiliconFlowResponse {
choices: Array<{
message: {
content: string; // AI生成的内容
role: string; // 消息角色
};
finish_reason: string; // 结束原因
index: number; // 选择索引
}>;
usage: {
completion_tokens: number; // 生成的token数
prompt_tokens: number; // 输入的token数
total_tokens: number; // 总token数
};
}5. 工具函数 (src/utils/helpers.ts)
/**
* 🔄 重试函数
* 提供自动重试机制,提高API调用的可靠性
*/
export async function retry<T>(
fn: () => Promise<T>, // 要重试的函数
maxAttempts: number = 3, // 最大重试次数
delayMs: number = 1000 // 基础延迟时间
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
if (attempt < maxAttempts) {
// 递增延迟:第一次1s,第二次2s,第三次3s
await delay(delayMs * attempt);
}
}
}
throw lastError!;
}工具函数设计:
- 泛型支持: 支持任意类型的返回值
- 递增延迟: 避免频繁重试对服务器造成压力
- 错误保留: 保留最后一次错误信息
🔧 Studio模式与工具交互
MCP服务器创建过程
初始化服务器
const server = new McpServer({ name: "prompt-format-mcp", // 服务器名称 version: "1.0.11", // 版本号 }, { capabilities: { tools: {}, // 声明支持工具功能 }, });注册工具
server.tool( "tool-name", // 工具名称 "Tool description", // 工具描述 schema, // 参数模式 handler // 处理函数 );启动服务器
const transport = new StdioServerTransport(); await server.connect(transport);
工具间协调机制
我们的项目实现了两个协调工具:
- optimize-prompt - 优化提示词
- confirm-and-continue - 确认并继续对话
这两个工具的协调流程:
用户输入 → optimize-prompt → 返回优化结果 → 用户确认 → confirm-and-continue → 触发AI继续对话客户端处理流程
客户端发起请求
{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "optimize-prompt", "arguments": { "content": "用户的提示词" } } }服务器处理并返回
{ "jsonrpc": "2.0", "result": { "content": [ { "type": "text", "text": "优化后的结果" } ] } }
📦 发布与打包
1. 构建项目
# 编译TypeScript到JavaScript
npm run build
# 编译后的文件在dist/目录2. 配置package.json
{
"name": "prompt-format-mcp",
"version": "1.0.11",
"type": "module", // 使用ES模块
"main": "dist/index.js", // 入口文件
"bin": {
"prompt-format-mcp": "dist/index.js" // 命令行工具
},
"files": [
"dist", // 只包含编译后的文件
"README.md"
]
}3. 发布到npm
# 登录npm账户
npm login
# 发布包
npm publish4. 版本管理
# 更新版本号并发布
npm version patch # 补丁版本 1.0.11 → 1.0.12
npm version minor # 次要版本 1.0.11 → 1.1.0
npm version major # 主要版本 1.0.11 → 2.0.0🎯 在Cursor中使用
1. 配置MCP服务器
在Cursor中创建或编辑 ~/.cursor/mcp.json:
{
"mcpServers": {
"prompt-format-mcp": {
"command": "npx",
"args": ["-y", "prompt-format-mcp@latest", "--stdio"],
"env": {
"SILICONFLOW_API_KEY": "your-api-key-here"
}
}
}
}2. 配置说明
- command: 使用npx运行,无需本地安装
- args:
-y: 自动确认安装--stdio: 使用stdio传输模式
- env: 环境变量配置
3. 重启Cursor
配置完成后重启Cursor,MCP服务器会自动启动。
4. 使用示例
# 优化提示词
@prompt-format-mcp optimize-prompt 我想做一个网站
# 确认并继续(在优化结果后使用)
@prompt-format-mcp confirm-and-continue 这是我确认的最终提示词...🎮 完整示例
开发自己的MCP服务器
创建项目结构
mkdir my-mcp-server cd my-mcp-server npm init -y npm install @modelcontextprotocol/sdk axios zod npm install -D typescript @types/node tsx创建基础文件
// src/server.ts import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; export class MyMcpServer { private server: McpServer; constructor() { this.server = new McpServer({ name: "my-mcp-server", version: "1.0.0", }, { capabilities: { tools: {}, }, }); this.registerTools(); } private registerTools() { // 注册你的工具 this.server.tool( "hello-world", "Say hello to the world", { name: z.string().describe("Name to greet") }, async ({ name }) => { return { content: [ { type: "text", text: `Hello, ${name}! Welcome to MCP!` } ] }; } ); } async startStdio(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); } }创建入口文件
// src/index.ts #!/usr/bin/env node import { MyMcpServer } from "./server.js"; async function main() { const server = new MyMcpServer(); await server.startStdio(); } main().catch(console.error);配置TypeScript
// tsconfig.json { "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "node", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }构建和测试
# 构建 npx tsc # 测试 echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
🎉 总结
通过这个教程,你学到了:
- MCP基础概念 - 理解MCP协议和架构
- 服务器开发 - 创建MCP服务器和工具注册
- 工具协调 - 实现工具间的协调和交互
- 客户端集成 - 在Cursor中配置和使用MCP服务器
- 发布流程 - 将MCP服务器发布到npm
MCP开发的核心在于:
- 理解stdio通信协议
- 正确注册和实现工具
- 处理错误和异常
- 提供良好的用户体验
现在你可以开始构建自己的MCP服务器了!🚀
🔗 相关资源
作者: MCP开发教程 版本: 1.0.11 更新时间: 2024年12月
