ABS Data (observed)

io.github.SamJB123由 GitHub 帳號 SamJB123 發布v0.1.0更新於 Nov 9, 2026

Australian Bureau of Statistics data: 1,227 tables, offering only options confirmed to serve data

已驗證Streamable HTTP可網頁執行網頁搜尋與抓取資料與分析

概覽

AI 產生的概覽

遠端 MCP 伺服器,用於澳洲統計局資料:檢索 1,227 張 ABS 表、檢視維度並取得經驗證的觀測資料。

可以做什麼
依主題、地理層級或頻率檢索 ABS 統計表,並檢視某張表的維度、涵蓋日期與選項。在某個維度內依標籤查找選項代碼,例如地理維度中的某個郊區。依維度代碼選取並取得觀測資料,選取會在取數前向 ABS 驗證。在沙箱中對整份目錄執行 JavaScript,或對具備相同檢索、描述、選項與取數能力的用戶端執行,用於多表或多序列問題。
適用情境
當助理需要澳洲官方統計資料(如 CPI、人口普查、各地理層級序列),且只應提供確實能回傳資料的組合時適用。也適合跨多張表或多條序列、用固定查詢步驟較難回答的問題。
執行需求
遠端 streamable HTTP 端點;未宣告任何套件、帳號、API 金鑰或標頭。需要能存取該端點及其背後的 ABS 資料。依用戶端位址限流:整體每分鐘 600 次請求,取數每分鐘 120 次,沙箱執行每分鐘 20 次。
安裝前請注意
取數會即時呼叫 ABS,並計入每分鐘 120 次限額;超限會回傳錯誤或 HTTP 429。沙箱執行工具會執行 JavaScript,其中目錄沙箱無網路,另一個僅暴露 ABS 用戶端。查詢與選取會傳送到遠端服務並轉送給 ABS。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 ABS Data (observed),將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.SamJB123%2Fabs-data/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "abs-data-observed": {
      "type": "http",
      "url": "https://abs-data-front-door.aicolab.workers.dev/mcp"
    }
  }
}

README

ABS Data API — cartography and front door

This project measured what the Australian Bureau of Statistics Data API actually serves — every dataflow, by retrieval — and exposes the result as a typed front door: an MCP server and an HTTP API that only ever offer what exists.

[The ABS Data API cartography: unmasking the 4.21% reality — a comic-style map of the findings and the front door]

