Skip to main content
Glama
cuolm

meteo-swiss-mcp

by cuolm

Swiss Weather MCP Server

Logo PyPI License Release Tests

A Model Context Protocol (MCP) server that provides AI applications with weather information for any place in Switzerland.

  • Forecasts for today and the next 8 days from the MeteoSwiss local forecasts, updated every hour

  • Measurements from about 160 SwissMetNet weather stations, updated every 10 minutes

  • Any place on the Swiss national map, such as towns, districts, lakes and peaks, from swissNAMES3D

  • When the Sun and the Moon rise and set at a place, the civil twilight, the Moon's phase and how much of it is lit, calculated for any day

  • A bundled MCP client for testing

Data sources. This project is not an official MeteoSwiss product.

Table of Contents

Related MCP server: wetter-mcp-server

Project Structure

swiss-weather-mcp/
├── src/swiss_weather_mcp/
│   ├── server.py           # MCP server and its tools
│   ├── places/             # swisstopo place lookup
│   ├── forecast/           # MeteoSwiss local forecasts
│   ├── measurements/       # MeteoSwiss SwissMetNet measurements
│   ├── astronomy/          # Sunrise, sunset, moonrise, moonset and phase
│   └── client.py           # MCP client
├── tests/swiss_weather_mcp/  # Tests
└── .github/workflows/      # CI and release pipelines

Installation

# As a command line tool
uv tool install swiss-weather-mcp

# With the optional MCP client, which pulls in the OpenAI SDK
uv tool install 'swiss-weather-mcp[client]'

# As a library dependency
uv add swiss-weather-mcp  # or: pip install swiss-weather-mcp

From source:

git clone https://github.com/cuolm/swiss-weather-mcp.git
cd swiss-weather-mcp
uv sync --extra client  # or, in a virtual environment: pip install -e ".[client]"

No configuration is needed, the server reads everything it requires from MeteoSwiss and swisstopo.

Usage

Running the Server

# stdio (default)
swiss-weather-mcp-server

# streamable-http
swiss-weather-mcp-server --transport=streamable-http --host=localhost --port=8050

From a source checkout, put uv run in front. --help lists all flags.

Note: The cache lives in your OS cache directory, such as ~/Library/Caches/swiss-weather-mcp on macOS or ~/.cache/swiss-weather-mcp on Linux. Set SWISS_WEATHER_MCP_CACHE_DIR to move it. The first start downloads the swissNAMES3D archive (about 33 MB) and the swissBOUNDARIES3D GeoPackage (about 37 MB, kept unpacked at about 74 MB).

MeteoSwiss publishes a new forecast run every hour, each hourly parameter as one file of about 30 to 34 MB for all forecast points. By default the server downloads such a file for every new forecast point and keeps only that point's rows. With --cache-all-forecast-points it keeps the whole files, so further places in the same run need no new download. This helps when many places are asked within the hour, at the cost of disk space.

Running the Server with Docker

Images are built and published automatically by GitHub Actions to the project's GitHub Container Registry, tagged :latest (newest release) and by version.

  1. Run the published image, mapping port 8050:

    docker run -p 8050:8050 ghcr.io/cuolm/swiss-weather-mcp:latest
  2. Access the server at:

    http://localhost:8050/mcp/

Note: The cache lives inside the container and is lost when it stops. Mount a volume to keep it across restarts, for example -v swiss-weather-cache:/root/.cache/swiss-weather-mcp.

Manual Build

docker build -t swiss-weather-mcp .
docker run -p 8050:8050 swiss-weather-mcp

Running the MCP Client using Stdio Transport

The bundled MCP client tests the server over stdio. It needs the client extra (see Installation) and starts the MCP server itself, but not the LLM, which has to be running first, for example in llama-server.

  1. Install llama.cpp, which provides llama-server, as its installation guide describes. With Homebrew on macOS or Linux:

    brew install llama.cpp
  2. Start llama-server with a model in its own terminal. It downloads the model on first use:

    llama-server --jinja --no-mmproj -hf unsloth/Qwen3.5-4B-GGUF --port 8080

    --jinja uses the model's chat template, which tool calling needs (the default in current llama.cpp), and --no-mmproj skips the vision projector.

  3. Run the client against it in a second terminal:

    swiss-weather-mcp-client --model=unsloth/Qwen3.5-4B-GGUF --base-url=http://localhost:8080/v1
    
    # From a source checkout, using uv
    uv run --extra client swiss-weather-mcp-client --model=unsloth/Qwen3.5-4B-GGUF --base-url=http://localhost:8080/v1

    --base-url is the server's OpenAI compatible API, and --model the name it lists under /v1/models.

Available Tools

The forecast tools take a location (the name of a place, such as "Zürich") and a Swiss local time, or a date for forecast_daily. Every tool that takes a location also takes an optional near, only needed when several places share the name (see Locations). Each answer holds the forecast, the place, the time it applies to, and the model run. It names the MeteoSwiss forecast point only when the point is not next to the place (see Forecast Points).

Tool

Purpose

Example Call

current_date_and_time()

Today's weekday and the Swiss time now

current_date_and_time()

forecast_daily(location, start_date, days)

One row per day, 1 to 9 days: lowest and highest temperature, median rainfall with its 10th and 90th percentile, daytime weather in words with an emoji

