rui-weather-service-api
Version:
Weather API service with OpenWeatherMap integration - includes both standalone API and MCP server
151 lines • 5.5 kB
JavaScript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { weatherApi } from "../api/weather-api.js";
import { formatCurrentWeather, formatForecast } from "../formatters/weather-formatter.js";
import { validateConfig } from "../config/index.js";
// Create an MCP server for weather information
const server = new McpServer({
name: "Weather API Server",
version: "1.0.0",
});
// Flag to track if server has already been set up
let isServerSetup = false;
/**
* Resets the server setup state, allowing tools to be registered again
*/
export function resetServer() {
isServerSetup = false;
console.log("MCP server state has been reset");
}
/**
* Initializes and registers all MCP server tools and resources
* Will only register tools once to prevent duplicate registration errors
*/
function setupServer() {
// Skip setup if already done to prevent duplicate registrations
if (isServerSetup) {
console.log("Server already set up, skipping tool registration");
return;
}
console.log("Setting up MCP server tools and resources...");
// Create a tool for getting weather forecast
server.tool("getWeatherForecast", {
city: z.string().describe("City name to get the forecast for"),
days: z.number().optional().describe("Number of days for the forecast (max 5)"),
}, async ({ city, days = 5 }) => {
try {
// Use our weather API client to fetch the forecast data
const forecastData = await weatherApi.getForecast(city, days);
// Format forecast info for display
const forecastInfo = formatForecast(forecastData);
return {
content: [
{
type: "text",
text: forecastInfo,
},
],
};
}
catch (error) {
console.error("Error fetching forecast:", error.message);
return {
content: [
{
type: "text",
text: `Error fetching forecast data for ${city}: ${error.message}`,
},
],
};
}
});
// Create a tool for resetting the MCP server state
server.tool("resetMcpCache", {}, async () => {
resetServer();
return {
content: [
{
type: "text",
text: "MCP server cache has been cleared. The server will register tools again on next restart.",
},
],
};
});
// Create a resource for getting current weather by city
server.resource("currentWeather", new ResourceTemplate("weather://{city}", {
list: undefined,
}), async (uri, { city }) => {
try {
// Use our weather API client to fetch the current weather
const cityName = Array.isArray(city) ? city[0] : city;
const weatherData = await weatherApi.getCurrentWeather(cityName);
// Format weather info for display
const weatherInfo = formatCurrentWeather(weatherData);
return {
contents: [
{
text: weatherInfo,
uri: `weather://${city}/info`,
},
],
};
}
catch (error) {
console.error("Error fetching weather:", error.message);
return {
contents: [
{
text: `Error fetching weather data for ${city}: ${error.message}`,
uri: `weather://${city}/error`,
},
],
};
}
});
// Add a weather advisory prompt
server.prompt("weather-advisory", {
city: z.string().describe("City to get weather advisory for"),
}, ({ city }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Please analyze the current weather conditions for ${city} and provide recommendations for activities, clothing, and precautions based on the weather data. Consider temperature, precipitation, wind conditions, and any severe weather alerts.`
}
}
]
}));
// Mark server as set up
isServerSetup = true;
console.log("MCP server tools and resources registered successfully");
}
/**
* Starts the MCP server with stdio transport
*/
export async function startServer() {
try {
console.log("Starting Weather MCP Server...");
// Check if API key is provided
try {
validateConfig();
}
catch (error) {
console.error(error.message);
process.exit(1);
}
// Initialize server with tools and resources
setupServer();
// Connect to stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
console.log("Weather MCP Server running and connected to stdio transport");
}
catch (error) {
console.error("Error starting server:", error);
process.exit(1);
}
}
export { server };
//# sourceMappingURL=mcp-server.js.map