Skip to main content
Glama
robertn702

OpenWeatherMap MCP Server

get-current-weather

Retrieve real-time weather data for a specific location using city name or coordinates. Specify temperature units (Celsius, Fahrenheit, or Kelvin) for accurate weather conditions.

Instructions

Get current weather conditions for a location

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
locationYesCity name (e.g., 'New York') or coordinates (e.g., 'lat,lon')
unitsNoTemperature units: metric (Celsius), imperial (Fahrenheit), or standard (Kelvin)

Implementation Reference

  • The anonymous async execute function that implements the core logic of fetching current weather data from OpenWeatherMap API via getOpenWeatherClient, configuring location, retrieving data, formatting with formatCurrentWeather, and returning formatted text response while handling specific errors.
    execute: async (args, { session, log }) => {
      try {
        log.info("Getting current weather", { location: args.location });
        
        // Get OpenWeather client
        const client = getOpenWeatherClient(session as SessionData | undefined);
        
        // Configure client for this request
        configureClientForLocation(client, args.location, args.units);
        
        // Fetch current weather
        const weatherData = await client.getCurrent();
        
        log.info("Successfully retrieved current weather", { 
          lat: weatherData.lat,
          lon: weatherData.lon,
          temp: weatherData.weather.temp.cur 
        });
        
        // Format the response
        const formattedWeather = formatCurrentWeather({
          name: `${weatherData.lat.toFixed(4)}, ${weatherData.lon.toFixed(4)}`, // Use coordinates as name
          main: {
            temp: weatherData.weather.temp.cur,
            feels_like: weatherData.weather.feelsLike.cur,
            humidity: weatherData.weather.humidity
          },
          weather: [{
            description: weatherData.weather.description
          }],
          wind: {
            speed: weatherData.weather.wind.speed,
            deg: weatherData.weather.wind.deg || 0
          },
          visibility: weatherData.weather.visibility,
          dt: weatherData.dtRaw,
          timezone: weatherData.timezoneOffset
        }, args.units);
        
        return {
          content: [
            {
              type: "text",
              text: formattedWeather
            }
          ]
        };
      } catch (error) {
        log.error("Failed to get current weather", { 
          error: error instanceof Error ? error.message : 'Unknown error' 
        });
        
        // Provide helpful error messages
        if (error instanceof Error) {
          if (error.message.includes('city not found')) {
            throw new Error(`Location "${args.location}" not found. Please check the spelling or try using coordinates.`);
          }
          if (error.message.includes('Invalid API key')) {
            throw new Error('Invalid OpenWeatherMap API key. Please check your configuration.');
          }
        }
        
        throw new Error(`Failed to get current weather: ${error instanceof Error ? error.message : 'Unknown error'}`);
      }
    }
  • Zod validation schema defining the input parameters for the tool: required 'location' string and optional 'units' enum (metric, imperial, standard).
    export const getCurrentWeatherSchema = z.object({
      location: z.string().describe("City name (e.g., 'New York') or coordinates (e.g., 'lat,lon')"),
      units: unitsSchema,
    });
  • src/main.ts:56-125 (registration)
    FastMCP server.addTool registration of the 'get-current-weather' tool, specifying name, description, input schema, and inline execute handler function.
    server.addTool({
      name: "get-current-weather",
      description: "Get current weather conditions for a location",
      parameters: getCurrentWeatherSchema,
      execute: async (args, { session, log }) => {
        try {
          log.info("Getting current weather", { location: args.location });
          
          // Get OpenWeather client
          const client = getOpenWeatherClient(session as SessionData | undefined);
          
          // Configure client for this request
          configureClientForLocation(client, args.location, args.units);
          
          // Fetch current weather
          const weatherData = await client.getCurrent();
          
          log.info("Successfully retrieved current weather", { 
            lat: weatherData.lat,
            lon: weatherData.lon,
            temp: weatherData.weather.temp.cur 
          });
          
          // Format the response
          const formattedWeather = formatCurrentWeather({
            name: `${weatherData.lat.toFixed(4)}, ${weatherData.lon.toFixed(4)}`, // Use coordinates as name
            main: {
              temp: weatherData.weather.temp.cur,
              feels_like: weatherData.weather.feelsLike.cur,
              humidity: weatherData.weather.humidity
            },
            weather: [{
              description: weatherData.weather.description
            }],
            wind: {
              speed: weatherData.weather.wind.speed,
              deg: weatherData.weather.wind.deg || 0
            },
            visibility: weatherData.weather.visibility,
            dt: weatherData.dtRaw,
            timezone: weatherData.timezoneOffset
          }, args.units);
          
          return {
            content: [
              {
                type: "text",
                text: formattedWeather
              }
            ]
          };
        } catch (error) {
          log.error("Failed to get current weather", { 
            error: error instanceof Error ? error.message : 'Unknown error' 
          });
          
          // Provide helpful error messages
          if (error instanceof Error) {
            if (error.message.includes('city not found')) {
              throw new Error(`Location "${args.location}" not found. Please check the spelling or try using coordinates.`);
            }
            if (error.message.includes('Invalid API key')) {
              throw new Error('Invalid OpenWeatherMap API key. Please check your configuration.');
            }
          }
          
          throw new Error(`Failed to get current weather: ${error instanceof Error ? error.message : 'Unknown error'}`);
        }
      }
    });
  • formatCurrentWeather helper function that transforms raw OpenWeatherMap current weather data into a structured JSON string suitable for LLM consumption.
    export function formatCurrentWeather(data: any, units: Units = "metric"): string {
      const weatherData = {
        location: data.name || 'Unknown',
        temperature: {
          current: Math.round(data.main.temp),
          feels_like: Math.round(data.main.feels_like),
          units: getTemperatureUnit(units)
        },
        conditions: data.weather[0].description,
        humidity: data.main.humidity,
        wind: {
          speed: Number(data.wind.speed.toFixed(1)),
          direction: getWindDirection(data.wind.deg),
          units: units === "imperial" ? "mph" : "m/s"
        },
        visibility: {
          value: units === "imperial" ? Number((data.visibility / 1609.34).toFixed(1)) : Number((data.visibility / 1000).toFixed(1)),
          units: units === "imperial" ? "mi" : "km"
        },
        timestamp: data.dt
      };
      
      return JSON.stringify(weatherData);
    }
  • getOpenWeatherClient helper that retrieves or creates a cached OpenWeatherAPI client instance from the session's API key.
    export function getOpenWeatherClient(session: SessionData | null | undefined): OpenWeatherAPI {
      // For stdio transport, use the global session
      const effectiveSession = session || getStdioSession();
    
      if (!effectiveSession) {
        throw new Error("No authentication session available");
      }
    
      const { apiKey } = effectiveSession;
    
      // Check cache first
      let client = clientCache.get(apiKey);
      
      if (!client) {
        // Create new client
        client = new OpenWeatherAPI({
          key: apiKey,
          // Default to metric units, can be overridden per request
          units: "metric"
        });
    
        // Cache the client
        clientCache.set(apiKey, client);
      }
    
      return client;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states what the tool does, not how it behaves. It lacks information about rate limits, error handling, data freshness, authentication needs, or response format. For a read operation with no annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste. It's front-loaded with the core purpose and appropriately sized for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations and no output schema, the description is too minimal. It doesn't explain what 'current weather conditions' includes (temperature, humidity, etc.), response format, or behavioral constraints. Given the complexity and lack of structured data, it should provide more context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents both parameters. The description adds no parameter-specific information beyond what's in the schema. Baseline 3 is appropriate when the schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Get' and the resource 'current weather conditions for a location', making the purpose explicit. It distinguishes from siblings like forecasts or alerts by specifying 'current' conditions, but doesn't explicitly contrast with all alternatives like 'get-weather-forecast'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'get-daily-forecast' or 'get-hourly-forecast'. It mentions 'current weather conditions' which implies real-time data, but offers no explicit usage context, prerequisites, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related 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/robertn702/mcp-openweathermap'

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