forecast_daily("Zürich", "2026-09-26", 2)

forecast_rain(location, start, end)

Rain and weather in 3-hour blocks over any period within the forecast: chance (%), median (mm), how much the wettest hour may bring (mm) and the weather in words with an emoji

forecast_rain("Zürich", "2026-09-23T12:00", "2026-09-24T00:00")

forecast_temperature(location, start, end)

Temperature hour by hour over any period within the forecast, or one hour without end: mean (°C) with its 10th and 90th percentile

forecast_temperature("Zürich", "2026-09-23T15:00")

forecast_sunshine(location, start, end)

Sunshine (h) summed over a period, or one hour without end

forecast_sunshine("Zürich", "2026-09-23T06:00", "2026-09-23T18:00")

forecast_wind(location, when)

Mean speed and strongest gust (km/h) in the hour up to that time, how strong that gust may get (its 90th percentile), and the direction as degrees and compass point

forecast_wind("Zürich", "2026-09-23T14:00")

forecast_cloud_cover(location, when)

Estimated total cloud cover (%) plus the low, medium and high layers

forecast_cloud_cover("Zürich", "2026-09-23T14:00")

forecast_freezing_level(location, when)

Height of the 0 °C line (m above sea level)

forecast_freezing_level("Zürich", "2026-09-23T14:00")

measurements_current(location)

Measured now at a MeteoSwiss station near the place: temperature, humidity, dew point, rain and sunshine in the last 10 minutes, wind, gust, direction and sea-level pressure, plus the temperature and pressure change over the last 3 hours and the rain, sunshine and strongest gust of the last hour

measurements_current("Zürich")

measurements_extremes(extreme)

Where in Switzerland it is warmest, coldest, windiest, wettest or sunniest now, from the measurements of all weather stations: the first 5 stations by temperature, gust or rain, how many stations are rainy, or how many stations are in each of MeteoSwiss's sunshine terms, in Switzerland and in each canton

measurements_extremes("sunniest")

astronomy_moon(location, date)

Moonrise and moonset for a level horizon, the phase with its emoji, the time of a New Moon, First Quarter, Full Moon or Last Quarter on that day, and the lit percent at 12:00

astronomy_moon("Zürich", "2026-11-01")

astronomy_sun(location, date)

Sunrise and sunset for a level horizon, and the begin and end of civil twilight, when it is light enough outside without artificial light

astronomy_sun("Zürich", "2026-10-28")

Good to Know

Times

  • Send times as Swiss clock time in ISO 8601, such as "2026-09-23T14:00"; the server applies summer or winter time.

  • Answers give times with their UTC offset, such as 2026-09-23T13:00+02:00.

  • An hourly value stamped 14:00 covers 13:00 to 14:00. Cloud cover and the freezing level are values at that moment.

  • The forecast covers today and the next 8 days. For "tomorrow" or "tonight", ask current_date_and_time() first.

Locations

  • A location is a place name from swissNAMES3D: a town, village, city district, peak, pass, lake, glacier, valley or railway station, such as Zürich, Oerlikon, Titlis or Zürichsee.

  • Case and accents are ignored, and English names such as Geneva work too.

  • A name of several places, such as Blausee, needs near: a village next to the one the user means, such as near="Riederalp". Without it, the tool lists every place, each with a village to pass as near and the municipality and canton it lies in. A lake that belongs to a canton itself, such as the Thunersee, gets only its canton:

    'Blausee' is the name of 6 places. [...] The biggest first:
      near="Blausee-Mitholz": district and lake, fewer than 20 people, 887 m, municipality Kandergrund, canton Bern
      near="Ramiswil": settlement, fewer than 20 people, 683 m, municipality Mümliswil-Ramiswil, canton Solothurn
      ...
  • The municipalities and cantons carry swisstopo's names, in the local language, such as Genève or Graubünden. They appear once the swissBOUNDARIES3D GeoPackage is downloaded in the background at start.

  • An unknown name gets suggestions, such as Davos Dorf and Davos Platz for Davos.

Forecast Points

  • The forecast comes from a MeteoSwiss forecast point near the place. An answer names it in data_from when it is more than 1 km away or more than 50 m higher or lower.

  • Weather changes faster with height than with distance: in the standard atmosphere, air cools by 0.65 °C per 100 m.

  • So among the points within 5 km, the server takes the one with the smallest distance plus 20 times the height gap: 100 m of height gap counts like 2 km of distance. Without a point within 5 km, it takes the nearest one.

  • The factor 20 was tested on the real data: up to 20, the height gaps of lakes and peaks shrink a lot, and every town of 1,000 people or more still gets a point within 3 km.

Measurements

  • measurements_current uses one of the about 160 SwissMetNet stations that measure the temperature, chosen like the forecast point: the smallest distance plus 20 times the height gap. Stations are far fewer than forecast points, so the station can still be far from the place and higher or lower.

  • Every answer starts with a sentence that says so, such as "The measurements for Braunwald (1290 m) are those of the MeteoSwiss station Elm (958 m), 13.5 km away and 332 m lower."

  • measurements_extremes lists the first 5 stations by temperature, gust or rain, and counts the rainy stations in Switzerland and in each canton.

  • For the sunniest it groups the stations by their sun in the last 10 minutes with the sunshine terms of MeteoSwiss: mostly sunny (8 to 10 minutes, 80 to 100 %), rather sunny (5 to 7), partly sunny (2 to 4), only a little sunshine (1) and hardly any sunshine (0). A share on the boundary of two of its terms counts for the sunnier one. The cantons come in the order of their stations' average sun.

