{
  "markdown": "# aemo-mcp\n\nmcp-name: io.ausdata/aemo-mcp\n\n[![PyPI](https://img.shields.io/pypi/v/aemo-mcp.svg)](https://pypi.org/project/aemo-mcp/)\n[![Python](https://img.shields.io/pypi/pyversions/aemo-mcp.svg)](https://pypi.org/project/aemo-mcp/)\n[![License](https://img.shields.io/pypi/l/aemo-mcp.svg)](https://github.com/Bigred97/aemo-mcp/blob/main/LICENSE)\n[![Tests](https://github.com/Bigred97/aemo-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/Bigred97/aemo-mcp/actions/workflows/test.yml)\n[![CodeQL](https://github.com/Bigred97/aemo-mcp/actions/workflows/codeql.yml/badge.svg)](https://github.com/Bigred97/aemo-mcp/actions/workflows/codeql.yml)\n[![Glama MCP server quality](https://glama.ai/mcp/servers/Bigred97/aemo-mcp/badges/score.svg)](https://glama.ai/mcp/servers/Bigred97/aemo-mcp)\n\n**Ask Claude about Australia's electricity market and get real, current\nnumbers** — 5-minute spot prices, regional demand, generation by fuel,\ninterconnector flows, rooftop solar — not \"I don't have access to that data.\"\nThis MCP server gives Claude (and other MCP clients like Cursor) live access\nto the [Australian Energy Market Operator (AEMO) NEMWEB](http://nemweb.com.au/Reports/Current/)\nfeeds, with curated mappings for the most-asked indicators.\n\n> **Hosted access?** For cross-source queries, webhooks, an always-on REST API, and a uniform response envelope across all 9 sources, see **[ausdata.io](https://ausdata.io)** — free tier available (500 calls/mo, no card).\n\nCompanion to [abs-mcp](https://github.com/Bigred97/abs-mcp) (ABS macro stats),\n[rba-mcp](https://github.com/Bigred97/rba-mcp) (RBA interest + FX rates),\n[ato-mcp](https://github.com/Bigred97/ato-mcp) (ATO tax + ACNC charity),\n[apra-mcp](https://github.com/Bigred97/apra-mcp) (banking + superannuation),\n[aihw-mcp](https://github.com/Bigred97/aihw-mcp) (health & welfare),\n[asic-mcp](https://github.com/Bigred97/asic-mcp) (companies + financial advisers),\nand [au-weather-mcp](https://github.com/Bigred97/au-weather-mcp) (Australian\nweather) — together they cover the most-asked Australian official data.\n\n## What you can ask\n\nOnce installed, your LLM can answer questions like:\n\n| Question | What the tool does |\n|---|---|\n| What's the current NSW spot price? | `latest(\"dispatch_price\", filters={\"region\":\"NSW1\"})` |\n| Did SA hit negative pricing in the last 24 hours? | `get_data(\"dispatch_price\", filters={\"region\":\"SA1\"}, start_period=…)` and filter `value < 0` |\n| Generation by fuel type right now in QLD | `latest(\"generation_scada\", filters={\"region\":\"QLD1\"})`, aggregated by fuel |\n| Weekly average dispatch price for VIC, last 4 weeks | `get_data(\"dispatch_price\", filters={\"region\":\"VIC1\"}, start_period=…)` |\n| Rooftop PV forecast for tomorrow | `get_data(\"rooftop_pv\", filters={\"section\":\"forecast\"}, start_period=\"<tomorrow>\")` |\n| What's the current flow across Heywood (VIC ↔ SA)? | `latest(\"interconnector_flows\", filters={\"interconnector\":\"V-SA\"})` |\n| Total NEM demand right now | `latest(\"dispatch_region\")` |\n\nEvery answer comes with the interval timestamp (AEMO market time, UTC+10),\nunits (MW, $/MWh), and a link back to the NEMWEB source. The MCP wraps\nNEMWEB's CSV/ZIP feeds and exposes them through 5 plain-English tools.\n\n## Install\n\n```bash\n# After publish:\nuvx --upgrade aemo-mcp\n\n# Local dev:\nuv pip install -e .\n```\n\n### Claude Desktop\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"aemo\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--upgrade\", \"aemo-mcp\"]\n    }\n  }\n}\n```\n\n> **Why `--upgrade`?** `uvx aemo-mcp` (without the flag) uses whatever wheel\n> is cached and never adopts new PyPI releases on its own. `--upgrade` makes\n> uvx check PyPI on each launch and pull a newer release if one exists.\n> Recommended for everyone except offline-first / pinned-version workflows.\n> To verify which version is currently serving you, look at the\n> `server_version` field on any `DataResponse`.\n\nIf you also have `rba-mcp` / `abs-mcp` installed, all servers run side-by-side.\nClaude disambiguates with the server prefix (`aemo:get_data`, `rba:get_data`,\n`abs:get_data`).\n\nFor local dev (pre-PyPI):\n\n```json\n{\n  \"mcpServers\": {\n    \"aemo\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"--directory\", \"/absolute/path/to/aemo-mcp\", \"aemo-mcp\"]\n    }\n  }\n}\n```\n\n### Cursor\n\nAdd to `~/.cursor/mcp.json` (or workspace `.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"aemo\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--upgrade\", \"aemo-mcp\"]\n    }\n  }\n}\n```\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `search_datasets(query, limit=10)` | Fuzzy-search the 7 curated NEM datasets by name, topic, or region. |\n| `describe_dataset(dataset_id)` | Schema, filters, source URL, cadence, and example queries for one dataset. |\n| `get_data(dataset_id, filters, start_period, end_period, format)` | Query data. Records / series / csv format. |\n| `latest(dataset_id, filters)` | Most recent 5-min or 30-min interval for time-series feeds. |\n| `list_curated()` | The 7 curated dataset IDs. |\n\n## Curated datasets\n\nThe 7 datasets cover ~95% of typical NEM analytic queries:\n\n| `dataset_id` | Cadence | Source | Use case |\n|---|---|---|---|\n| **`dispatch_price`** | 5 min | DispatchIS / DISPATCHPRICE | Current spot price per region; negative-pricing detection |\n| **`dispatch_region`** | 5 min | DispatchIS / DISPATCHREGIONSUM | Demand + scheduled + semi-scheduled gen + net interchange |\n| **`interconnector_flows`** | 5 min | DispatchIS / DISPATCHINTERCONNECTORRES | MW flow + losses across NEM interconnectors |\n| **`generation_scada`** | 5 min | Dispatch_SCADA | DUID-level MW (every unit), aggregable by fuel |\n| **`rooftop_pv`** | 30 min | ROOFTOP_PV/ACTUAL + FORECAST | Regional rooftop solar (actual + forecast) |\n| **`predispatch_30min`** | 30 min | PredispatchIS | 30-min forecast, ~40h horizon |\n| **`daily_summary`** | Daily | Daily_Reports | Yesterday's full data in one drop |\n\nUse `list_curated()` to enumerate, `describe_dataset(dataset_id)` to learn\nthe filters available on each.\n\n## Regions\n\nNSW1 (New South Wales), QLD1 (Queensland), SA1 (South Australia), TAS1\n(Tasmania), VIC1 (Victoria). Western Australia (WEM) and the Northern\nTerritory are not on the NEM and are out of scope.\n\n## Trust contract\n\nEvery `DataResponse` carries:\n\n- `source = \"Australian Energy Market Operator\"`\n- `attribution` — AEMO Copyright Permissions verbatim attribution string\n- `source_url` — the NEMWEB folder the data came from\n- `retrieved_at` — UTC timestamp of the fetch\n- `interval_start` / `interval_end` — period covered\n- `stale` — `True` if the latest interval is older than 2× the feed cadence\n- `server_version` — the wheel that served the call\n\n## Licence + attribution\n\nThis package is MIT-licensed (see [LICENSE](LICENSE)).\n\nThe **AEMO data** it fetches is published under AEMO's Copyright Permissions\npolicy: AEMO grants general permission to use AEMO Material for any purpose\n(commercial included) on the sole condition of accurate attribution of the\nrelevant material and AEMO as its author. See\n[https://aemo.com.au/privacy-and-legal-notices/copyright-permissions](https://aemo.com.au/privacy-and-legal-notices/copyright-permissions).\n\nEnd-users redistributing data fetched via this server must credit AEMO.\nThe canonical attribution string is on every `DataResponse.attribution`.\n\n## Worked examples\n\n**\"What's the current NSW spot price?\"**\n\n```\nlatest(dataset_id=\"dispatch_price\", filters={\"region\": \"NSW1\"})\n```\n\n→ `{\"records\": [{\"period\": \"2026-05-14T10:05:00+10:00\", \"value\": 87.5,\n\"dimensions\": {\"region\": \"NSW1\", \"metric\": \"rrp\"}, \"unit\": \"$/MWh\"}], ...}`\n\n**\"NSW spot price for the last 24 hours\"**\n\n```\nget_data(dataset_id=\"dispatch_price\", filters={\"region\": \"NSW1\"},\n         start_period=\"2026-05-13\", end_period=\"2026-05-14\")\n```\n\n**\"Did SA hit negative pricing in the last 24 hours?\"**\n\n```\nget_data(dataset_id=\"dispatch_price\", filters={\"region\": \"SA1\"},\n         start_period=\"<24h ago>\")\n```\n\nThen the LLM filters `value < 0` client-side.\n\n**\"Generation by fuel type right now in QLD\"**\n\n```\nlatest(dataset_id=\"generation_scada\", filters={\"region\": \"QLD1\"})\n```\n\n→ DUID-level rows with fuel attribution; the LLM aggregates by fuel.\n\n## How it works\n\n- **Live-fetch only.** No NEMWEB archives in the wheel. Every request goes\n  through the cache.\n- **Cache TTLs tuned per cadence.** 60s for 5-min feeds, 5min for 30-min\n  feeds, 1h forecasts, 24h daily archive. Timestamped historical files are\n  immutable in NEMWEB and cache effectively forever.\n- **In-flight request deduplication.** Concurrent callers for the same URL\n  share one HTTP request. Critical at 5-min cadence with many users.\n- **Latest-file detection** is purely lexicographic on the NEMWEB directory\n  listing — AEMO embeds the interval timestamp in every filename\n  (`PUBLIC_DISPATCHIS_YYYYMMDDHHmm_<seq>.zip`), so `max()` is enough.\n- **Multi-section CSV parser** handles AEMO's `I,/D,` row format where a\n  single ZIP holds several tables (DISPATCHPRICE, DISPATCHREGIONSUM,\n  DISPATCHINTERCONNECTORRES, etc.).\n\n## Development\n\n```bash\ngit clone https://github.com/Bigred97/aemo-mcp\ncd aemo-mcp\nuv sync --extra dev\nuv pip install -e .\nuv run pytest -q\n```\n\nRun live tests (hit NEMWEB):\n\n```bash\nuv run pytest -q -m live\n```\n\nZero-flake validation:\n\n```bash\nfor i in $(seq 1 10); do uv run pytest -q || break; done\n```\n\n## Sister MCPs (Australian Public Data portfolio)\n\n> **Want all 9 sources behind one REST API?** The hosted gateway at **[ausdata.io](https://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).\n\n- [abs-mcp](https://pypi.org/project/abs-mcp/) — Australian Bureau of Statistics (CPI, unemployment, ERP, building approvals)\n- [rba-mcp](https://pypi.org/project/rba-mcp/) — Reserve Bank of Australia (cash rate, lending stats, exchange rates)\n- [ato-mcp](https://pypi.org/project/ato-mcp/) — Australian Taxation Office (tax stats, ACNC charities)\n- [apra-mcp](https://pypi.org/project/apra-mcp/) — Australian Prudential Regulation Authority (banking, insurance, super)\n- [aihw-mcp](https://pypi.org/project/aihw-mcp/) — Australian Institute of Health and Welfare\n- [asic-mcp](https://pypi.org/project/asic-mcp/) — Australian Securities and Investments Commission (company registers)\n- **aemo-mcp** — this one. Australian Energy Market Operator (NEM dispatch, spot prices, generation).\n- [au-weather-mcp](https://pypi.org/project/au-weather-mcp/) — Open-Meteo (Bureau of Meteorology aggregator)\n- [wgea-mcp](https://pypi.org/project/wgea-mcp/) — Workplace Gender Equality Agency\n- [aus-identity](https://pypi.org/project/aus-identity/) — Postcode / state / ABN normalisation helper used by all sisters\n\n## Author\n\nBuilt by Harry Vass. Issues + PRs welcome at\n[github.com/Bigred97/aemo-mcp](https://github.com/Bigred97/aemo-mcp).\n",
  "bytes": 10896,
  "sha": "4e346cc93819286cfe09fcd1c4b7e7a9b60ca35a5cf05cc17ff436273ff35263",
  "repo_slug": "bigred97/aemo-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_ausdata_aemo_mcp_3cdb41d4/readme"
}