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 分

    请在仓库或注册中心条目中声明许可证。