Skip to main content
Glama
Bigred97

au-weather-mcp

au-weather-mcp

mcp-name: io.ausdata/au-weather-mcp

PyPI Python License Tests CodeQL Glama MCP server quality

Ask Claude about Australian weather and air quality and get real, current numbers — not "I don't have access to that data." This MCP server gives Claude (and other MCP clients like Cursor) live access to Australian weather + air-quality data via Open-Meteo, which aggregates Bureau of Meteorology observations under licence. 45 curated locations (every state capital + every regional centre over ~25k), postcode and place-name lookup, current observations, 16-day forecasts, 80+ years of historical data, and multi-location comparison.

Hosted access? For cross-source queries, webhooks, an always-on REST API, and a uniform response envelope across all 9 sources, see ausdata.io — free tier available (500 calls/mo, no card).

Companion to abs-mcp (ABS macro stats), rba-mcp (Reserve Bank), and ato-mcp (tax + charity register) — together the four cover Australia's most-asked public data.

What you can ask

Once installed, your LLM can answer questions like:

Question

Real response

What's the weather in Sydney right now?

Current temperature, humidity, wind, rain, pressure with the time stamped

Forecast for Melbourne next week?

7-day daily forecast with max/min temps and rain

How was Sydney summer in January 2020?

Historical daily data from Open-Meteo's archive (1940+)

Compare rainfall in Cairns vs Brisbane this year

Multi-location queries with provenance per row

Tropical Queensland weather today

Search fuzzy by region/state/description

Every response carries a CC-BY 4.0 attribution string and a direct Open-Meteo URL the agent can cite back to the user.

Related MCP server: au-weather-mcp

Why Open-Meteo (not BOM directly)

BOM publishes their own JSON/XML endpoints, but they actively 403 non-browser User-Agents and have no documented commercial-use path below their ~$5k/yr Registered User Service. Open-Meteo:

  • Aggregates BOM data under their existing licensing arrangements with national meteorological services

  • Free tier is explicit and generous; commercial use is $30/mo with public terms

  • Returns clean, versioned, schema-stable JSON with units alongside every value

  • Covers historical data back to 1940 via their archive endpoint

  • No API key, no User-Agent gymnastics

We attribute both Open-Meteo and BOM in every response.

Install

# After publish:
uvx au-weather-mcp

# Local dev:
uv pip install -e .

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "weather": {
      "command": "uvx",
      "args": ["--upgrade", "au-weather-mcp"]
    }
  }
}

The --upgrade flag makes uvx re-check PyPI on each Claude Desktop launch, so bug fixes propagate without manual cache refresh. Costs ~100ms at startup.

For a local checkout (before PyPI publish):

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/au-weather-mcp", "au-weather-mcp"]
    }
  }
}

Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "weather": {
      "command": "uvx",
      "args": ["--upgrade", "au-weather-mcp"]
    }
  }
}

Tools

Tool

What it does

search_locations(query, limit=10)

Fuzzy-search the 45 curated AU locations by name, state, or description.

describe_location(location)

Lat/lng, timezone, elevation, nearest BOM station, and the canonical Open-Meteo URL.

latest(location)

Current weather observation — temp, humidity, wind, rain, pressure. 15-min cache.

get_weather(location, start_date, end_date, granularity)

Time-series query. Auto-routes to historical archive (1940+) or forecast (today + 16 days). Daily or hourly granularity.

air_quality(location)

Current PM2.5, PM10, ozone, NO₂, SO₂, CO + European & US AQI with plain-English labels. (v0.4.0)

compare_locations([locs])

Side-by-side current weather for 2–10 locations in one call. Fans out concurrently. (v0.4.0)

list_curated()

All 45 supported location IDs.

Accepts almost any input shape

The location parameter on every tool resolves six different input shapes — agents and users don't need to know the curated key format:

Input shape

Example

Resolves via

Curated ID

"sydney", "gold_coast"

Direct curated lookup (fast)

Place name, any case

"Sydney", "Gold Coast", "GOLD COAST"

Normalised curated lookup

State code or full name

"NSW", "Queensland", "Western Australia"

