init
This commit is contained in:
commit
227d77f586
5 files changed
+1179
No files matched your search
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
.qwen
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Qwen Code Context: Node.js MCP Server
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
This is a Node.js-based Model Context Protocol (MCP) server implementation that provides tools for external clients to interact with. The server uses the `@modelcontextprotocol/sdk` to implement the MCP specification and offers tools like greeting and weather information retrieval.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
- `index.js`: Main server implementation containing tool registrations and server startup logic
|
||||||
|
- `package.json`: Project metadata and dependencies
|
||||||
|
- `package-lock.json`: Dependency lock file
|
||||||
|
- `node_modules/`: Project dependencies
|
||||||
|
|
||||||
|
## Key Dependencies
|
||||||
|
- `@modelcontextprotocol/sdk`: Core SDK for MCP implementation
|
||||||
|
- `zod`: For runtime type checking and validation of tool parameters
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
The server implements the Model Context Protocol and registers two tools:
|
||||||
|
1. `say_hello`: A simple greeting tool that takes a name and returns a personalized greeting
|
||||||
|
2. `get_weather`: A weather information tool that fetches current weather data for a given city using WeatherAPI
|
||||||
|
|
||||||
|
## Building and Running
|
||||||
|
- To run the server: `node index.js`
|
||||||
|
- The server uses stdio transport for communication with clients
|
||||||
|
- For the weather tool to work, a `WEATHER_API_KEY` environment variable must be set
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
- Uses ES modules (indicated by "type": "module" in package.json)
|
||||||
|
- Implements async/await for handling asynchronous operations
|
||||||
|
- Uses Zod for parameter validation
|
||||||
|
- Includes proper error handling for robust operation
|
||||||
|
- Logs important messages to stderr to separate them from data output
|
||||||
|
- Follows MCP specification for return value formatting
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
The weather tool requires a `WEATHER_API_KEY` environment variable to be set to access the weather API service.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
This project serves as an example MCP server implementation that demonstrates how to register and implement tools that can be called by MCP-compatible clients. It's designed to be extensible for adding more tools as needed.
|
||||||
|
|
||||||
|
|
||||||
|
Always respond in 中文
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
// 引入必要的模块
|
||||||
|
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);
|
||||||
|
});
|
||||||
Generated
+1006
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "my-nodejs-mcp-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"@modelcontextprotocol/sdk": "^1.22.0",
|
||||||
|
"zod": "^3.25.76"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user