Forecast Values Are Medians

  • Temperature and rain are the median of the many possible outcomes MeteoSwiss calculates, not the most likely value.

  • Medians do not add up: when showers are possible but unlikely in any single hour, every hour shows 0 mm while the day still has several millimetres.

  • Use forecast_daily for the rain of a day, and forecast_rain for the chance and how much a wet hour may bring.

Example Usage with LMStudio

Using the streamable-http transport layer

Configure the mcp.json file in LMStudio:

{
  "mcpServers": {
    "swiss_weather_mcp_server": {
      "url": "http://localhost:8050/mcp/"
    }
  }
}

Run the MCP server with the streamable-http transport layer:

swiss-weather-mcp-server --transport=streamable-http --host=localhost --port=8050

Using the stdio transport layer

Configure the mcp.json file in LMStudio. Replace <path-to> so the command is the full path that which swiss-weather-mcp-server prints:

{
  "mcpServers": {
    "swiss_weather_mcp_server": {
      "command": "<path-to>/swiss-weather-mcp-server"
    }
  }
}

LMStudioMCPServer

Resources

License

Licensed under the Apache License 2.0.

Available Tools

10 tools
current_conditionsA
        Get the latest measurements of a MeteoSwiss station near the location.

        These are the measurements of that station, not of the location itself. The station is
        the one with the smallest distance plus 20 times the height gap, so it can be several
        kilometres away and hundreds of metres higher or lower than the location. Always start
        the answer with the data_from sentence, which names the station, its distance and its
        height difference, and then give the values as the station's measurements. MeteoSwiss
        publishes new values about every 10 minutes.

        Temperature, humidity, dew point and pressure are measured at measured_at. Rain,
        sunshine, wind speed, the strongest gust and the wind direction cover the 10 minutes up
        to it. The temperature and pressure changes compare measured_at with 3 hours before it,
        negative when the value fell. The rain and sunshine of the last hour are the totals of
        its six 10-minute values, and the strongest gust of the last hour is the highest of them.
        For later today or the coming days use forecast_hourly or forecast_daily.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").

        Returns:
            dict: The place, the station with its distance and height difference, the time of the
                measurements and the measured values; the field names give the units. A value is
                None when the station does not measure it, and a change or a last-hour value is
                None when the station has not published all the measurements it needs, such as
                shortly after midnight UTC.

        Examples:
            current_conditions("Zurich")
            current_conditions("Braunwald")
        
NameRequiredDescriptionDefault
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
locationYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden and does so thoroughly: station selection uses smallest distance plus 20 times height gap, the station may be kilometres away and hundreds of metres higher or lower, values update about every 10 minutes, and the measured_at and 10-minute window semantics are explained. It also explains when values can be None.

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

Conciseness4/5

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

The description is long but front-loaded and every paragraph carries relevant semantics for a tool whose measurements are easy to misinterpret. Some repetition about station measurements could be trimmed, but overall the structure is purposeful and efficient.

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

Completeness5/5

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

There is no output schema, so the description must explain return values, and it does: it names the place, station distance and height difference, measurement time and values, with field names giving units. It also defines None cases for missing measurements and for changes or last-hour values that cannot be computed yet.

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

Parameters4/5

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

Schema description coverage is only 50%, but the description compensates for the undocumented location parameter by defining it as a town, village, city district, lake or peak and giving examples. The near parameter is not mentioned in the description, but its schema description is already detailed and sufficient.

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 states a specific verb and resource: latest measurements from a MeteoSwiss station near a location. It explicitly distinguishes the tool from forecast siblings by directing later-today and multi-day queries to forecast_hourly or forecast_daily.

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

Usage Guidelines5/5

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

It gives an explicit routing rule: use forecast_hourly or forecast_daily for later today or the coming days. It also includes a mandatory answer-format instruction: always begin with the data_from sentence. There is no ambiguity about when this tool is the right choice.

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

current_date_and_timeA
        Get the current weekday and Swiss local time.

        Call this first when the question is relative, such as "tomorrow" or "tonight", because
        the forecast tools take a real date rather than an offset. The time is written the way
        the tools read it, ISO 8601 without an offset, so it can be sent back to them as it is.

        Returns:
            str: For example "Today is Wednesday, 2026-09-23T13:02 (Swiss time)".
        
NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations, the description carries the full transparency burden. It discloses the return type (str), a concrete example ('Today is Wednesday, 2026-09-23T13:02 (Swiss time)'), and the ISO 8601 without-offset format, noting it can be sent directly to the forecast tools. Minor gaps remain about edge cases like DST or system-clock dependence, but they are low-risk.

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 four concise sentences, each earning its place: purpose, usage timing, format rationale, and return example. It is front-loaded with the essential 'what' and keeps the supporting reasoning tight.

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

Completeness5/5

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

For a zero-parameter utility tool, the description is complete. It covers what it returns, when to call it, how the output should be interpreted, and how it feeds into sibling forecast tools. Nothing needed to invoke it correctly is left out.

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