State → capital alias

Raw coordinates

"-33.87,151.21"

Direct lat/lng (AU bbox enforced)

AU postcode

"2026" (Bondi Beach), "4217" (Gold Coast), "6160" (Fremantle)

OpenStreetMap Nominatim

Any AU place name

"Byron Bay", "Margaret River", "Toowoomba"

Open-Meteo geocoding (AU-filtered, population-sorted)

Typo of a curated name

"Sydny", "Melbourn"

High-confidence fuzzy match

Every response includes a location_resolution field with one of curated, state_alias, raw_coordinates, geocoded, or fuzzy_curated — so the agent (and the user) can see HOW the input was interpreted.

Curated locations

45 curated locations covering all 8 state/territory capitals plus 37 major regional centres (every AU population centre over ~25k). Anything outside the curated set still works via the place-name geocoder or postcode lookup.

Region

Locations

Capitals (8)

sydney · melbourne · brisbane · perth · adelaide · hobart · darwin · canberra

NSW regional (10)

newcastle · wollongong · tamworth · wagga_wagga · albury · orange · bathurst · dubbo · coffs_harbour · port_macquarie

QLD regional (9)

gold_coast · sunshine_coast · cairns · townsville · mackay · toowoomba · rockhampton · bundaberg · hervey_bay

VIC regional (6)

geelong · ballarat · bendigo · mildura · shepparton · warrnambool

WA regional (5)

broome · bunbury · geraldton · albany · kalgoorlie

SA regional (2)

mount_gambier · whyalla

TAS regional (3)

launceston · devonport · burnie

NT regional (2)

alice_springs · katherine

Coordinates are anchored to the canonical BOM observation point for each city (e.g. Sydney = Observatory Hill, Melbourne = Olympic Park) so cross-checking against BOM's official observations is straightforward. See src/au_weather_mcp/data/curated/locations.yaml for the full registry.

Worked examples

"What's the weather in Sydney right now?"

latest(location="sydney")

Returns:

{
  "location_id": "sydney",
  "location_name": "Sydney",
  "state": "NSW",
  "latitude": -33.8607,
  "longitude": 151.205,
  "timezone": "Australia/Sydney",
  "period": {"start": "2026-05-12T11:30", "end": "2026-05-12T11:30"},
  "current": {
    "time": "2026-05-12T11:30",
    "temperature_c": 19.7,
    "apparent_temperature_c": 18.1,
    "relative_humidity_pct": 67,
    "precipitation_mm": 0.0,
    "cloud_cover_pct": 43,
    "pressure_msl_hpa": 1034.5,
    "wind_speed_kmh": 18.4,
    "wind_direction_deg": 149,
    "wind_gusts_kmh": 43.2,
    "weather_code": 1,
    "weather_description": "Mainly clear"
  },
  "source": "Open-Meteo (aggregates Bureau of Meteorology data under licence)",
  "attribution": "Weather data by Open-Meteo.com (https://open-meteo.com), licensed under CC BY 4.0...",
  "source_url": "https://api.open-meteo.com/v1/forecast?latitude=-33.8607&...",
  "server_version": "<package version, e.g. 0.3.3>",
  "location_resolution": "curated",
  "location_input": "sydney"
}

"How was Sydney in January 2020?"

get_weather(
  location="sydney",
  start_date="2020-01-01",
  end_date="2020-01-31",
  granularity="daily"
)

Returns 31 DailyAggregate rows with temperature_max_c, temperature_min_c, precipitation_sum_mm, and weather descriptions per day.

"7-day Melbourne forecast, hourly detail"

get_weather(
  location="melbourne",
  start_date="2026-05-12",
  end_date="2026-05-19",
  granularity="hourly"
)

Returns 168 hourly rows.

Date formats

start_date and end_date must be YYYY-MM-DD. The server validates both the regex and the semantic date — 2024-13-40 raises a clean ValueError rather than silently failing.

Date range

Routes to

Coverage

end_date >= today - 5 days

Open-Meteo forecast endpoint

Today + 16 days

end_date < today - 5 days

