Skip to main content
Glama

weather-get_hourly

Retrieve hourly weather forecasts for the next 12 hours to plan activities and prepare for changing conditions. Specify location and temperature units (metric/imperial) for accurate predictions.

Instructions

Get hourly weather forecast for the next 12 hours

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
locationYesThe city or location for which to retrieve the weather forecast.
unitsNoTemperature unit system (metric for Celsius, imperial for Fahrenheit). Default is metric.

Implementation Reference

  • Core execution logic for the 'weather-get_hourly' tool: validates inputs, queries AccuWeather API for location and hourly forecast, formats output, handles errors.
    export async function handler(
      args: { [x: string]: any },
      extra: RequestHandlerExtra<any, any>
    ): Promise<{ content: TextContent[] }> {
      // Validate args using the Zod schema
      let validatedArgs: z.infer<typeof inputSchema>;
      try {
        validatedArgs = inputSchema.parse(args);
      } catch (error) {
        if (error instanceof z.ZodError) {
          const errorMessages = error.errors
            .map((e) => `${e.path.join('.')}: ${e.message}`)
            .join(', ');
          return { content: [{ type: 'text', text: `Invalid input: ${errorMessages}` }] };
        }
        return { content: [{ type: 'text', text: 'An unexpected error occurred during input validation.' }] };
      }
    
      const { location, units = "metric" } = validatedArgs;
      const apiKey = process.env.ACCUWEATHER_API_KEY;
      if (!apiKey) {
        return { content: [{ type: 'text', text: 'Error: AccuWeather API key not configured' }] };
      }
    
      try {
        // Step 1: Get location key
        const locationUrl = `https://dataservice.accuweather.com/locations/v1/cities/search?apikey=${apiKey}&q=${encodeURIComponent(location)}`;
        const locationResp = await axios.get(locationUrl);
    
        if (!locationResp.data || locationResp.data.length === 0) {
          return { content: [{ type: 'text', text: `No location found for: ${location}` }] };
        }
    
        const locationKey = locationResp.data[0].Key;
    
        // Step 2: Get forecast with location key
        const forecastUrl = `https://dataservice.accuweather.com/forecasts/v1/hourly/12hour/${locationKey}?apikey=${apiKey}&metric=${units === "metric" ? "true" : "false"}`;
        const forecastResp = await axios.get(forecastUrl);
        const data = forecastResp.data;
    
        if (!data || !Array.isArray(data) || data.length === 0) {
          return {
            content: [{ type: 'text', text: `No weather data available for location: ${location}` }]
          };
        }
    
        const unitSymbol = units === "metric" ? "C" : "F";
        const content: TextContent[] = data.map((hour: any) => ({
          type: 'text',
          text: `${hour.DateTime}: ${hour.Temperature.Value}°${unitSymbol}, ${hour.IconPhrase}`,
        }));
    
        return { content };
      } catch (error) {
        console.error("WeatherTool handler error:", error);
        let errorMessage = "An error occurred while fetching weather data.";
    
        if (axios.isAxiosError(error)) {
          if (error.response?.status === 401) {
            errorMessage = "Invalid AccuWeather API key. Please check your credentials.";
          } else if (error.response?.status === 404) {
            errorMessage = `Location not found: ${location}`;
          } else if (error.response) {
            errorMessage = `AccuWeather API error (${error.response.status}): ${error.response.data?.Message || error.message}`;
          } else if (error.request) {
            errorMessage = "Network error: Unable to connect to AccuWeather API.";
          }
        }
    
        return { content: [{ type: 'text', text: errorMessage }] };
      }
    }
  • src/index.ts:10-28 (registration)
    Defines the Tool metadata for 'weather-get_hourly', including name, description, and input schema.
    const hourlyWeatherTool: Tool = {
      name: "weather-get_hourly",
      description: "Get hourly weather forecast for the next 12 hours",
      inputSchema: {
        type: "object",
        properties: {
          location: {
            type: "string",
            description: "The city or location for which to retrieve the weather forecast."
          },
          units: {
            type: "string",
            description: "Temperature unit system (metric for Celsius, imperial for Fahrenheit). Default is metric.",
            enum: ["metric", "imperial"]
          }
        },
        required: ["location"]
      }
    };
  • src/index.ts:69-71 (registration)
    Registers the available tools, including 'weather-get_hourly', in response to ListTools requests.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [hourlyWeatherTool, dailyWeatherTool],
    }));
  • src/index.ts:83-85 (registration)
    Dispatches CallTool requests to the appropriate handler based on tool name 'weather-get_hourly'.
    if (request.params.name === "weather-get_hourly") {
      return await hourlyHandler(args, {} as RequestHandlerExtra<any, any>);
    } else if (request.params.name === "weather-get_daily") {
  • Zod schema for input validation used within the handler.
    export const inputShape = {
      location: z.string().min(1, "Location must be at least 1 character"),
      units: z.enum(["imperial", "metric"]).default("metric").optional().describe("Temperature unit system")
    };
    
    export const inputSchema = z.object(inputShape).describe("Get hourly weather forecast");

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It states the scope (hourly, next 12 hours) and implies a read-only operation, but does not mention return format, error behavior, or data source limitations. It is adequate but not rich.

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 concise sentence with no filler. It front-loads the core action and scope, making it easy for an agent to process quickly.

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

Completeness4/5

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

For a simple two-parameter tool, the description is largely complete: it states the forecast type, granularity, and time window. It does not describe the return payload, but no output schema exists and the tool's purpose is straightforward enough that an agent can infer expected weather data fields.

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 both parameters are already documented in the schema. The description adds no additional parameter-level details beyond what the schema provides, so the baseline score of 3 applies.

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

Purpose5/5

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

The description uses a specific verb ('Get') and resource ('hourly weather forecast') with a clear time bound ('next 12 hours'). This clearly distinguishes it from the sibling tool weather-get_daily, which is for daily forecasts.

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

Usage Guidelines3/5

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

The time range and 'hourly' granularity imply when to use this tool, but the description never explicitly names the alternative or states when to choose it instead. The guidance is present by inference, not direct instruction.

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

Deploy Server

Other Tools