// 引入必要的模块 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; // 创建 MCP 服务器实例 // 为其设置一个名字和版本 const server = new McpServer({ name: "my-first-nodejs-mcp-server", version: "1.0.0", }); /** * 完善版的打招呼工具 * 1. 使用 registerTool 方法进行更完整的描述 * 2. 利用 Zod 库定义严格的参数模式和验证规则 */ server.registerTool('say_hello', { // 工具描述至关重要,它直接帮助AI理解工具的用途、适用场景和参数要求 description: "向指定的用户生成一条个性化的问候语。该工具适用于在对话开始时或需要欢迎用户时使用。", // 使用 Zod 定义参数模式,这是确保AI正确传参的关键[8](@ref) inputSchema: z.object({ // 第一个参数:用户名 name: z.string() .min(1, { message: "姓名不能为空字符串。" }) // 基础验证:确保非空字符串 .max(50, { message: "姓名长度不能超过50个字符。" }) // 防止过长输入 .describe("被问候者的姓名。请尽量提供完整的姓名或常用称呼。"), // 清晰的参数描述 // 第二个参数(可选):语言/风格 language: z.enum(["casual", "formal", "warm"]) // 枚举类型,将AI的输入严格限制在预设的选项内 .default("casual") // 设置默认值,当AI未提供此参数时使用 .describe("问候的语言风格。'casual'为随意,'formal'为正式,'warm'为热情。默认为'casual'。"), }), }, async ({ name, language }) => { // 根据不同的语言风格生成不同的问候语 const greetings = { casual: `嘿,${name}!最近怎么样?`, formal: `您好,${name}。很高兴见到您。`, warm: `欢迎你,${name}!真高兴你今天能来!`, }; const greetingMessage = greetings[language] || greetings.casual; // MCP 工具要求返回特定的格式 return { content: [ { type: "text", // 内容类型为文本 text: greetingMessage, }, ], }; }); // // 在 server.tool() 方法内,实现一个获取天气的工具 // server.registerTool( // "get_weather", // { // city: z.string().describe("要查询天气的城市名称"), // }, // async ({ city }) => { // // 重要:API密钥等敏感信息应从环境变量读取 // const apiKey = process.env.WEATHER_API_KEY; // if (!apiKey) { // throw new Error("WEATHER_API_KEY 环境变量未设置"); // } // try { // // 调用外部天气 API // const response = await fetch( // `https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${city}&aqi=no` // ); // const weatherData = await response.json(); // // 处理并返回需要的信息 // return { // content: [ // { // type: "text", // text: `城市 ${city} 的天气情况: // 温度:${weatherData.current.temp_c}°C // 天气状况:${weatherData.current.condition.text} // `, // }, // ], // }; // } catch (error) { // // 良好的错误处理至关重要 // return { // content: [ // { // type: "text", // text: `获取天气信息失败: ${error.message}`, // }, // ], // isError: true, // 标记这是一个错误结果 // }; // } // } // ); // 启动服务器,使用标准输入/输出(stdio)与客户端通信 async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP 服务器已通过 stdio 启动"); // 日志输出到 stderr } // 运行主函数,并捕获可能的错误 main().catch((error) => { console.error("服务器运行出现致命错误:", error); process.exit(1); });