天气数据服务

一个基于ModelContextProtocol的天气数据服务,提供天气警报和天气预报功能,适用于需要集成天气信息的应用场景。

  • by Sunil-paudel
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 Sunil-paudel/mcpserverasof2025updated

使用说明

npm init-y-->创建包json npm安装@modelcontextprotocol/sdkzod@3--安装mcp-sdk和zod进行数据验证 mkdir src-->创建src文件夹 触摸src/index.ts-->创建index.ts文件

****替换package.json内容bby->这将创建模块格式并添加scriot用于构建 { “name”:“mcpserver”, “版本”:“1.0.0”, “description”:“”, “类型”:“模块”, “main”:“index.js”, “bin”:{ “天气”:“./build/index.js” }, “脚本”:{ “test”:“echo”错误:未指定测试“&&退出1”, “build”:“tsc&&chmod 755 build/index.js” }, “文件”:[ “构建” ], “关键字”:[], 作者 “许可证”:“ISC”, “依赖关系”:{ “@modelcontextprotocol/sdk”:“^1.22.0”, “安装”:“^0.13.0”, “下午”:“^2.2.6”, “zod”:“^3.25.76” } }

****在项目的根目录中创建一个tsconfig.json:

    {
    "compilerOptions": {
        "target": "ES2022",
        "module": "Node16",
        "moduleResolution": "Node16",
        "outDir": "./build",
        "rootDir": "./src",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules"]
    }

    then add thuis code in index.ts
                            // Import MCP server framework
                            import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
                            import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
                            // zod for input validation
                            import { z } from "zod";

                            // Base URL for the US National Weather Service API
                            const NWS_API_BASE = "https://api.weather.gov";
                            // Custom User-Agent required by NWS API
                            const USER_AGENT = "weather-app/1.0";

                            // Create an MCP server instance with basic metadata (NEW API – no capabilities)
                            const server = new McpServer({
                            name: "weather",
                            version: "1.0.0",
                            });

                            // ---------------------------------------------
                            // Helper: General fetch wrapper for NWS API
                            // ---------------------------------------------
                            async function makeNWSRequest<T>(url: string): Promise<T | null> {
                            const headers = {
                                "User-Agent": USER_AGENT,
                                Accept: "application/geo+json",
                            };

                            try {
                                const response = await fetch(url, { headers });

                                if (!response.ok) {
                                throw new Error(`HTTP error! status: ${response.status}`);
                                }

                                return (await response.json()) as T;
                            } catch (error) {
                                console.error("Error making NWS request:", error);
                                return null;
                            }
                            }

                            // ---------------------------------------------
                            // Types for API responses
                            // ---------------------------------------------
                            interface AlertFeature {
                            properties: {
                                event?: string;
                                areaDesc?: string;
                                severity?: string;
                                status?: string;
                                headline?: string;
                            };
                            }

                            interface ForecastPeriod {
                            name?: string;
                            temperature?: number;
                            temperatureUnit?: string;
                            windSpeed?: string;
                            windDirection?: string;
                            shortForecast?: string;
                            }

                            interface AlertsResponse {
                            features: AlertFeature[];
                            }

                            interface PointsResponse {
                            properties: {
                                forecast?: string;
                            };
                            }

                            interface ForecastResponse {
                            properties: {
                                periods: ForecastPeriod[];
                            };
                            }

                            // ---------------------------------------------
                            // Helper: Format alert into readable text
                            // ---------------------------------------------
                            function formatAlert(feature: AlertFeature): string {
                            const props = feature.properties;

                            return [
                                `Event: ${props.event || "Unknown"}`,
                                `Area: ${props.areaDesc || "Unknown"}`,
                                `Severity: ${props.severity || "Unknown"}`,
                                `Status: ${props.status || "Unknown"}`,
                                `Headline: ${props.headline || "No headline"}`,
                                "---",
                            ].join("\n");
                            }

                            // ---------------------------------------------
                            // TOOL #1 — GET WEATHER ALERTS FOR A STATE
                            // ---------------------------------------------
                            server.tool(
                            "get_alerts",
                            "Get weather alerts for a state",
                            {
                                state: z.string().length(2).describe("Two-letter state code (e.g. CA, NY)"),
                            },
                            async ({ state }) => {
                                const stateCode = state.toUpperCase();
                                const alertsUrl = `${NWS_API_BASE}/alerts?area=${stateCode}`;

                                const alertsData = await makeNWSRequest<AlertsResponse>(alertsUrl);

                                if (!alertsData) {
                                return {
                                    content: [{ type: "text", text: "Failed to retrieve alerts data" }],
                                };
                                }

                                const features = alertsData.features || [];

                                if (features.length === 0) {
                                return {
                                    content: [{ type: "text", text: `No active alerts for ${stateCode}` }],
                                };
                                }

                                const text = `Active alerts for ${stateCode}:\n\n${features
                                .map(formatAlert)
                                .join("\n")}`;

                                return { content: [{ type: "text", text }] };
                            }
                            );

                            // ---------------------------------------------
                            // TOOL #2 — GET WEATHER FORECAST FOR COORDINATES
                            // ---------------------------------------------
                            server.tool(
                            "get_forecast",
                            "Get weather forecast for a location",
                            {
                                latitude: z.number().min(-90).max(90).describe("Latitude"),
                                longitude: z.number().min(-180).max(180).describe("Longitude"),
                            },
                            async ({ latitude, longitude }) => {
                                const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(
                                4
                                )},${longitude.toFixed(4)}`;

                                const pointsData = await makeNWSRequest<PointsResponse>(pointsUrl);

                                if (!pointsData) {
                                return {
                                    content: [
                                    {
                                        type: "text",
                                        text: `Failed to retrieve grid point data for ${latitude}, ${longitude}. Only US locations are supported.`,
                                    },
                                    ],
                                };
                                }

                                const forecastUrl = pointsData.properties?.forecast;

                                if (!forecastUrl) {
                                return {
                                    content: [{ type: "text", text: "No forecast URL found for location" }],
                                };
                                }

                                const forecastData = await makeNWSRequest<ForecastResponse>(forecastUrl);

                                if (!forecastData) {
                                return { content: [{ type: "text", text: "Failed to retrieve forecast" }] };
                                }

                                const periods = forecastData.properties?.periods || [];

                                if (periods.length === 0) {
                                return { content: [{ type: "text", text: "No forecast periods available" }] };
                                }

                                const text = `Forecast for ${latitude}, ${longitude}:\n\n${periods
                                .map((p) =>
                                    [
                                    `${p.name}:`,
                                    `Temperature: ${p.temperature}°${p.temperatureUnit}`,
                                    `Wind: ${p.windSpeed} ${p.windDirection}`,
                                    `${p.shortForecast}`,
                                    "---",
                                    ].join("\n")
                                )
                                .join("\n")}`;

                                return { content: [{ type: "text", text }] };
                            }
                            );

                            // ---------------------------------------------
                            // MAIN ENTRYPOINT — Start MCP Server
                            // ---------------------------------------------
                            async function main() {
                            const transport = new StdioServerTransport();
                            await server.connect(transport);
                            console.error("Weather MCP Server running on stdio");
                            }

                            // Start and handle fatal errors
                            main().catch((error) => {
                            console.error("Fatal error in main():", error);
                            process.exit(1);
                            });

然后 npm安装--保存dev@types/node npm安装-g typescript npm运行构建 节点构建/index.js

然后,要连接到claude桌面,请转到终端并粘贴此打开的~/Library/Application\Support/claude/claude_desktop_config json 然后你会看到你的配置json, 但请转到thid文件夹并粘贴 { “mcpServers”:{ “天气服务器”:{ “command”:“node”, “args”:[“/Users-->index.js文件的路径,并用/”]关闭它 } } } 现在保存它,您可以重新启动claude桌面,并可以看到您的mcp服务器 然后在克劳德桌面上聊天,让它按城市名称或经纬度获取天气数据

获得gitrepo后: git克隆(此报告URL) npm安装 npm运行构建 节点构建/index.js