Skip to main content
Glama
terisuke

MCP Weather Service

by terisuke

get-weather

Retrieve current weather data for any city by providing the city name as input. This tool fetches weather information from the MCP Weather Service.

Instructions

Get weather information for a city

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cityYesCity name to get weather for

Implementation Reference

  • src/index.ts:178-238 (registration)
    Registers the 'get-weather' tool using server.tool() with name, description, input schema using Zod, and inline handler function.
    server.tool(
      'get-weather', 
      'Get weather information for a city', 
      {
        city: z.string().describe('City name to get weather for')
      }, 
      async ({ city }) => {
        debug(`Handling get-weather request for city: ${city}`);
        
        try {
          let attempts = 0;
          const maxAttempts = 3;
          let lastError: Error | null = null;
          
          while (attempts < maxAttempts) {
            try {
              attempts++;
              debug(`Attempt ${attempts}/${maxAttempts} for city: ${city}`);
              
              // 最後の試行では、可能であればモックデータを使用
              const useMockData = attempts === maxAttempts;
              const weather = await getWeatherForCity(city, useMockData);
              
              const conditionJapanese = weather.condition;
              
              return {
                content: [{
                  type: 'text',
                  text: `${weather.cityName}の天気:\n気温: ${weather.temperature}\n状態: ${conditionJapanese}`
                }]
              };
            } catch (error) {
              lastError = error instanceof Error ? error : new Error(String(error));
              debug(`Attempt ${attempts} failed:`, lastError.message);
              
              if (attempts < maxAttempts) {
                const waitTime = 1000 * attempts;
                debug(`Waiting ${waitTime}ms before next retry`);
                await new Promise(resolve => setTimeout(resolve, waitTime));
              }
            }
          }
          
          return {
            content: [{
              type: 'text',
              text: `${city}の天気情報の取得に失敗しました: ${lastError?.message || '不明なエラー'}`
            }]
          };
        } catch (error) {
          debug(`Error processing weather request:`, error);
          
          return {
            content: [{
              type: 'text',
              text: `${city}の天気情報の取得に失敗しました: ${error instanceof Error ? error.message : String(error)}`
            }]
          };
        }
      }
    );
  • Handler function implementing the 'get-weather' tool logic: retries API calls via getWeatherForCity, handles errors, formats response as MCP text content.
    async ({ city }) => {
      debug(`Handling get-weather request for city: ${city}`);
      
      try {
        let attempts = 0;
        const maxAttempts = 3;
        let lastError: Error | null = null;
        
        while (attempts < maxAttempts) {
          try {
            attempts++;
            debug(`Attempt ${attempts}/${maxAttempts} for city: ${city}`);
            
            // 最後の試行では、可能であればモックデータを使用
            const useMockData = attempts === maxAttempts;
            const weather = await getWeatherForCity(city, useMockData);
            
            const conditionJapanese = weather.condition;
            
            return {
              content: [{
                type: 'text',
                text: `${weather.cityName}の天気:\n気温: ${weather.temperature}\n状態: ${conditionJapanese}`
              }]
            };
          } catch (error) {
            lastError = error instanceof Error ? error : new Error(String(error));
            debug(`Attempt ${attempts} failed:`, lastError.message);
            
            if (attempts < maxAttempts) {
              const waitTime = 1000 * attempts;
              debug(`Waiting ${waitTime}ms before next retry`);
              await new Promise(resolve => setTimeout(resolve, waitTime));
            }
          }
        }
        
        return {
          content: [{
            type: 'text',
            text: `${city}の天気情報の取得に失敗しました: ${lastError?.message || '不明なエラー'}`
          }]
        };
      } catch (error) {
        debug(`Error processing weather request:`, error);
        
        return {
          content: [{
            type: 'text',
            text: `${city}の天気情報の取得に失敗しました: ${error instanceof Error ? error.message : String(error)}`
          }]
        };
      }
    }
  • Zod input schema defining the 'city' parameter as a required string.
    {
      city: z.string().describe('City name to get weather for')
    }, 
  • Helper function to fetch real weather data from Open-Meteo APIs (geocoding + forecast) or use mock data, translates weather codes to Japanese.
    async function getWeatherForCity(city: string, useMockData: boolean = false) {
      try {
        const normalizedCity = city.trim();
        debug(`Getting weather for city: ${normalizedCity}`);
        
        if (useMockData && MOCK_WEATHER_DATA[normalizedCity]) {
          debug(`Using mock data for ${normalizedCity}`);
          return MOCK_WEATHER_DATA[normalizedCity];
        }
        
        // ジオコーディングAPIを使用して座標を取得
        const geocodingResponse = await axios.get(
          `https://geocoding-api.open-meteo.com/v1/search`,
          {
            params: {
              name: normalizedCity,
              count: 1,
              language: 'en'
            },
            timeout: 5000
          }
        );
        
        if (!geocodingResponse.data.results || geocodingResponse.data.results.length === 0) {
          throw new Error(`City "${normalizedCity}" not found`);
        }
        
        const { latitude, longitude, name } = geocodingResponse.data.results[0];
        debug(`Found coordinates for ${name}: ${latitude}, ${longitude}`);
        
        // 天気APIを使用して天気情報を取得
        const weatherResponse = await axios.get(
          `https://api.open-meteo.com/v1/forecast`,
          {
            params: {
              latitude,
              longitude,
              current: 'temperature_2m,weather_code',
              timezone: 'Asia/Tokyo'
            },
            timeout: 5000
          }
        );
        
        const weatherCode = weatherResponse.data.current.weather_code;
        const weatherDescription = weatherCodes[weatherCode] || "不明";
        
        return {
          cityName: name,
          temperature: `${weatherResponse.data.current.temperature_2m}${weatherResponse.data.current_units.temperature_2m}`,
          condition: weatherDescription
        };
      } catch (error) {
        debug(`Error getting weather for city ${city}:`, error);
        
        if (MOCK_WEATHER_DATA[city]) {
          debug(`Falling back to mock data for ${city}`);
          return MOCK_WEATHER_DATA[city];
        }
        
        throw error;
      }
    }
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/terisuke/my-weather-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server