Australian Bureau of Statistics
This server gives LLMs live access to Australian Bureau of Statistics data via five core tools plus a release calendar, translating plain-English queries into SDMX for curated economic indicators.
Query current or historical data on 10 curated datasets (unemployment, CPI, GDP, building approvals, population, etc.) using plain-English filters like
region: "nsw"— no SDMX codes neededGet the latest observation for any indicator with a fast
latest()call (e.g., "current unemployment rate")Rank entities by a measure at the latest period via
top_n()(e.g., top 5 states by unemployment, bottom 3 industries by wage growth)Search and discover datasets via fuzzy text (
search_datasets), and inspect dimensions/valid values (describe_dataset)Retrieve data in multiple formats: records, grouped series, or CSV (
get_data)List all curated dataflows with plain-English support (
list_curated)Check the upcoming ABS release calendar (
release_calendar) to know what's published nextAccess ~1,200 raw ABS dataflows beyond the curated ones, just pass raw SDMX codes
Every response includes source URLs, units, periods, and CC-BY attribution for verifiable answers
abs-mcp
mcp-name: io.ausdata/abs-mcp
Ask Claude about the Australian economy 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 the ABS Data API, with curated mappings for the 10 most-asked Australian economic indicators.
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).

Behind the scenes it wraps SDMX 2.1, but you never see SDMX codes — just plain-English filters like region: "nsw" and measure: "unemployment_rate". Five tools, ten curated dataflows (Labour Force, CPI, Wage Price Index, Job Vacancies, Average Weekly Earnings, GDP / National Accounts, quarterly + annual Estimated Resident Population, Building Approvals, Lending Indicators), and 1,200+ other ABS dataflows accessible via raw codes.
Companion to rba-mcp (Reserve Bank of Australia — cash rate, FX, lending rates), ato-mcp (Australian Taxation Office — postcode-level personal tax, company tax by industry, corporate tax transparency, ACNC charity register), and au-weather-mcp (Australian weather — 21 curated locations + postcode/place-name lookup, current observations, 16-day forecasts, 80yr historical archive). Install all four for the full AU macro / regulator / tax / climate stack.
What you can ask
Once installed, your LLM can answer questions like:
Question | Real response (verified) |
What's the unemployment rate in NSW? | 4.27% (Mar 2026) |
AU annual CPI inflation? | 4.60% (Mar 2026) |
AU annual wage growth? | 3.40% (Q4 2025) |
Average weekly earnings in Australia? | $1,562 (Sep–Oct 2025) |
AU GDP quarterly growth? | 0.80% (Q4 2025) |
AU GDP per capita? | $24,900/qtr (Q4 2025) |
Job vacancies in NSW? | 101,200 (Q1 2026) |
Dwelling approvals in NSW? | 4,400/month (Mar 2026) |
New NSW housing loan commitments? | $19.7B (Q4 2025) |
Quarterly population of Australia? | 27.7M (Q3 2025) |
Every answer comes with the period, units, and a link back to the ABS source page. Comparisons and time-series queries work just as well — see Worked examples below.
Related MCP server: Reserve Bank of Australia
Install
# After publish:
uvx --upgrade abs-mcp
# Local dev install:
uv pip install -e .Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"abs": {
"command": "uvx",
"args": ["--upgrade", "abs-mcp"]
}
}
}Why
--upgrade?uvx abs-mcp(without the flag) uses whatever wheel is cached and never adopts new PyPI releases on its own — Claude Desktop's MCP child process keeps running the same wheel until you fully quit the app and refresh the cache by hand.--upgrademakes uvx check PyPI on each launch and pull a newer release if one exists. To verify which version is currently serving you, look at theserver_versionfield on anyDataResponse(added in 0.2.10).
For a local checkout (before PyPI publish):
{
"mcpServers": {
"abs": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/abs-mcp", "abs-mcp"]
}
}
}Restart Claude Desktop. The abs server appears in the tools panel with five tools.
Cursor
Add to ~/.cursor/mcp.json (or workspace .cursor/mcp.json):
{
"mcpServers": {
"abs": {
"command": "uvx",
"args": ["--upgrade", "abs-mcp"]
}
}
}Tools
Tool | What it does |
| Fuzzy-search ABS dataflow names. Returns the top matches. |
| Plain-English description of a dataflow's dimensions and values. |
| Query a dataflow with filters. Returns clean records (default), grouped series, or CSV. |
| Just the most recent observation(s) — wraps |
| Rank rows of a curated dataflow by a measure (e.g. |
| The ten dataflow IDs that have hand-curated plain-English support. |
Curated dataflows
For these curated dataflows, filters accepts plain-English values (e.g. "region": "nsw" instead of "REGION": "1"):
LF — Labour Force, monthly: employment, unemployment, participation by state/sex
CPI — Consumer Price Index, quarterly inflation (cat 6401.0 — the headline rate)
CPI_MONTHLY — Monthly CPI Indicator (cat 6484.0), full sub-category and per-city breakdown
WPI — Wage Price Index, quarterly wage growth by industry/sector/state
PPI_FD — Producer Price Index Final Demand, quarterly producer inflation
JV — Job Vacancies, quarterly labour demand by industry/sector/state
AWE — Average Weekly Earnings, half-yearly by industry/sector/state
ANA_AGG — National Accounts: GDP, GDP per capita, terms of trade, real income (Australia, quarterly)
ABS_ANNUAL_ERP_ASGS2021 — Estimated Resident Population, annual by state and sub-state geography
ERP_Q — Quarterly Estimated Resident Population, by state/sex/age
BUILDING_APPROVALS — Building Approvals (cat 8731.0), monthly by state/capital region, building type (houses / townhouses / apartments / total dwellings / non-residential) and measure (number / value). The property-economist "Building Index" series.
BA_GCCSA — Building Approvals, monthly by state/capital region and building type (raw GCCSA dimension surface;
BUILDING_APPROVALSis the cleaner alias)BA_LGA2024 — Building Approvals at the council (Local Government Area) level, monthly, ~570 councils — far more granular than BA_GCCSA's 8-capital geography. Pass
region=an LGA code (e.g."10050"Albury,"22750"Greater Geelong,"31000"Brisbane) for council-by-council approvals; defaults to Brisbane. Council-level only — for state / national totals useBUILDING_APPROVALS. Resolves to ABS's currentBA_LGA2025SDMX dataflow so the series stays live.BUILDING_ACTIVITY — Building Activity (cat 8752.0), quarterly dwelling units completed / commenced / under construction plus value of work, by state and building type. The trailing-reality counterpart to
BUILDING_APPROVALS— pair the two for approvals-vs-completions, and addNOMfor the supply-vs-migration story.NOM — Net Overseas Migration (cat 3412.0), financial-year arrivals/departures/net by state and age. The dominant rents-vs-migration series; publishes the headline net figure to the latest FY.
ABS_NOM_VISA_CY — NOM by visa subclass (calendar year, student / skilled / working holiday / permanent streams)
LEND_HOUSING — Lending Indicators, quarterly new housing loan commitments by purpose, lender, and state
HSI_M — Monthly Household Spending Indicator (ABS-blessed retail-trade replacement), COICOP category × discretionary × state
RT — Retail Trade (43-year historical series, ceased Jul 2025)
C21_G01_POA / C21_G02_POA / C21_G02_SA2 — Census 2021 selected characteristics and medians by postcode / SA2
Any other ABS dataflow still works — pass raw SDMX dimension IDs and codes.
Worked examples
Cross-source compatibility. All location filters accept canonical state codes (
"NSW"), full names ("New South Wales"), case-insensitive variants ("nsw"), ISO 3166-2 ("AU-NSW"), and 4-digit postcodes ("2000"→ NSW). Powered byaus-identity— the same input format works across abs-mcp, ato-mcp, apra-mcp, aihw-mcp, and asic-mcp.
"What's the current unemployment rate in NSW?"
Claude calls:
latest(dataset_id="LF", filters={"region": "nsw", "measure": "unemployment_rate"})Returns:
{
"dataset_id": "LF",
"dataset_name": "Labour Force",
"query": {"region": "nsw", "measure": "unemployment_rate"},
"period": {"start": "2026-03", "end": "2026-03"},
"unit": "Percent",
"records": [
{
"period": "2026-03",
"value": 4.27,
"dimensions": {"measure": "Unemployment rate", "region": "New South Wales", "sex": "Persons"},
"unit": "Percent"
}
],
"source": "Australian Bureau of Statistics",
"retrieved_at": "2026-05-11T03:14:22Z",
"abs_url": "https://www.abs.gov.au/statistics/labour/employment-and-unemployment/labour-force-australia"
}"Show me NSW housing approvals over the last two years"
get_data(dataset_id="BA_GCCSA", filters={"region": "nsw", "measure": "dwelling_units"}, start_period="2024")"Compare monthly CPI inflation in Sydney vs Melbourne"
get_data(dataset_id="CPI_MONTHLY", filters={"region": ["sydney", "melbourne"], "measure": "change_year"}, start_period="2023")(CPI itself publishes only the national weighted average at quarterly cadence; the monthly indicator carries per-city series.)
Period formats
ABS uses different period formats per dataflow. Pass start_period / end_period in the matching format:
Dataflows | Frequency | Format | Example |
LF, BA_GCCSA, BUILDING_APPROVALS | Monthly |
|
|
BUILDING_ACTIVITY | Quarterly |
|
|
CPI, WPI, PPI_FD, JV, ANA_AGG, LEND_HOUSING, ERP_Q | Quarterly |
|
|
CPI_MONTHLY, HSI_M | Monthly |
|
|
AWE | Half-yearly |
|
|
NOM (financial year), ABS_ANNUAL_ERP_ASGS2021 | Annual |
|
|
Verifying your install
The running MCP server reports its version on every DataResponse:
{ ..., "server_version": "0.2.11", ... }If you see a value below the latest on PyPI, your uvx cache is stale. Either switch to ["--upgrade", "abs-mcp"] in your config (recommended), or refresh manually:
uvx --refresh abs-mcp --help
# Then fully quit and relaunch Claude Desktop (Cmd+Q — window-close is not enough).Claude Desktop's MCP child processes are long-lived; refreshing the wheel cache does not restart an already-running server. Cold app launch is required.
Development
git clone https://github.com/Bigred97/abs-mcp.git
cd abs-mcp
uv sync --extra dev
uv pip install -e .
# Unit tests (no network)
uv run pytest
# Live integration tests (hits real ABS API)
uv run pytest -m liveThe SQLite cache lives at ~/.abs-mcp/cache.db. Catalogue refreshes every 24h, codelists every 7 days, data responses every hour, latest 15 minutes. Delete the file to force a refresh.
How it works
When you ask Claude an ABS question, it picks the right tool, fills in the curated filters, and calls the live ABS API. You see the reasoning + tool call inline:

Claude does the picking; this server does the SDMX translation, unit attribution, and clean response shaping. You don't have to know what M13.3.1599.20.1.M means — and neither does Claude.
How it differs from existing ABS MCP servers
The one existing community option (seansoreilly/abs) exposes a single query_dataset tool that passes raw SDMX through. This package offers semantic tools and curated mappings for the highest-value dataflows so an LLM can answer real questions without you needing to know what M13.3.1599.20.1.M means.
Sister MCPs (Australian Public Data portfolio)
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 — this one. 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 — Open-Meteo (Bureau of Meteorology aggregator)
wgea-mcp — Workplace Gender Equality Agency
aus-identity — Postcode / state / ABN normalisation helper used by all sisters
Changelog
See CHANGELOG.md for release history.
License
MIT — Harry Vass, 2026.
Available Tools
7 toolsdescribe_datasetA
Describe an ABS dataflow's filter dimensions, value codes, and source.
For curated dataflows (LF, CPI, ANA_AGG, AWE, BA_GCCSA, ERP_Q, JV, LEND_HOUSING, WPI, ABS_ANNUAL_ERP_ASGS2021), returns plain-English dimension names + curated value keys + the ABS source URL.
For other dataflows (~1,200 in total), returns raw SDMX dimensions and codelists translated to the same response shape — pass raw SDMX codes to get_data when querying these.
Examples: # Curated path — plain-English values detail = await describe_dataset("LF") # detail.dimensions = [{'name': 'region', 'values': [{'key': 'nsw', # 'sdmx_code': '1'}, {'key': 'vic', 'sdmx_code': '2'}, ...]}, ...]
# Raw path — full SDMX codelist
detail = await describe_dataset("ALC") # Apparent Consumption of Alcohol
# detail.is_curated == False; values are raw SDMX codesWhen to use: - Before calling get_data on an unfamiliar dataflow — to discover valid filter dim names and value keys - To get the canonical source URL on the ABS site - To see whether a dataflow is curated (plain-English) or raw SDMX
Returns: DatasetDetail with id, name, description, is_curated flag, the list of filter dimensions (name, sdmx_id, values), and abs_url.
Inputs: dataset_id (required). Returns: id, name, abs_url, dimensions, +3 more
get_dataA
Query an ABS dataflow and return observations.
Pass filters and/or a period range — unfiltered queries on large dataflows can return tens of thousands of observations.
Curated dataflows accept plain-English filter keys and values that
are translated to SDMX codes server-side. For example, on LF:
{"region": "nsw", "measure": "unemployment_rate"} resolves to
SDMX key M13.3.1599.20.1.M with hidden-dim defaults auto-applied.
Examples: # NSW unemployment monthly for 2024 resp = await get_data( "LF", filters={"region": "nsw", "measure": "unemployment_rate"}, start_period="2024", end_period="2024-12", ) # → resp.records[0]: period='2024-01', value=4.8, unit='Percent'
# Multi-state comparison
resp = await get_data(
"LF",
filters={"region": ["nsw","vic","qld"], "measure": "unemployment_rate"},
start_period="2024",
format="csv",
)
# → resp.csv contains 36 rows (3 states × 12 months)
# Australia quarterly CPI annual change
resp = await get_data(
"CPI",
filters={"region": "australia", "measure": "change_year"},
start_period="2020",
)When to use: - You want observations over a time range (use latest() for the most-recent only) - You want a multi-state or multi-measure comparison via list filters - You want a CSV for downstream charting / spreadsheet tools
Returns: DataResponse with records (list of {period, value, dimensions, unit}), unit (when homogeneous), period bounds, the resolved query echo, the ABS source URL, and the CC-BY 4.0 attribution string.
Inputs: dataset_id (required), format, filters, end_period, +1 more. Returns: csv, unit, query, stale, +13 more
latestA
Return the most recent observation(s) for a dataflow.
Wraps get_data with lastNObservations=1 and a 15-minute cache TTL (vs 1 hour for general data calls). Use this for "what's the current X?" questions — it's a cheap, fast call: warm-cache p50 ~22ms, cold-cache ~200ms.
Examples: # Latest NSW unemployment rate resp = await latest("LF", {"region": "nsw", "measure": "unemployment_rate"}) # → resp.records[0]: period='2026-03', value=4.61, unit='Percent'
# Latest Australia headline annual inflation
resp = await latest("CPI", {"region": "australia", "measure": "change_year"})
# → resp.records[0]: period='2026-Q1', value=4.6, unit='Percent'
# Latest Greater Sydney population
resp = await latest("ABS_ANNUAL_ERP_ASGS2021",
{"region": "greater_sydney", "region_type": "gccsa"})
# → resp.records[0]: period='2025', value=5640000, unit='Persons'When to use: - You want "the current value" of an indicator (most common workflow) - You're answering a "what's the unemployment rate?" style question - You want sub-50ms warm-cache latency for chat/agent integration
Returns: DataResponse with one most-recent observation per matched dimension combination. Same envelope as get_data.
Inputs: dataset_id (required), filters. Returns: csv, unit, query, stale, +13 more
list_curatedA
List the 10 ABS dataflow IDs with hand-curated plain-English support.
These are the dataflows where get_data accepts plain-English filter
keys ({"region": "nsw"}) and describe_dataset returns rich
human-readable metadata. All other ABS dataflows (~1,200) are still
accessible via get_data with raw SDMX dimension IDs and codes.
The 10 curated dataflows: - LF — Labour Force (unemployment, employment, participation) - CPI — Consumer Price Index (inflation) - WPI — Wage Price Index (wage growth) - AWE — Average Weekly Earnings - JV — Job Vacancies - BA_GCCSA — Building Approvals (by Greater Capital City) - LEND_HOUSING — Lending Indicators / Housing Finance - ANA_AGG — National Accounts (GDP) - ERP_Q — Estimated Resident Population (quarterly) - ABS_ANNUAL_ERP_ASGS2021 — Population (annual; supports SA2/SA3/SA4)
Example: ids = list_curated() # → ['ABS_ANNUAL_ERP_ASGS2021', 'ANA_AGG', 'AWE', 'BA_GCCSA', 'CPI', # 'ERP_Q', 'JV', 'LEND_HOUSING', 'LF', 'WPI']
When to use: - You want to know which dataflows have plain-English support - You're enumerating capabilities programmatically (e.g. building a UI) - You're showing users a "supported topics" list
Returns: Sorted list of dataflow IDs. Always 10 entries today.
Inputs: no named parameters. Returns: result
release_calendarA
Upcoming ABS publication schedule (data releases).
Scrapes the official ABS release calendar
(https://www.abs.gov.au/release-calendar/future-releases-calendar) and
returns each scheduled publication with its release timestamp, title,
reference period, and — when the title maps to a curated abs-mcp
dataset — the dataset_id an agent can plug into get_data or
latest. Curated mappings cover the 10 datasets in list_curated()
plus a handful of commonly-watched non-curated catalogues (Retail
Trade, International Trade in Goods, etc., where dataset_id stays
null but publication_id carries the ABS catalogue number).
release_at is returned with Sydney's local UTC offset (+10:00 AEST
or +11:00 AEDT) — what ABS publishes against. The DST switch is
naive (month-based), within an hour of correct at the changeover
boundary; downstream code should treat the offset as authoritative
rather than re-deriving local time.
Examples: # Next 7 days cal = await release_calendar(7) for r in cal.releases: print(r.release_at, r.title, r.dataset_id)
# Filter to curated datasets only
cal = await release_calendar(30)
curated_releases = [r for r in cal.releases if r.dataset_id]When to use: - Building a webhook / notification feed (ABS publishes at 11:30 AEST) - "What's next from the ABS?" agent answers - Pre-warming caches the morning of a known release
Returns:
ReleaseCalendarResponse — same envelope shape as rba-mcp's
release_calendar for portfolio interop. Sorted ascending by
release_at. stale=True + stale_reason is set when the live
HTML scrape failed and a cached payload was served past TTL.
Inputs: days_ahead. Returns: Upcoming ABS publications over a rolling horizon. Shape mirrors `rba-mcp.Releas…
search_datasetsA
Fuzzy-search ABS dataflow names, descriptions, and keywords.
Use this when you don't know the exact dataset ID. The 10 curated dataflows (LF, CPI, ANA_AGG, etc.) get a relevance boost so common queries like "unemployment" or "gdp" return the right dataset at rank #1 — not one of ABS's 800+ census tables that mention these keywords incidentally.
Examples: # Discover which dataflow answers "what's NSW unemployment?" results = await search_datasets("unemployment") # → [{id: 'LF', name: 'Labour Force', is_curated: True}, ...]
# Broader topic exploration
results = await search_datasets("housing", limit=5)
# → top 5 housing-related dataflows, curated firstWhen to use: - You have a natural-language question and need to identify the dataset - You want to discover what ABS publishes on a topic - You're not sure if a topic has a plain-English (curated) mapping yet
Returns: List of DatasetSummary (id, name, description, is_curated), ranked by relevance. Curated dataflows surface above raw SDMX dataflows.
Inputs: query (required), limit. Returns: result
top_nA
Return the N rows with the largest (or smallest) value of a measure.
Ranks across the most-recent available period only (uses lastNObservations=1 under the hood) so the result is a clean "top N entities at the latest period" view — not noisy historical highs.
This is the most common agent workflow: "show me the top 10 X by Y". Without this tool, an agent would call get_data, receive the full time series, and then sort/slice locally — wasting tokens and turns. top_n does the rank server-side and returns only the requested rows.
Examples: # 5 states with the highest current unemployment rate top_n("LF", "unemployment_rate", n=5)
# 10 GCCSAs with the largest populations
top_n("ABS_ANNUAL_ERP_ASGS2021", "estimated_resident_population",
n=10, filters={"region_type": "gccsa"})
# 3 industries with the lowest wage growth
top_n("WPI", "wage_price_index", n=3, direction="bottom")Returns:
DataResponse with at most n records, sorted by measure value
in the requested direction. Other fields (period, unit, attribution)
match a regular get_data call.
Inputs: measure (required), dataset_id (required), n, filters, +1 more. Returns: csv, unit, query, stale, +13 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: describe for metadata, get_data for historical data, latest for current, list_curated for curated IDs, release_calendar for schedule, search for discovery, top_n for ranking. No overlap in functionality.
Most tool names follow a verb_noun pattern (describe_dataset, search_datasets, list_curated), but get_data, top_n, and release_calendar use different forms. However, all are snake_case and descriptive, making them predictable.
Seven tools cover the essential operations for a statistics bureau server: metadata discovery, data retrieval, listing curated sources, release schedule, and search. The scope is neither too broad nor too narrow.
The tool set covers querying, latest values, ranking, metadata description, search, and release calendar. For a read-only statistical data portal, this is comprehensive; no obvious gaps for common workflows.
Maintenance
Related MCP Connectors
Australian economic data from the ABS, RBA, and APRA: CPI, GDP, cash rate, labour, and more.
Australian Bureau of Statistics (ABS) Data API MCP.
Macro data for AI agents: GDP, inflation, unemployment and more (World Bank, US BLS). No keys.
Macro data for AI agents: GDP, inflation, unemployment and more (World Bank, US BLS). No keys.
Related MCP Servers
- FlicenseCqualityBmaintenanceProvides access to the Australian Bureau of Statistics (ABS) Data API. This server allows AI assistants to query and analyze ABS statistical data.19-
- AlicenseAqualityBmaintenanceOne-call Australian economic data plumbing via the RBA — cited responses for rates and macro series, not a data broker.643 PyPIMIT
- AlicenseAqualityCmaintenanceEnables querying the ONS NOMIS labour market and census API from Claude, with tools for dataset discovery, dimension exploration, code resolution, and data fetching while guarding against silent truncation.6MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to browse, search, and query Australian Bureau of Statistics datasets through the ABS Data API, exposing dataflow discovery, dimension/code structure inspection, and SDMX dataKey-based retrieval of time-indexed observations with decoded labels. It can run as a hosted gateway endpoint or a local stdio server.99 npmMIT