Open-Meteo historical archive

1940-01-01 onwards

Trust contract

Every response carries:

  • source_url — the exact Open-Meteo URL the data came from

  • attribution — CC-BY 4.0 notice for both Open-Meteo and BOM

  • retrieved_at — UTC timestamp when we fetched

  • server_version — which wheel served the call (debugging stale uvx caches)

  • stale — true if we're serving cached data because upstream failed; comes with stale_reason

Sanity validators reject upstream values outside the plausible Australian range (temperature outside −30°C to +55°C, humidity outside 0-100%, pressure outside 850-1080 hPa). Rather than silently passing bad data to your agent, we raise an explicit validation error so the agent can degrade gracefully.

Development

git clone https://github.com/Bigred97/au-weather-mcp.git
cd au-weather-mcp
uv sync --extra dev
uv pip install -e .

# Unit tests (no network)
uv run pytest

# Live integration tests (hits Open-Meteo)
uv run pytest -m live

The SQLite cache lives at ~/.au-weather-mcp/cache.db. Current observations refresh every 15 minutes (matching Open-Meteo's update cadence), forecasts every 1 hour, historical never (a year-old day in the archive doesn't change). Delete the file to force a refresh.

Sister MCPs (Australian Public Data portfolio)

The portfolio runs side-by-side in any MCP client; Claude disambiguates via the server prefix (weather:latest vs abs:latest vs rba:latest vs ato:get_data).

Want all 9 sources behind one REST API? The hosted gateway at ausdata.io adds cross-source joins, full history, webhooks, and HMAC-signed responses on top of these MCPs — free tier (500 calls/mo, no card).

  • abs-mcp — Australian Bureau of Statistics (CPI, unemployment, ERP, building approvals)

  • rba-mcp — Reserve Bank of Australia (cash rate, lending stats, exchange rates)

  • ato-mcp — Australian Taxation Office (tax stats, ACNC charities)

  • apra-mcp — Australian Prudential Regulation Authority (banking, insurance, super)

  • aihw-mcp — Australian Institute of Health and Welfare

  • asic-mcp — Australian Securities and Investments Commission (company registers)

  • aemo-mcp — Australian Energy Market Operator (NEM dispatch, spot prices, generation)

  • au-weather-mcp — this one. Open-Meteo (Bureau of Meteorology aggregator).

  • wgea-mcp — Workplace Gender Equality Agency

  • aus-identity — Postcode / state / ABN normalisation helper used by all sisters

Data attribution

Weather data is provided by Open-Meteo, licensed under CC BY 4.0. The underlying observations include data from the Australian Bureau of Meteorology under Open-Meteo's licensing arrangement.

Postcode resolutions (when location_resolution == "postcode") additionally use OpenStreetMap via the Nominatim service, licensed under the Open Database Licence (ODbL). The OSM attribution is automatically appended to the response's attribution field for any postcode lookup, so redistribution is licence-compliant out of the box.

If you redistribute responses, credit Open-Meteo + BOM (always) and OpenStreetMap (when postcode lookup was used).

Changelog

See CHANGELOG.md for release history.

License

MIT — Harry Vass, 2026.

Available Tools

7 tools
air_qualityA

Return current air-quality readings for any Australian location.

Sourced from Open-Meteo's air-quality API, which merges Copernicus CAMS European + global air-composition models. Returns PM2.5, PM10, ozone, nitrogen dioxide, sulphur dioxide, carbon monoxide (all µg/m³), plus the European and US AQI indices with plain-English labels.

Especially useful during AU bushfire season (Oct–Mar) when smoke can push PM2.5 above safe levels across whole regions.

Examples: # Current Sydney air quality resp = await air_quality("sydney") # resp.current.pm2_5_ugm3 == 8.8 # resp.current.european_aqi == 21 # resp.current.european_aqi_label == 'Good' # resp.current.us_aqi == 39 # resp.current.us_aqi_label == 'Good'

# Bushfire smoke check for the Blue Mountains
resp = await air_quality("-33.7,150.3")

# Brisbane CBD via postcode
resp = await air_quality("4000")

