Skip to main content
Glama
robobobby

mcp-swedish-weather

by robobobby

current_weather

Get current weather conditions for any location in Sweden using SMHI data. Provide a Swedish city name or coordinates to receive detailed meteorological information.

Instructions

Get current weather for a location in Sweden using SMHI.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
locationYesSwedish city name or lat,lon coordinates

Implementation Reference

  • Main handler function for current_weather tool that takes a location parameter, resolves it using helper functions, fetches forecast data from SMHI API, finds the closest time entry to current time, extracts weather parameters (temperature, humidity, wind, pressure, precipitation), and returns formatted weather data as text.
    async ({ location }) => {
      try {
        const loc = await getLocation(location);
        const data = await fetchForecast(loc.lat, loc.lon);
        const ts = data.timeSeries;
        if (!ts?.length) throw new Error("No forecast data");
        const now = Date.now();
        let closest = ts[0];
        let minDiff = Math.abs(new Date(ts[0].validTime).getTime() - now);
        for (const entry of ts.slice(1, 10)) {
          const diff = Math.abs(new Date(entry.validTime).getTime() - now);
          if (diff < minDiff) { closest = entry; minDiff = diff; }
        }
        const p = closest.parameters;
        const lines = [
          `## ${loc.name} — Current Weather`,
          `**Conditions:** ${WSYMB2[getParam(p, "Wsymb2")] || "Unknown"}`,
          `**Temperature:** ${getParam(p, "t")}°C`,
          `**Humidity:** ${getParam(p, "r")}%`,
          `**Wind:** ${getParam(p, "ws")} m/s from ${getParam(p, "wd")}° (gusts ${getParam(p, "gust")} m/s)`,
          `**Pressure:** ${getParam(p, "msl")} hPa`,
          getParam(p, "pmean") != null ? `**Precipitation:** ${getParam(p, "pmean")} mm/h` : null,
          `\n*SMHI — ${closest.validTime}*`,
        ].filter(Boolean);
        return { content: [{ type: "text", text: lines.join("\n") }] };
      } catch (err) {
        return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true };
      }
    }
  • src/index.js:106-139 (registration)
    Registration of the current_weather tool using server.tool() with tool name 'current_weather', description, input schema (z.string() for location parameter), and the async handler function that implements the weather logic.
    server.tool(
      "current_weather",
      "Get current weather for a location in Sweden using SMHI.",
      { location: z.string().describe("Swedish city name or lat,lon coordinates") },
      async ({ location }) => {
        try {
          const loc = await getLocation(location);
          const data = await fetchForecast(loc.lat, loc.lon);
          const ts = data.timeSeries;
          if (!ts?.length) throw new Error("No forecast data");
          const now = Date.now();
          let closest = ts[0];
          let minDiff = Math.abs(new Date(ts[0].validTime).getTime() - now);
          for (const entry of ts.slice(1, 10)) {
            const diff = Math.abs(new Date(entry.validTime).getTime() - now);
            if (diff < minDiff) { closest = entry; minDiff = diff; }
          }
          const p = closest.parameters;
          const lines = [
            `## ${loc.name} — Current Weather`,
            `**Conditions:** ${WSYMB2[getParam(p, "Wsymb2")] || "Unknown"}`,
            `**Temperature:** ${getParam(p, "t")}°C`,
            `**Humidity:** ${getParam(p, "r")}%`,
            `**Wind:** ${getParam(p, "ws")} m/s from ${getParam(p, "wd")}° (gusts ${getParam(p, "gust")} m/s)`,
            `**Pressure:** ${getParam(p, "msl")} hPa`,
            getParam(p, "pmean") != null ? `**Precipitation:** ${getParam(p, "pmean")} mm/h` : null,
            `\n*SMHI — ${closest.validTime}*`,
          ].filter(Boolean);
          return { content: [{ type: "text", text: lines.join("\n") }] };
        } catch (err) {
          return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true };
        }
      }
    );
  • Input schema definition for the current_weather tool using Zod: a single 'location' parameter of type string with description 'Swedish city name or lat,lon coordinates'.
    { location: z.string().describe("Swedish city name or lat,lon coordinates") },
  • fetchForecast helper function that constructs the SMHI API URL with latitude/longitude coordinates and fetches weather forecast data as JSON, throwing an error if the API request fails.
    async function fetchForecast(lat, lon) {
      const url = `${BASE_URL}/lon/${lon.toFixed(6)}/lat/${lat.toFixed(6)}/data.json`;
      const res = await fetch(url, { headers: { "User-Agent": USER_AGENT } });
      if (!res.ok) throw new Error(`SMHI API error (${res.status}): ${await res.text()}`);
      return res.json();
    }
  • getLocation helper function that first tries to resolve location from predefined Swedish cities or coordinate strings, then falls back to geocoding via Open-Meteo API if needed, and throws an error if location cannot be found in Sweden.
    async function getLocation(input) {
      const loc = resolveLocation(input);
      if (loc) return loc;
      const geo = await geocode(input);
      if (geo) return geo;
      throw new Error(`Could not find location "${input}" in Sweden. Try a city name or lat,lon coordinates.`);
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states the data source (SMHI) and geographic scope (Sweden), but doesn't mention rate limits, error conditions, authentication needs, or what the response format looks like. For a read operation with zero annotation coverage, this leaves significant behavioral gaps.

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 that states the core functionality without any wasted words. It's appropriately sized for a simple tool and front-loads the essential information.

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

Completeness3/5

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

For a single-parameter read tool with good schema coverage but no annotations or output schema, the description provides adequate basic context (what it does, geographic scope, data source). However, it lacks important behavioral details like response format, error handling, or usage guidance relative to the sibling tool, leaving room for improvement.

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?

The input schema has 100% description coverage, with the 'location' parameter fully documented as 'Swedish city name or lat,lon coordinates'. The description doesn't add any parameter details beyond what the schema already provides, so it meets the baseline for high schema coverage.

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 action ('Get current weather') and resource ('for a location in Sweden using SMHI'), making the purpose immediately understandable. It doesn't explicitly differentiate from the sibling 'weather_forecast' tool, which prevents a perfect score, but the 'current' vs 'forecast' distinction is implied.

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 the sibling 'weather_forecast' tool, nor does it mention any prerequisites or constraints beyond the location requirement. The agent must infer usage context from the tool names alone.

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

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/robobobby/mcp-swedish-weather'

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