Skip to main content

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.

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.

Release files for au-weather-mcp 0.4.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for au-weather-mcp 0.4.10
File Size Uploaded
au_weather_mcp-0.4.10.tar.gz 159.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for au-weather-mcp 0.4.10
File Interpreter ABI Platform
au_weather_mcp-0.4.10-py3-none-any.whl Python 3 none any Details

Total release size: 205.2 kB

Release files / au_weather_mcp-0.4.10.tar.gz

Download URL au_weather_mcp-0.4.10.tar.gz
Size 159.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7d5c501f16a5286442b966c7e6b9b7dfa3e1eeb0a0b530b1ff03d69710306a9f
BLAKE2b-256 checksum
How to use checksums
e989287dddc14729444de3dfbb32d41793309496050d06a000b6b6501ecc0572
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release files / au_weather_mcp-0.4.10-py3-none-any.whl

Download URL au_weather_mcp-0.4.10-py3-none-any.whl
Size 45.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e5894d34d008345767e17e75e51c49a835d40830323eb82f1c904125264b8ad7
BLAKE2b-256 checksum
How to use checksums
09db0d6cb0d345017ec0dc35b4fe81956429a430d6f2b93bd9cd9b78fad6a841
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.10 This release

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page