When to use: - "Is the air clean enough to go for a run in ?" - Bushfire smoke or burn-off impact checks - Asthma / allergy planning - Long-term air quality monitoring (call periodically and chart)

Returns: AirQualityResponse with current populated (pollutants + AQI scales), plus location metadata, source_url, attribution, and server_version.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYesAny Australian location. Same accepted shapes as latest(): curated ID, place name, state code/name, postcode, or 'lat,lng' coordinates.

Output Schema

ParametersJSON Schema
NameRequiredDescription
staleNo
stateYes
sourceNo
currentNo
latitudeYes
timezoneYes
longitudeYes
source_urlYes
attributionNo
location_idYes
retrieved_atYes
stale_reasonNo
location_nameYes
location_inputYes
server_versionYes
location_resolutionYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description fully discloses the data source (Open-Meteo, Copernicus CAMS), units (µg/m³), and output structure (pollutants, AQI scales, plain-English labels). It also notes seasonal relevance and coordinates. No contradictions.

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 well-structured with a clear opening, source note, examples, use cases, and return summary. It is concise without unnecessary repetition, and key information is front-loaded.

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 the tool's simplicity (one parameter) and the presence of an output schema, the description is complete. It covers all aspects: purpose, usage, parameter, output, and context. No gaps.

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 coverage is 100% with a single 'location' parameter. The description adds significant meaning beyond the schema by providing multiple examples (city names, postcodes, coordinates) and explaining that it accepts curated IDs, place names, states, and lat,lng. This enriches semantic understanding.

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 explicitly states it returns current air-quality readings for Australian locations, listing specific pollutants and AQI indices. It distinguishes from sibling tools like get_weather and compare_locations by focusing solely on air quality.

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 'When to use' section provides concrete examples such as checking air quality before running, during bushfire season, for asthma planning, and long-term monitoring. It lacks explicit 'when not to use' or alternatives, but the guidance is clear.

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

compare_locationsA

Compare current weather across multiple Australian locations in one call.