Parameters4/5

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

The tool has zero parameters, so the baseline is 4. The description correctly avoids inventing parameter details and instead focuses on the returned value and its use. No further parameter documentation is needed.

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 opens with a clear verb and object: 'Get the current weekday and Swiss local time.' This unambiguously defines the tool's purpose. It also differentiates from the weather-forecast siblings by being the date/time anchor tool rather than a forecast tool.

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

Usage Guidelines5/5

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

The description explicitly tells the agent when to call it: 'Call this first when the question is relative, such as "tomorrow" or "tonight"'. It also explains why, saying the forecast tools expect a real date rather than an offset. This provides concrete, actionable routing guidance.

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

current_extremesA
        Get where in Switzerland it is warmest, coldest, windiest, wettest or sunniest now.

        This compares the latest measurements of about 160 MeteoSwiss stations. They are the
        values of stations, not of towns, and not a forecast. A high mountain station is
        colder and windier than the valleys, so name the altitude with a station. MeteoSwiss
        publishes new values about every 10 minutes.

        The warmest, coldest and windiest stations are ranked by the temperature and by the
        strongest gust. For the sunniest and the wettest the answer counts stations: a station
        is sunny when the sun shone for at least 5 of the last 10 minutes, and rainy when it
        measured rain in the last 10 minutes. The counts are given for Switzerland and for
        each canton, as the number of sunny or rainy stations out of the stations that measure
        it. Always give both numbers, because a canton with one station says little. A canton
        with 0 sunny or rainy stations has none. A canton that is not listed has no station
        that measures it. Liechtenstein is listed like a canton. At night no station is sunny.

        Args:
            extreme (str): One of "warmest", "coldest", "windiest", "wettest" or "sunniest".

        Returns:
            dict: The time of the measurements and the first 5 stations, or for the sunniest and
                the wettest the counts in all and for each canton, the highest share first; the
                field names give the units. The wettest also lists the first 5 rainy stations.
                A station that does not measure the value is left out everywhere.

        Examples:
            current_extremes("warmest")
            current_extremes("sunniest")
        
NameRequiredDescriptionDefault
extremeYes

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden and does so in detail: about 160 MeteoSwiss stations, published roughly every 10 minutes, station-level rather than town-level values, not a forecast. It also discloses ranking logic for temperature/gust extremes, count logic for sunny/rainy stations, night behavior, and how missing cantons and non-measuring stations are handled.

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

Conciseness4/5

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

The description is front-loaded with purpose and then structured around behavior, parameter, return shape, and examples. It is longer than typical but mostly earns its length because the return semantics are complex; a little tightening is possible, but there is no serious redundancy.

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

Completeness5/5

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

Given one required enum parameter, no annotations, and no output schema, the description supplies the missing return-shape detail: measurement time, first five stations, canton counts ordered by highest share, units from field names, and exclusion of non-measuring stations. It is complete enough for an agent to call and interpret the tool without guessing.

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

Parameters5/5

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

Although schema description coverage is 0%, the sole parameter is an enum and the description enumerates all five values while explaining what each choice means. It goes beyond schema by specifying that warmest/coldest/windiest use ranked station values while sunniest/wettest produce station counts plus canton shares.

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 first sentence states a specific verb and scope: get where in Switzerland it is warmest, coldest, windiest, wettest or sunniest now. It also explicitly distinguishes the tool from forecast siblings by saying these are latest measurements and not a forecast, and clarifies station values rather than town values.

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

Usage Guidelines4/5

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

The description gives clear usage context: use it for current station extremes, not forecasts, and name altitude when discussing mountain stations. It also explains how to interpret sunny/rainy counts and warns to give both Switzerland and canton numbers. It stops short of explicitly naming sibling alternatives such as current_conditions or forecast_hourly, so it is strong but not fully route-aware.

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

forecast_cloud_coverA
        Get how cloudy it is at a place at a specific time.

        MeteoSwiss publishes low, medium and high cloud separately, and they overlap, so the
        total is an estimate that assumes the layers are independent. All three layers are
        returned as well, which tells low fog apart from thin high cloud.

        When a number is not needed, forecast_hourly answers "how cloudy" in plain words.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            when (str): Swiss local time as a full hour in ISO 8601 without offset, e.g. "2026-09-23T14:00". Today or up to 8 days ahead.

        Returns:
            dict: The total cloud cover and its low, medium and high layers in percent, the
                place, the forecast point used, the time it is valid for and the model run.

        Examples:
            forecast_cloud_cover("Zurich", "2026-09-23T14:00")
            forecast_cloud_cover("Locarno", "2026-09-24T09:00")
        
NameRequiredDescriptionDefault
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
whenYes
locationYes

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and discloses a meaningful caveat: the total is an estimate assuming independent layers because MeteoSwiss publishes layers separately. It also explains why all three layers are returned (distinguishing low fog from thin high cloud) and what the response includes (place, forecast point, valid time, model run). It does not mention rate limits, units caveats beyond percent, or failure behavior for out-of-range times.

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

Conciseness4/5

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

Front-loaded with the purpose, then a caveat paragraph, then a routing sentence, then args/returns/examples. Every section is short and the examples are concrete rather than decorative. The literal Args/Returns block formatting is slightly heavier than prose would be, but no sentence is wasted.

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?