Front doorhttps://abs-data-front-door.aicolab.workers.dev
Add to claude.ai / any MCP client as a connectorhttps://abs-data-front-door.aicolab.workers.dev/mcp (registry name io.github.AI-CoLab/abs-data)
MCP (2026-07-28, stateless) — 4 fixed verbs + Code Mode search/execute, resources, promptshttps://abs-data-front-door.aicolab.workers.dev/mcp
RPC door (Cap'n Web; what @abs/sdk speaks — HTTP batch or WebSocket)https://abs-data-front-door.aicolab.workers.dev/rpc
HTTP APIhttps://abs-data-front-door.aicolab.workers.dev/api/tables
Scalar referencehttps://abs-data-front-door.aicolab.workers.dev/api/docs
Corrected OpenAPIhttps://abs-data-front-door.aicolab.workers.dev/api/openapi.json
The menu as one documenthttps://abs-data-front-door.aicolab.workers.dev/api/catalogue.json
Live browsable cataloguehttps://abs-data-front-door.aicolab.workers.dev/catalogue
Static snapshot (claude.ai artifact)https://claude.ai/code/artifact/d0635dee-5cce-40dd-bfa2-7ab7dd03e5bd

What was found

  • 621,536,714 series exist across 1,227 dataflows. ABS's metadata implies 14,761,557,818 — a density of 4.21%, overstated 23.8×.
  • The per-dimension metadata is exact: every advertised option exists, and nothing real is unadvertised. The entire overstatement is combinatorial.
  • 81.0% of series sit in flows whose sparsity is principled and verified in the keys — almost entirely hierarchical geography encoded as separate dimensions (STATE is a function of REGION in 664 flows). The remaining 19% is not reducible to a single-dimension dependency.
  • detail=serieskeysonly — the endpoint that should answer "what exists" — is broken (HTTP 200, malformed JSON). Eight of fifteen documented behaviours do not conform. See reports/.

DESIGN.md is the full record: verified API findings, every decision and why, and the corrections made along the way.

Layout

packages/schema      Drizzle schema (declared vs observed, never joined), shared CSV/period parsingpackages/crawler     structural crawl, observed probe, conformance suite, sizingpackages/catalogue   delta report, sparsity analysis, contract generator, OpenAPI emitter, artifactpackages/contract    the corrected contract: stable Zod verbs + generated tables/options (per crawl)packages/worker      the front door: MCP door (SDK v2) + HTTP door (oRPC + Scalar) + RPC door (Cap'n Web) on one Workerpackages/sdk         @abs/sdk — typed TypeScript client over the RPC door (connect(), invalidSelectionFromError())reports/             delta.md/json, sparsity.md/json, openapi.json, abs-report-draft.mddata/                local SQLite catalogue (~400GB), raw archive, D1 import SQL — not committed

Running it

sh
pnpm installpnpm db:migrate                       # local SQLite at data/abs-catalogue.sqlite
pnpm crawl:structural                 # 7 bulk requests, ~1 minutepnpm crawl:probe -- '--key-values=*'  # every dataflow by retrieval; ~24h, 20GB heap for the giantspnpm report:delta && pnpm report:sparsitypnpm generate:contract                # -> packages/contract/src/generated, data/d1/*.sqlpnpm --filter @abs/catalogue emit:openapi
cd packages/workernpx wrangler d1 execute abs-catalogue --local --file=../../data/d1/00-schema.sql   # then each data filenpx wrangler devABS_MCP_URL=http://localhost:8787/mcp npx tsx test/protocol.ts                     # ~50 checks, all doorspnpm --filter @abs/sdk example                                                     # the SDK against productionABS_URL=http://localhost:8787 npx tsx test/limits.ts                               # rate limits (spends a minute's budget)

Rate limits, per client address: 600 requests/min overall; 120/min for data pulls (each is a live ABS call); 20/min for Code Mode execute. Over the limit, HTTP doors answer 429 with Retry-After; an MCP tool call gets a tool error.

Using the SDK from TypeScript:

ts
import { connect, invalidSelectionFromError } from "@abs/sdk";
const abs = connect(); // https://abs-data-front-door.aicolab.workers.dev/rpcconst [hits, cpi] = await Promise.all([          // one HTTP batch  abs.searchTables({ query: "cpi rent", limit: 3 }),  abs.describeTable("CPI"),]);try {  const data = await abs.getData({ table: "CPI", select: { REGION: "Sydney", INDEX: "10001" }, lastN: 4 });} catch (err) {  const invalid = invalidSelectionFromError(err); // typed: reason, dimension, validOptions from observation}

The probe is resumable: rerunning skips flows already recorded as complete. For the largest census flows run with NODE_OPTIONS=--max-old-space-size=20480.

Gotcha: wrangler keys the local D1 state by database_id. Changing the id in wrangler.toml (e.g. after d1 create) gives wrangler dev a fresh, empty local database — re-run the local import.

Principles

  • Observed-only. Declared metadata steers the crawler and feeds the defect report; it never enters what a caller sees. Availability is empirical: observed options from the catalogue, exact combination checks live against ABS's availableconstraint (which agrees with the probe on every dimension of every flow).
  • One contract, derived doors. Every crawl regenerates one contract; the MCP verbs, the HTTP routes, the OpenAPI document and the docs all read or render it. Nothing hardcodes the surface, so nothing drifts.
  • Only calls that return data. A selection is verified before it is forwarded; an invalid one comes back with the observed valid options — as an MRTR input_required on MCP, a typed 422 on HTTP.

來源:README.md,提交 3f57e8d

工具

6

search_tables

Search ABS tables

Find ABS statistical tables (dataflows) by topic words, geography level or frequency. Matches table names, topics and dimension names, and also option labels inside dimensions — a search for 'rent' finds CPI through its INDEX option 'Rents' and reports the match in matchedOptions. Census tables published at several geography levels are collapsed to one result with familyGeographies listing the others (use the geography filter to pick one). Every result is confirmed to serve data — nothing here comes from documentation alone. Start here, then describe_table.

輸入參數limitqueryfrequencygeography

describe_table

Describe a table

A table's dimensions in key order, its coverage dates, and its observed options. Dimensions with up to 64 options list them inline with labels; larger ones (geography, occupations) say how many and are searchable with search_options.

輸入參數table必填

search_options

Search a dimension's options

Find option codes by label text within one dimension of one table — e.g. a suburb name in a geography dimension. Returns codes to use in get_data's select.

輸入參數limitquery必填table必填dimension必填

get_data

Get data

Fetch observations. `select` maps dimension ids to option codes or labels (several allowed); omitted dimensions match everything. The selection is verified live against ABS before fetching, so a call that succeeds always returns real data. Returns up to maxRows observations (default 500, most recent 12 periods per series unless a period range is given), a summary, and the URL for the complete pull. If an option or combination does not exist you are asked to choose from the valid ones.

輸入參數lastNtable必填firstNselectmaxRowsendPeriodstartPeriod

execute

Fetch and analyse data by writing code

Run JavaScript in an isolated sandbox whose only capability is `abs`, a client with the same four verbs as this server (searchTables, describeTable, searchOptions, getData) and the same guarantees: every selection is verified against ABS before fetching. Use it for multi-series or multi-table analysis — fetch several series, compute growth rates, rank capitals, join tables — and `return` only the computed result, so large payloads never reach the conversation. No network beyond `abs`. Budgets: 10s CPU, 50 calls, 25s wall clock, 200KB result. Your code runs inside an async function; use `await`; console.log is captured. // The `abs` object available in execute(): interface Abs { searchTables(input: { query?: string; geography?: string; frequency?: "A"|"S"|"Q"|"M"|"W"|"D"; limit?: number }): Promise<{ results: TableSummary[]; total: number }>; describeTable(table: string): Promise<{ table: TableSummary; dimensions: { id: string; position: number; optionCount: number; options?: { code: string; label: string|null }[] }[]; keyFormat: string }>; searchOptions(input: { table: string; dimension: string; query: string; limit?: number }): Promise<{ options: { code: string; label: string|null; parent?: string|null }[]; total: number }>; getData(input: { table: string; select?: Record<string, string|string[]>; startPeriod?: string; endPeriod?: string; lastN?: number; firstN?: number; maxRows?: number }): Promise<{ key: string; rows: { series: string; period: string; value: number|null; unit?: string|null }[]; rowsReturned: number; truncated: boolean; seriesMatched: number; fullDataUrl: string }>; } interface TableSummary { id: string; name: string|null; seriesCount: number; frequencies: string[]; coverage: { from: string|null; to: string|null }; dimensions: string[]; family: string|null; geography: string|null; matchedOptions?: { dimension: string; code: string; label: string|null }[] } // getData throws an Error whose message is JSON: { reason, dimensi

輸入參數code必填

版本歷史

1
  1. v0.1.0最新Sep 16, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。