Fans out concurrently via asyncio.gather, so all locations come back in roughly the time of a single call (after the cache is warm). Each location is independently resolved (curated / state / postcode / geocode / etc.) and independently fetched. If one location fails (e.g. geocoder can't find it), that row gets an error field while the rest still return.

Examples: # Capital-city dashboard resp = await compare_locations(["sydney","melbourne","brisbane","perth"]) for row in resp.locations: print(row.location_name, row.current.temperature_c)

# Tropical north today
resp = await compare_locations(["Cairns","Darwin","Townsville","Broome"])

# Mixed input shapes work
resp = await compare_locations(["sydney","NSW","2026","-33.87,151.21"])

When to use: - "Compare weather in " — the canonical use case - Build a multi-region dashboard in one tool call - Plan a holiday across regions

Returns: ComparisonResponse with one ComparisonRow per input location. Successful rows have current populated; failed rows have error.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationsYesTwo to ten Australian locations to compare side-by-side. Each entry accepts the same shapes as latest(): curated ID, place name, state, postcode, or 'lat,lng'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metricYes
sourceNo
locationsYes
attributionNo
retrieved_atYes
server_versionYes

TDQS

A4.6/5.0
Behavior5/5

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

Without annotations, the description carries full burden. It details concurrent fan-out via asyncio.gather, independent resolution of each location, error handling (failures yield error fields without affecting others), and caching behavior. This provides comprehensive insight into the tool's operation.

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 well-structured with clear sections (purpose, behavior, examples, when to use, returns). It is informative without being verbose, though slightly more conciseness could be achieved by trimming some repetitive elements.

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 the output schema exists, the description appropriately focuses on input usage and behavioral details. It covers single-parameter usage thoroughly, explains error behavior, and mentions return structure, making it self-contained for effective agent invocation.

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 100% and the schema already describes the 'locations' parameter well. The description adds value by providing concrete examples and clarifying that mixed input shapes (IDs, names, postcodes) are accepted, which enhances usability beyond the schema alone.

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 clearly states 'Compare current weather across multiple Australian locations in one call.' It specifies the verb (compare), resource (current weather), and scope (multiple Australian locations). This clearly distinguishes it from sibling tools like 'get_weather' which handles a single location.

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 'When to use' section provides clear use cases such as comparing weather in several cities, building multi-region dashboards, or planning holidays. It does not explicitly list alternatives, but the context strongly implies when to use this tool versus single-location tools like 'get_weather'.

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

describe_locationA

Return metadata for an Australian location — name, lat/lng, timezone, elevation, and (for curated locations) the nearest BOM station ID.

Accepts a wide range of input shapes for compatibility — see the location parameter description. The returned id is None for non-curated lookups (geocoded place names, raw coordinates) and a snake_case curated key when the input matched the curated set.

Examples: await describe_location("sydney") # → curated path await describe_location("Sydney") # → curated path (case-insensitive) await describe_location("NSW") # → state capital (Sydney) await describe_location("Margaret River") # → geocoded (Western Australia) await describe_location("-33.87,151.21") # → raw coordinates

When to use: - Before calling get_weather, to confirm coordinates and timezone - To cross-reference with BOM's own observation network (for curated) - To verify how the server resolved an ambiguous customer input

Returns: LocationDetail with id (or None), name, state, lat/lng, timezone, elevation, nearest BOM station ID (curated only), the Open-Meteo URL, and the CC-BY attribution.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYesAny Australian location, in any of these shapes: (1) curated ID like 'sydney', 'gold_coast'; (2) place name in any case like 'Sydney', 'Gold Coast', 'Margaret River', 'Byron Bay'; (3) state code or name like 'NSW', 'VIC', 'Queensland' (returns the state capital); (4) raw coordinates like '-33.87,151.21'. Case-insensitive throughout.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
stateYes
latitudeYes
timezoneYes
longitudeYes
attributionYes
descriptionNo
elevation_mNo
open_meteo_urlYes
nearest_bom_stationNo

TDQS

A4.6/5.0
Behavior4/5

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

No annotations are provided, so the description carries full burden. It discloses that input can be various shapes (curated IDs, place names, states, coordinates), explains the behavior of the returned 'id' (None for non-curated, snake_case for curated), and mentions case-insensitivity. It lacks an explicit read-only declaration but implies a safe lookup.

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 well-structured and concise: it starts with a clear purpose, then covers input flexibility, return behavior, examples, usage guidance, and return fields. Every sentence adds value without redundancy, achieving a balance between completeness and brevity.

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 that an output schema exists, the description appropriately covers the key return fields (LocationDetail with id, name, state, lat/lng, timezone, elevation, BOM station ID, Open-Meteo URL, attribution). It also addresses non-curated vs. curated behavior and provides usage context, making it complete for the tool's purpose.

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 100% (the 'location' parameter is well-documented). The description adds significant value beyond the schema by providing multiple examples illustrating different input shapes, explaining the relationship between input and output (especially the 'id' behavior), and clarifying case-insensitivity.

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 explicitly states 'Return metadata for an Australian location' with a specific verb and resource, listing fields like name, lat/lng, timezone, elevation, and BOM station ID. It clearly distinguishes itself from sibling tools (e.g., get_weather, search_locations) by focusing on metadata lookup, not weather or search.

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 includes a 'When to use:' section with three concrete scenarios: before get_weather, for BOM cross-reference, and to verify ambiguous input. While it doesn't explicitly state when not to use, the positive guidance is clear and sufficient for an agent to recognize appropriate contexts.

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

get_weatherA

Query weather over a date range. Routes to historical archive or forecast endpoint automatically based on the date range.

Routing logic: - end_date in the past (>= 5 days ago) → historical archive (1940+) - start_date in the future → forecast (today + 16 days max) - range straddles today → forecast with past_days set

Examples: # Historical: how was Sydney summer 2020? resp = await get_weather( "sydney", start_date="2020-01-01", end_date="2020-01-31", granularity="daily", ) # → 31 DailyAggregate rows with temp_max, temp_min, precip per day

# 7-day forecast for Melbourne, hourly detail
resp = await get_weather(
    "melbourne",
    start_date="2026-05-12",
    end_date="2026-05-19",
    granularity="hourly",
)
# → 168 hourly WeatherObservation rows

# Just today (omit both dates)
resp = await get_weather("brisbane")
# → today's daily aggregate

When to use: - Time-series queries (forecast over the next week, or historical comparison) - Multi-day weather analysis - Climate research and historical look-backs (decade-scale via archive)

Returns: WeatherResponse with either daily or hourly populated depending on granularity. Period bounds populated from actual returned data.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateNoInclusive end date in 'YYYY-MM-DD' format. Same range rules as start_date.
locationYesAny Australian location. Same accepted shapes as latest(): curated ID, place name (any case), state code/name, or raw 'lat,lng' coordinates.
start_dateNoInclusive start date in 'YYYY-MM-DD' format. Open-Meteo's historical archive covers 1940-01-01 onwards (5-day lag). Forecast covers today through today + 16 days.
granularityNoTime resolution of the returned series. 'daily' (default) returns one row per day with max/min/sum aggregates. 'hourly' returns one row per hour with point observations — useful for intraday detail but expect ~24× more records.daily

Output Schema

ParametersJSON Schema
NameRequiredDescription
dailyNo
queryNo
staleNo
stateYes
hourlyNo
periodNo
sourceNo
currentNo
latitudeYes
timezoneYes
longitudeYes
source_urlYes
attributionNo
location_idYes
retrieved_atYes
stale_reasonNo
location_nameYes
location_inputYes
server_versionYes
location_resolutionYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description fully discloses routing logic, date constraints (1940+ lag, 16-day forecast), and default behavior when dates are omitted. It does not cover rate limits or permissions, but provides enough detail for safe invocation.

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 well-structured with clear sections (routing logic, examples, when to use, returns). It is relatively lengthy due to examples, but front-loaded with purpose. Each part serves a purpose, though some repetition could be trimmed.

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?

The description is comprehensive for a tool with routing logic and date complexity. It covers all key behaviors, provides examples for different scenarios, and explains the return type. With an output schema existing, further detail is not needed.

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 100%, but the description adds significant value by explaining automatic routing based on date values, showing example calls, and clarifying granularity impact (e.g., ~24x more records for hourly). This exceeds the baseline of 3.

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 clearly states the tool queries weather over a date range and distinguishes it from sibling tools like 'latest' which handles current conditions. It specifies automatic routing between historical and forecast endpoints.

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 'When to use' section explicitly lists three use cases (time-series queries, multi-day analysis, climate research), but does not mention when to avoid using it or suggest alternatives like 'latest' for current conditions.

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

latestA

Return the current weather observation for any Australian location.

Wraps Open-Meteo's /forecast endpoint with current=... parameters and a 15-minute cache TTL (matches Open-Meteo's own update cadence). Use for "what's the weather right now?" — warm-cache latency < 100 ms.