No output schema exists, so the Returns section does the work of describing the shape (total plus low/medium/high percentages, place, forecast point, valid time, model run) and does it adequately. Together with the estimate caveat and the time-window constraint, an agent has enough to call it correctly. Minor gaps are the 'near' disambiguation flow and any failure mode for unavailable times.

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 coverage is 33%: only 'near' is documented in the schema, while 'location' and 'when' are bare. The description compensates by defining location as a town, village, city district, lake or peak with examples, and by specifying the exact time format (full hour, ISO 8601 without offset, today to 8 days ahead). That is real added meaning, but the overlap/ambiguity handling for duplicate place names is left entirely to the schema and never reinforced in the description.

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?

States a specific verb and resource: 'Get how cloudy it is at a place at a specific time.' The second paragraph distinguishes it from plain-language cloud reporting and names the three cloud layers it returns, so an agent can tell it apart from forecast_hourly. It does not explicitly contrast against forecast_daily or forecast_rain, but the numeric cloud-cover scope is unambiguous.

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

Usage Guidelines4/5

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

Explicitly routes the plain-word case to forecast_hourly ('when a number is not needed'), giving a clear when-not condition and a named alternative. It also states the time window ('today or up to 8 days ahead'), which sets a usable boundary. No guidance on when to prefer the layer breakdown vs a total-only read, but the essentials are present.

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

forecast_dailyA
        Get the whole-day forecast for a place, for one day or several days in a row: the
        cheapest way to answer "how is the weather" for a day, the weekend or the week.

        Each day covers a Swiss calendar day, 00:00 to 24:00 local time. The minimum and maximum
        are the lowest and highest hourly mean temperature of that day, and the weather words
        describe the daytime. Always use this for the rain of a whole day.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            start_date (str): The first Swiss calendar day in ISO 8601, e.g. "2026-09-23". Today or up to 8 days ahead.
            days (int): How many days in a row, from 1 to 9. Default 1.

        Returns:
            dict: The place, the forecast point used, one row per day and the model run; the
                field names give the units. In 8 of 10 possible outcomes, the day's rain lies
                between its 10th and 90th percentile. A value is None when MeteoSwiss does not
                publish it for that forecast point.

        Examples:
            forecast_daily("Zurich", "2026-09-23")
            forecast_daily("Lugano", "2026-09-26", 2)   # a weekend
        
NameRequiredDescriptionDefault
daysNo
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
locationYes
start_dateYes

TDQS

A5/5.0
Behavior5/5

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

No annotations exist, and the description carries the full burden well: it defines the Swiss calendar day (00:00-24:00 local), explains how min/max are derived from hourly means, warns that weather words describe the daytime, and discloses uncertainty (rain between the 10th and 90th percentile in 8 of 10 outcomes) and None handling. These are non-obvious behaviors an agent could not get from the schema.

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?

Front-loaded with the core purpose and routing sentence, followed by tightly organized semantics, argument notes, return notes and two concrete examples. Every line adds information; nothing is repetitive padding.

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

Completeness5/5

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

A four-parameter forecast tool with no output schema and no annotations still gets everything an agent needs: input formats, ranges, defaults, return structure and unit conventions, uncertainty interpretation, and null-value behavior. No material gap remains.

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

Parameters5/5

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

Schema description coverage is only 25%, but the description supplies the missing meaning: location accepts towns, districts, lakes or peaks; start_date is an ISO Swiss calendar day from today to 8 days ahead; days is 1-9 with default 1. The only undocumented parameter, `near`, is fully explained in the schema itself.

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?

States a specific verb and resource ("Get the whole-day forecast for a place") and immediately scopes it to one or several consecutive days, which separates it from the hourly and single-variable siblings. The parenthetical "the cheapest way to answer 'how is the weather'" makes the intended use recognizable without opening the schema.

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

Usage Guidelines5/5

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

Explicitly routes the agent: use this for a day/weekend/week and "Always use this for the rain of a whole day", which implicitly contrasts with forecast_hourly and the dedicated rain tool. Usage conditions and the date-window limits are stated outright rather than inferred.

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

forecast_freezing_levelA
        Get the height of the 0 degree line at a place at a specific time.

        This is the height where the air is at 0 degrees. Snow usually reaches somewhat below it,
        so it answers questions about snow in the mountains, such as how high a ski area has to be.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            when (str): Swiss local time as a full hour in ISO 8601 without offset, e.g. "2026-09-23T14:00". Today or up to 8 days ahead.

        Returns:
            dict: The freezing level in metres above sea level, the place, the forecast point
                used, the time it is valid for and the model run.

        Examples:
            forecast_freezing_level("Zermatt", "2026-09-23T14:00")
            forecast_freezing_level("Arosa", "2026-09-25T06:00")
        
NameRequiredDescriptionDefault
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
whenYes
locationYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the input time semantics (Swiss local time, full hour, ISO 8601 without offset, today to 8 days ahead) and enumerates what the return dict contains (freezing level in metres AMSL, place, forecast point, valid time, model run). It does not state behavior for out-of-range times, ambiguous place names, or errors.

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

Conciseness4/5

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

