au-weather-mcp
This server gives LLMs live Australian weather and air-quality data via Open-Meteo (BOM-aggregated), with location resolution, forecasts, history, and multi-city comparisons.
Current weather: get real-time temperature, humidity, wind, rain, pressure for any Australian location via
latestForecasts & history: query 16-day forecasts or 80+ years of historical daily/hourly data via
get_weatherAir quality: current PM2.5, PM10, ozone, NO₂, SO₂, CO, and European/US AQI labels via
air_qualityMulti-location comparison: compare current weather across 2–10 places in one call via
compare_locationsLocation search & metadata: fuzzy-search curated locations (
search_locations), list all 45 curated IDs (list_curated), or get lat/lng, timezone, BOM station, and source URL (describe_location)Flexible input handling: accepts curated IDs, place names, state codes, postcodes, raw coordinates, and fuzzy typos, with
location_resolutionexplaining how each input was interpretedTrust contract: every response includes source URL, CC-BY attribution, retrieval timestamp, server version, and stale-cache flags
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@au-weather-mcpWhat's the weather like in Sydney right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
au-weather-mcp
mcp-name: io.ausdata/au-weather-mcp
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 |
| Fuzzy-search the 45 curated AU locations by name, state, or description. |
| Lat/lng, timezone, elevation, nearest BOM station, and the canonical Open-Meteo URL. |
| Current weather observation — temp, humidity, wind, rain, pressure. 15-min cache. |
| Time-series query. Auto-routes to historical archive (1940+) or forecast (today + 16 days). Daily or hourly granularity. |
| Current PM2.5, PM10, ozone, NO₂, SO₂, CO + European & US AQI with plain-English labels. (v0.4.0) |
| Side-by-side current weather for 2–10 locations in one call. Fans out concurrently. (v0.4.0) |
| 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 |
| Direct curated lookup (fast) |
Place name, any case |
| Normalised curated lookup |
State code or full name |
| State → capital alias |
Raw coordinates |
| Direct lat/lng (AU bbox enforced) |
AU postcode |
| OpenStreetMap Nominatim |
Any AU place name |
| Open-Meteo geocoding (AU-filtered, population-sorted) |
Typo of a curated name |
| 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) |
|
NSW regional (10) |
|
QLD regional (9) |
|
VIC regional (6) |
|
WA regional (5) |
|
SA regional (2) |
|
TAS regional (3) |
|
NT regional (2) |
|
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 |
| Open-Meteo forecast endpoint | Today + 16 days |
| Open-Meteo historical archive | 1940-01-01 onwards |
Trust contract
Every response carries:
source_url— the exact Open-Meteo URL the data came fromattribution— CC-BY 4.0 notice for both Open-Meteo and BOMretrieved_at— UTC timestamp when we fetchedserver_version— which wheel served the call (debugging staleuvxcaches)stale— true if we're serving cached data because upstream failed; comes withstale_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 liveThe 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 toolsair_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.
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Any Australian location. Same accepted shapes as latest(): curated ID, place name, state code/name, postcode, or 'lat,lng' coordinates. |
Output Schema
| Name | Required | Description |
|---|---|---|
| stale | No | |
| state | Yes | |
| source | No | |
| current | No | |
| latitude | Yes | |
| timezone | Yes | |
| longitude | Yes | |
| source_url | Yes | |
| attribution | No | |
| location_id | Yes | |
| retrieved_at | Yes | |
| stale_reason | No | |
| location_name | Yes | |
| location_input | Yes | |
| server_version | Yes | |
| location_resolution | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| locations | Yes | Two 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
| Name | Required | Description |
|---|---|---|
| metric | Yes | |
| source | No | |
| locations | Yes | |
| attribution | No | |
| retrieved_at | Yes | |
| server_version | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Any 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
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | Yes | |
| state | Yes | |
| latitude | Yes | |
| timezone | Yes | |
| longitude | Yes | |
| attribution | Yes | |
| description | No | |
| elevation_m | No | |
| open_meteo_url | Yes | |
| nearest_bom_station | No |
TDQS
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.
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.
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.
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.
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.
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 aggregateWhen 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.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | Inclusive end date in 'YYYY-MM-DD' format. Same range rules as start_date. | |
| location | Yes | Any Australian location. Same accepted shapes as latest(): curated ID, place name (any case), state code/name, or raw 'lat,lng' coordinates. | |
| start_date | No | Inclusive 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. | |
| granularity | No | Time 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
| Name | Required | Description |
|---|---|---|
| daily | No | |
| query | No | |
| stale | No | |
| state | Yes | |
| hourly | No | |
| period | No | |
| source | No | |
| current | No | |
| latitude | Yes | |
| timezone | Yes | |
| longitude | Yes | |
| source_url | Yes | |
| attribution | No | |
| location_id | Yes | |
| retrieved_at | Yes | |
| stale_reason | No | |
| location_name | Yes | |
| location_input | Yes | |
| server_version | Yes | |
| location_resolution | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Any 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
| Name | Required | Description |
|---|---|---|
| daily | No | |
| query | No | |
| stale | No | |
| state | Yes | |
| hourly | No | |
| period | No | |
| source | No | |
| current | No | |
| latitude | Yes | |
| timezone | Yes | |
| longitude | Yes | |
| source_url | Yes | |
| attribution | No | |
| location_id | Yes | |
| retrieved_at | Yes | |
| stale_reason | No | |
| location_name | Yes | |
| location_input | Yes | |
| server_version | Yes | |
| location_resolution | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return, ranked by relevance. | |
| query | Yes | Free-text search query. Matches against location IDs, names, and state codes. Case-insensitive. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.4.7- Added
air_quality - Added
compare_locations - Changed
describe_location3 fields changed- changed
Output schema / descriptionPrevious 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." - added
Output schema / properties / id / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Output schema / properties / id / typeRemoved value: -"string"
- Changed
get_weather1 field changed- added
Output schema / properties / location_resolution / enumAdded value: +[ + "curated", + "state_alias", + "raw_coordinates", + "postcode", + "geocoded", + "fuzzy_curated" +]
- Changed
latest1 field changed- added
Output schema / properties / location_resolution / enumAdded value: +[ + "curated", + "state_alias", + "raw_coordinates", + "postcode", + "geocoded", + "fuzzy_curated" +]
5 tool updates
v0.2.0- First observed
describe_location - First observed
get_weather - First observed
latest - First observed
list_curated - First observed
search_locations
TDQS
Scored across 7 tools
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.
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.
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.
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
Related MCP Connectors
Global weather via Open-Meteo: forecast, ERA5 archive, marine, air quality, geocoding, elevation.
Real-time weather conditions and multi-day forecasts via Open-Meteo — free, no API key required
Get current weather for any city and create images from your prompts. Streamline planning, reports…
Current weather and forecasts for any coordinates, backed b… — paid per call (x402/credits), 1 tools
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides 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.17361 npm1MIT
- AlicenseNot gradedqualityDmaintenanceProvides access to Australian weather data from the Bureau of Meteorology, enabling location search, forecasts, and current observations.2MIT
- FlicenseBqualityDmaintenanceProvides current weather conditions and forecasts for any location using the Open-Meteo API.2-
- AlicenseAqualityCmaintenanceProvides weather forecasts and geocoding lookup using free Open-Meteo APIs, enabling LLMs to query real-time weather and multi-day forecasts for any location.12 npmISC