Examples: resp = await latest("sydney") # curated, fast path resp = await latest("Sydney") # case-insensitive resp = await latest("Byron Bay") # geocoded resp = await latest("NSW") # state → Sydney resp = await latest("-33.87,151.21") # raw coordinates

The response's location_resolution field tells the agent how the input was interpreted ('curated', 'state_alias', 'geocoded', 'raw_coordinates', or 'fuzzy_curated').

When to use: - "What's the weather right now in ?" — canonical use case - Multi-city current-conditions dashboards (call once per place) - Anchoring agent conversations to live weather context

Returns: WeatherResponse with current populated, plus location metadata, resolution source, source_url, CC-BY attribution, and server_version.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYesAny Australian location. Accepted shapes: curated ID ('sydney'), place name in any case ('Sydney', 'Byron Bay', 'Margaret River'), state code or name ('NSW', 'Queensland' → returns the capital), or raw coordinates ('-33.87,151.21').

Output Schema

ParametersJSON Schema
NameRequiredDescription
dailyNo
queryNo
staleNo
stateYes
hourlyNo
periodNo
sourceNo
currentNo
latitudeYes
timezoneYes
longitudeYes
source_urlYes
attributionNo
location_idYes
retrieved_atYes
stale_reasonNo
location_nameYes
location_inputYes
server_versionYes
location_resolutionYes

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations, the description fully discloses behavior: 15-minute cache TTL, wrapper around Open-Meteo, latency, response fields like 'location_resolution', and attribution. No contradictions.

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 well-structured with sections for purpose, implementation, examples, usage, and returns. It is front-loaded and every sentence is informative, though slightly lengthy.

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 the low complexity (1 parameter, output schema exists), the description is comprehensive: covers caching, resolution, use cases, and return fields. No gaps.

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 100%, so baseline is 3. The description adds value with multiple examples and explains how inputs are interpreted (curated, geocoded, etc.), enhancing understanding beyond 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?