The core meaning and scope come first, followed by a helpful interpretation sentence, then Args/Returns/Examples. The Args section partially duplicates the schema, but the structure is scannable and no sentence is pure filler.

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 3-parameter, no-annotation, no-output-schema tool, the description covers purpose, both required inputs' formats and ranges, the return payload contents, and worked examples. Minor gaps: no guidance on error cases or on when the 'near' disambiguation is needed (deferred to the schema).

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

Parameters4/5

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

Schema coverage is only 33% (only 'near' is documented in the schema), but the description fully compensates for both required parameters: it defines 'location' as a town/village/city district/lake/peak with an example, and 'when' with format, timezone, hour granularity and a valid range. The 'near' parameter is left to the schema, which handles it adequately.

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?

States a specific verb and resource: 'Get the height of the 0 degree line at a place at a specific time', reinforced by a plain-language gloss ('the height where the air is at 0 degrees'). The resource is clearly distinct from the sibling forecast_* tools, though it never names or contrasts them explicitly.

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

Usage Guidelines4/5

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

Gives concrete usage context ('answers questions about snow in the mountains, such as how high a ski area has to be') and an operational constraint (today or up to 8 days ahead), which tells the agent when the tool is applicable. No explicit when-not-to-use or pointer to a sibling alternative.

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

forecast_hourlyA
        Get the weather hour by hour for a place: temperature with its likely range, chance
        of rain and the weather in words.

        Use this for one hour, such as "how warm is it at 15:00", or part of a day, such as "how
        is the afternoon" or "when is the best time for a walk". Without end it returns the one
        hour starting at start. Each row covers the hour from its "from" to its "to": the
        temperature is the mean of that hour, while the rain chance and the weather cover the 3
        hours up to "to", as MeteoSwiss publishes them only per 3 hours. For whole days or
        periods longer than a day use forecast_daily, which answers in far fewer rows, and for
        rain amounts forecast_rain.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            start (str): Swiss local time as a full hour in ISO 8601 without offset, e.g. "2026-09-23T15:00". Today or up to 8 days ahead.
            end (str): Optional. Swiss local time as a full hour in ISO 8601 without offset, after start.

        Returns:
            dict: The place, the forecast point used, one row per hour and the model run; the
                field names give the units. In 8 of 10 possible outcomes, the temperature lies
                between its 10th and 90th percentile.

        Examples:
            forecast_hourly("Zurich", "2026-09-23T15:00")                        # one hour
            forecast_hourly("Zurich", "2026-09-23T12:00", "2026-09-23T18:00")    # the afternoon
        
NameRequiredDescriptionDefault
endNo
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
startYes
locationYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the default single-hour behavior when 'end' is omitted, the aggregation semantics (temperature is the hour mean while rain chance and weather cover the 3 hours up to 'to', because MeteoSwiss publishes them per 3 hours), and the 8-day horizon. It stops short of covering failure modes (ambiguous place names besides 'near', out-of-range times) and any auth/rate constraints.

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

Conciseness4/5

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

Purpose and the aggregation caveat are front-loaded, followed by sibling routing, then Args/Returns/Examples in a conventional shape. The Examples block earns its place by showing the single-hour vs range call. A little boilerplate indentation and the redundant restatement of the 3-hour caveat in Returns keep it from a 5.

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?

No output schema exists, but the Returns section describes the payload (place, forecast point, one row per hour, model run, units from field names) and the percentile interpretation, which is enough to call and interpret confidently. The only gap is that the 'near' disambiguation parameter is not addressed in the prose despite no annotations anywhere.

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

Parameters4/5

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

Schema coverage is only 25%, so the description must compensate, and it does: 'start' is specified as Swiss local time, full hour, ISO 8601 without offset, with an example and a 'today to 8 days ahead' range, and 'end' as optional and after start. The 'near' parameter is omitted from the Args block, leaving that one to the schema.

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?

States a specific verb+resource (hour-by-hour weather for a place) and enumerates the returned quantities: temperature with likely range, rain chance, and weather in words. It also distinguishes itself from siblings by naming forecast_daily and forecast_rain and the conditions that select them.

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

Usage Guidelines5/5

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

Gives concrete use cases ('how warm is it at 15:00', 'how is the afternoon', 'best time for a walk') and explicit alternatives for the out-of-scope cases: forecast_daily for whole days or multi-day periods, forecast_rain for rain amounts. When-to-use and when-not are both present.

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

forecast_rainA
        Get when and how much it may rain at a place, in 3-hour blocks over a period.

        Use this for "will it rain this afternoon", "do I need an umbrella" or "when does the
        rain stop". Each block gives the chance of rain, the median rainfall of the 3 hours, and
        how much the wettest hour of the block may bring (its 90th percentile). The median is
        often 0 when showers are possible, so read the chance and the "up to" amount as well.
        A period up to the end of the forecast ends with its last full 3-hour block.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            start (str): Swiss local time the period starts, as a full hour in ISO 8601 without offset, e.g. "2026-09-23T12:00". Today or up to 8 days ahead.
            end (str): Swiss local time the period ends, as a full hour in ISO 8601 without offset, after start.

        Returns:
            dict: The place, the forecast point used, one row per 3-hour block and the model
                run; the field names give the units.

        Examples:
            forecast_rain("Zurich", "2026-09-23T12:00", "2026-09-24T00:00")
            forecast_rain("Lugano", "2026-09-24T06:00", "2026-09-24T18:00")
        
