Files
gitlab-mcp-server/index.js
T
2025-11-14 15:10:16 +08:00

113 lines
3.9 KiB
JavaScript

// 引入必要的模块
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);
});