The description clearly states it returns current weather for any Australian location, with a specific verb and resource. It differentiates from siblings like 'get_weather' and 'air_quality' by focusing on current conditions and fast cache.

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 'When to use' section provides clear canonical use cases and practical scenarios. It does not explicitly state when not to use or name alternatives among siblings, but the examples and context effectively guide usage.

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

list_curatedA

List the 45 curated Australian location IDs supported by this MCP.

The curated set covers all 8 state/territory capitals plus 37 major regional centres. Any Australian place name outside this set still works via the place-name geocoder; the curated entries just get fast-path lookup (no network call) and appear in search_locations.

Coverage by state: - 8 capitals: sydney, melbourne, brisbane, perth, adelaide, hobart, darwin, canberra - NSW regional (10): newcastle, wollongong, tamworth, wagga_wagga, albury, orange, bathurst, dubbo, coffs_harbour, port_macquarie - VIC regional (6): geelong, ballarat, bendigo, mildura, shepparton, warrnambool - QLD regional (9): gold_coast, sunshine_coast, cairns, townsville, mackay, toowoomba, rockhampton, bundaberg, hervey_bay - WA regional (5): broome, bunbury, geraldton, albany, kalgoorlie - SA regional (2): mount_gambier, whyalla - TAS regional (3): launceston, devonport, burnie - NT regional (2): alice_springs, katherine

When to use: - You want to enumerate which locations have first-class support - You're building a UI / dashboard that needs the supported set up front - You want to plan a multi-location dashboard call

Returns: Sorted list of location IDs (currently 45). Adding a location is a YAML edit in src/au_weather_mcp/data/curated/locations.yaml.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description fully discloses behavior: fast-path lookup, inclusion in search_locations, and the YAML-based update process. It also specifies the return format (sorted list of 45 IDs).

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 well-structured with clear sections and bullet points, making it easy to read. It is somewhat lengthy but each sentence adds value. Minor redundancy could be trimmed, but overall it is 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?

Given the absence of parameters and presence of an output schema, the description covers purpose, usage, return value, and even internal maintenance. It is complete for the complexity of this simple list tool.

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 schema is trivially covered. The description adds no parameter details, which is acceptable as baseline for no parameters. The description does not need to add meaning beyond the empty 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?

The description clearly states the tool lists 45 curated Australian location IDs, with a specific verb and resource. It distinguishes from sibling tools like search_locations by noting that non-curated locations work via a geocoder, while curated entries get fast-path lookup.

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?

An explicit 'When to use' section provides three concrete scenarios: enumerating supported locations, building UIs, and planning multi-location dashboards. It also implies when not to use by referencing alternative tools for locations outside the curated set.

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

search_locationsA

Fuzzy-search the 45 curated Australian locations.

The curated set covers all 8 state/territory capitals plus 37 major regional centres (every AU population centre over ~25k). Anything outside the curated set still resolves via place-name geocoding or postcode lookup — see list_curated() for the full set.

Examples: results = await search_locations("sydney") # → [{id: 'sydney', name: 'Sydney', state: 'NSW', ...}]

results = await search_locations("nsw")
# → Newcastle, Wollongong, Sydney (all NSW locations)

When to use: - Discover the location ID for a city you know by name - Find all supported locations in a state - Verify whether a place is in the curated set before calling get_weather