NameRequiredDescriptionDefault
endYes
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
startYes
locationYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does it well: it explains that each block reports chance, median rainfall, and a 90th-percentile "up to" amount, warns that median is often 0 for showers, and discloses that a period past the forecast horizon truncates at the last full 3-hour block. It doesn't mention any auth, rate limits, or cost, which are the remaining gaps.

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

Conciseness4/5

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

It is front-loaded with the core purpose and the disambiguating usage line before the mechanics. The Args/Returns/Examples block is somewhat redundant with the prose and schema for a fairly simple tool, but nothing is misleading.

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?

No output schema exists, and the description compensates by describing the returned dict's shape (place, forecast point, one row per block, model run) and noting units live in field names. Combined with the statistical interpretation guidance, an agent has enough to call and read it correctly.

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

Parameters4/5

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

Schema coverage is only 25% (just `near`), so the description must compensate, and it does: location is defined with examples of acceptable place types, and start/end are specified as Swiss local time, full-hour ISO 8601 without offset, with start constrained to today through 8 days ahead. The only undocumented item is the `near` parameter's interaction, which the schema handles.

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?

States a specific verb and resource — when and how much it may rain at a place, in 3-hour blocks — which cleanly separates it from sibling tools like forecast_daily, forecast_hourly, and forecast_wind.

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

Usage Guidelines4/5

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

Gives concrete triggering questions ("will it rain this afternoon", "do I need an umbrella", "when does the rain stop"), which makes the intended use unambiguous. It never explicitly names a sibling as the alternative for non-rain questions, so it stops short of full routing guidance.

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

forecast_sunshineA
        Get the sunshine hours for a place over a period.

        MeteoSwiss publishes sunshine as minutes per hour, which are added up over the period
        and reported as hours.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            start (str): Swiss local time the period starts, as a full hour in ISO 8601 without offset, e.g. "2026-09-23T06:00". Today or up to 8 days ahead.
            end (str): Swiss local time the period ends, as a full hour in ISO 8601 without offset, e.g. "2026-09-23T18:00".

        Returns:
            dict: The sunshine in hours, the place, the forecast point used, the period and the
                model run.

        Examples:
            forecast_sunshine("Zurich", "2026-09-23T00:00", "2026-09-24T00:00")   # the whole day
            forecast_sunshine("Zurich", "2026-09-23T12:00", "2026-09-23T18:00")   # the afternoon
        
NameRequiredDescriptionDefault
endYes
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
startYes
locationYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden and does well: it explains the MeteoSwiss minutes-per-hour aggregation, gives the allowed forecast horizon, and lists what the return value contains. It stops short of mentioning error modes or ambiguity handling for place names, which the optional near parameter addresses in the schema.

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

Conciseness4/5

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

The description is front-loaded with the core purpose and then organized into Args, Returns, and Examples. It is slightly long for a simple forecast query, but every section adds useful information rather than repeating structured fields.

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?

Given no output schema and no annotations, the description sufficiently covers inputs, return contents, aggregation behavior, and date constraints. It leaves minor gaps around handling ambiguous locations and sibling-tool selection, but an agent has enough to invoke the tool correctly.

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

Parameters4/5

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

Schema coverage is only 25%, so the description compensates by explaining location, start, and end semantics, including ISO 8601 format without offset, Swiss local time, full-hour requirement, and date range. The optional near parameter is omitted from the description, though the schema itself documents it.

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 states a specific verb and resource: get sunshine hours for a place over a period. The metric is distinct from sibling forecast tools like rain, wind, and cloud cover, though it does not explicitly name or differentiate those alternatives.

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?

It gives useful examples for whole-day and afternoon queries and notes the forecast window is today or up to 8 days ahead. However, it does not say when to use this tool versus forecast_daily, forecast_hourly, or other sibling tools, so guidance is implied rather than explicit.

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

forecast_windA
        Get the wind at a place at a specific time: mean speed, strongest gust and direction.

        The speed is the mean over the hour up to that time, and the gust the strongest
        one-second gust in that hour, which is what makes wind hazardous. The gust's 90th
        percentile is a cautious high estimate of that strongest gust: in 9 of 10 possible
        outcomes the gust stays below it, and in 1 of 10 it is stronger, so it is not the
        highest gust possible. The direction is where the wind blows from, in degrees clockwise
        from north (0 is a north wind, 180 a south wind) and as a compass point.

        Args:
            location (str): Place name: a town, village, city district, lake or peak (e.g., "Zurich").
            when (str): Swiss local time as a full hour in ISO 8601 without offset, e.g. "2026-09-23T14:00". Today or up to 8 days ahead.

        Returns:
            dict: The wind, the place, the forecast point used, the time it is valid for and the
                model run; the field names give the units.

        Examples:
            forecast_wind("Zurich", "2026-09-23T14:00")
            forecast_wind("Titlis", "2026-09-24T12:00")
        