Returns: List of LocationSummary (id, name, state, description), ranked by relevance.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of results to return, ranked by relevance.
queryYesFree-text search query. Matches against location IDs, names, and state codes. Case-insensitive.

Output Schema

ParametersJSON 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 full burden. It discloses fuzzy-matching behavior, coverage of curated set, resolution for non-curated places, and return format. It could note that it's read-only, but the examples imply no side effects.

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 well-organized with clear sections, bullet points, and examples. Every sentence is informative and earns its place, avoiding unnecessary fluff.

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 the output schema exists, the description appropriately summarizes return format (List of LocationSummary with id, name, state, description). It integrates well with sibling tools and provides enough context for an agent to decide when to use this tool.

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 100%, so baseline is 3. The description adds value by providing examples (e.g., 'tropical north') and clarifying matching behavior (case-insensitive, matches IDs, names, state codes), which goes beyond the schema's description.

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 clearly states the tool does 'Fuzzy-search the 45 curated Australian locations.' It specifies the verb and resource accurately and distinguishes from siblings like list_curated (which returns the full set) and describe_location.

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 includes a 'When to use' section with three specific use cases: discovering location ID, finding all locations in a state, and verifying if a place is curated. It also mentions alternatives for outside the curated set, referencing list_curated() and geocoding.

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. 5 tool updatesv0.4.7
    • Addedair_quality
    • Addedcompare_locations
    • Changeddescribe_location3 fields changed
      • changedOutput schema / description
        Previous value: -"Full metadata for one location — surface for describe_location."New value: +"Full metadata for one location — surface for describe_location.\n\n`id` is the curated key when the input resolved against the curated YAML\n(e.g. 'sydney', 'gold_coast'); None when the input was resolved via\npostcode lookup, raw coordinates, or Open-Meteo geocoding. Matching\n`WeatherResponse.location_id` semantics."
      • addedOutput schema / properties / id / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / id / type
        Removed value: -"string"
    • Changedget_weather1 field changed
      • addedOutput schema / properties / location_resolution / enum
        Added value: +[
        +  "curated",
        +  "state_alias",
        +  "raw_coordinates",
        +  "postcode",
        +  "geocoded",
        +  "fuzzy_curated"
        +]
    • Changedlatest1 field changed
      • addedOutput schema / properties / location_resolution / enum
        Added value: +[
        +  "curated",
        +  "state_alias",
        +  "raw_coordinates",
        +  "postcode",
        +  "geocoded",
        +  "fuzzy_curated"
        +]
  2. 5 tool updatesv0.2.0
    • First observeddescribe_location
    • First observedget_weather
    • First observedlatest
    • First observedlist_curated
    • First observedsearch_locations

TDQS

A4.5/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clear, distinct role: get_weather handles time-series, latest handles current conditions, air_quality handles pollutants, compare_locations handles multi-city current weather, and the three location tools each serve different discovery/metadata purposes. No two tools appear interchangeable.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern: get_weather, search_locations, describe_location, compare_locations, and list_curated. The exceptions are 'latest' and 'air_quality', which are still readable and unambiguous but break the pattern slightly.

Tool Count5/5

Seven tools is well-scoped for a weather-focused MCP. Each tool covers a distinct part of the domain—time-series weather, current conditions, air quality, comparison, and location lookup—without redundancy or bloat.

Completeness4/5

The tool surface covers the core Australian weather workflows end to end: location resolution, current observations, forecasts, historical data, air quality, and multi-location comparison. Minor gaps exist—such as historical air quality, weather alerts, or sunrise/sunset data—but these are workable omissions rather than dead ends.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides comprehensive access to Open-Meteo weather APIs, including forecasts, historical data, air quality, marine weather, and geocoding, enabling LLMs to retrieve weather information and location data.
    17
    361 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides access to Australian weather data from the Bureau of Meteorology, enabling location search, forecasts, and current observations.
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Provides weather forecasts and geocoding lookup using free Open-Meteo APIs, enabling LLMs to query real-time weather and multi-day forecasts for any location.
    1
    2 npm
    ISC