NameRequiredDescriptionDefault
nearNoOnly when several places share the name: a village next to the place the user means. For "the Blausee near Bettmeralp" use location "Blausee" and near "Bettmeralp". Leave it out otherwise.
whenYes
locationYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden and does well: it explains that speed is the hourly mean, gust is the strongest one-second gust in that hour, and the 90th percentile is a cautious estimate rather than the maximum possible gust. It also describes the direction convention and the general return contents, though it does not explicitly state that the operation is read-only or mention any access constraints.

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 front-loaded with the tool purpose, then organized into semantics, Args, Returns, and Examples. The extra detail on gust percentile and direction convention is useful for correct interpretation, and no sentence is redundant.

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 forecast tool with no output schema and no annotations, the description is mostly complete: it explains the output dict contents, time validity, location types, and examples. The main omission is any mention of the optional near parameter for disambiguating shared place names, although that parameter is described in the schema.

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 only 33%, so the description must compensate for undocumented parameters. It adds strong meaning for location and when, including place types, Swiss local time format, full-hour requirement, and forecast horizon, but it never mentions the optional near parameter, which is documented only in the schema.

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 gives a specific verb and resource: get wind at a place and time, including mean speed, strongest gust, and direction. It is clearly distinct from sibling forecast tools by variable, but it does not explicitly contrast itself with alternatives such as forecast_hourly or current_conditions.

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 window and location expectations provide implied usage context, but the description never states when to choose forecast_wind over sibling tools such as forecast_hourly or current_conditions. There are no explicit when-not conditions or alternative-routing guidance.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 16 tool updatesv0.3.0
    • Addedcurrent_conditions
    • Addedcurrent_extremes
    • Removeddaily_forecast
    • Addedforecast_cloud_cover
    • Addedforecast_daily
    • Addedforecast_freezing_level
    • Addedforecast_hourly
    • Addedforecast_rain
    • Addedforecast_sunshine
    • Addedforecast_wind
    • Removedfreezing_level
    • Removedhourly_forecast
    • Removedrain_outlook
    • Removedsunshine_hours
    • Removedtotal_cloud_cover
    • Removedwind
  2. 13 tool updatesv0.2.0
    • Addeddaily_forecast
    • Addedfreezing_level
    • Addedhourly_forecast
    • Removedprecipitation_rate
    • Removedpressure_msl
    • Addedrain_outlook
    • Removedsnow_depth
    • Changedsunshine_hours6 fields changed
      • addedInput schema / properties / end
        Added value: +{
        +  "title": "End",
        +  "type": "string"
        +}
      • removedInput schema / properties / lead_time_end_swiss
        Removed value: -{
        -  "title": "Lead Time End Swiss",
        -  "type": "integer"
        -}
      • removedInput schema / properties / lead_time_start_swiss
        Removed value: -{
        -  "title": "Lead Time Start Swiss",
        -  "type": "integer"
        -}
      • addedInput schema / properties / start
        Added value: +{
        +  "title": "Start",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "location",
        -  "lead_time_start_swiss",
        -  "lead_time_end_swiss"
        -]New value: +[
        +  "location",
        +  "start",
        +  "end"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "number"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "sunshine_hoursOutput",
        -  "type": "object"
        -}New value: +null
    • Removedtemperature
    • Changedtotal_cloud_cover4 fields changed
      • removedInput schema / properties / lead_time_swiss
        Removed value: -{
        -  "title": "Lead Time Swiss",
        -  "type": "integer"
        -}
      • addedInput schema / properties / when
        Added value: +{
        +  "title": "When",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "location",
        -  "lead_time_swiss"
        -]New value: +[
        +  "location",
        +  "when"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "number"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "total_cloud_coverOutput",
        -  "type": "object"
        -}New value: +null
    • Removedtotal_rainfall
    • Addedwind
    • Removedwind_speed
  3. 9 tool updatesv0.1.0
    • First observedcurrent_date_and_time
    • First observedprecipitation_rate
    • First observedpressure_msl
    • First observedsnow_depth
    • First observedsunshine_hours
    • First observedtemperature
    • First observedtotal_cloud_cover
    • First observedtotal_rainfall
    • First observedwind_speed

TDQS

A4.4/5.0

Scored across 10 tools

Disambiguation5/5

The tools cleanly split by time granularity (daily, hourly, 3-hour rain blocks) and by weather variable (sunshine, wind, cloud cover, freezing level), with explicit guidance on when to use each. Minor rain overlap between forecast_daily, forecast_hourly, and forecast_rain is resolved by the descriptions.

Naming Consistency5/5

All tool names use snake_case and follow a predictable prefix pattern: forecast_* for forecast data and current_* for observations and the date/time helper. No mixed conventions or vague verbs appear.

Tool Count5/5

Ten tools is well scoped for a Swiss weather server covering forecasts and current observations. Each tool maps to a distinct forecast variable or observation type, so none feels redundant or missing from the count alone.

Completeness4/5

The surface covers core forecast variables plus current station and national observations, with a date/time helper for relative questions. Minor gaps remain, such as weather alerts/warnings and forecast humidity, pressure, or dew point, but common weather workflows are supported.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI models to access Swiss weather and climate data from MeteoSwiss, including current observations, forecasts, and warnings.
    6
    33 PyPI
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for querying MeteoSwiss open weather data, providing access to station data, forecasts, radar composites, and more via natural language.
    288 PyPI
    45
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides real-time weather forecasts, current conditions, and smart umbrella recommendations through MCP tools, backed by the Open-Meteo API.
    -