ausecon-mcp-server 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ausecon_mcp_server-0.5.0/.github/workflows/ci.yml +42 -0
- ausecon_mcp_server-0.5.0/.github/workflows/release.yml +43 -0
- ausecon_mcp_server-0.5.0/.gitignore +11 -0
- ausecon_mcp_server-0.5.0/AGENTS.md +74 -0
- ausecon_mcp_server-0.5.0/CHANGELOG.md +145 -0
- ausecon_mcp_server-0.5.0/CLAUDE.md +74 -0
- ausecon_mcp_server-0.5.0/LICENSE +21 -0
- ausecon_mcp_server-0.5.0/PKG-INFO +412 -0
- ausecon_mcp_server-0.5.0/README.md +371 -0
- ausecon_mcp_server-0.5.0/docs/superpowers/plans/2026-04-12-rba-abs-mcp-server.md +61 -0
- ausecon_mcp_server-0.5.0/docs/variant_candidates.md +14 -0
- ausecon_mcp_server-0.5.0/examples/claude_desktop_config.json +13 -0
- ausecon_mcp_server-0.5.0/fastmcp.json +11 -0
- ausecon_mcp_server-0.5.0/pyproject.toml +49 -0
- ausecon_mcp_server-0.5.0/scripts/dump_variant_candidates.py +152 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/__init__.py +1 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/cache.py +29 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/catalogue/__init__.py +1 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/catalogue/abs.py +889 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/catalogue/rba.py +947 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/catalogue/resolver.py +333 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/catalogue/search.py +134 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/errors.py +17 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/models.py +61 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/parsers/__init__.py +1 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/parsers/abs_csv.py +100 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/parsers/abs_structure.py +72 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/parsers/rba_csv.py +131 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/providers/__init__.py +1 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/providers/_retry.py +43 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/providers/abs.py +105 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/providers/rba.py +113 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/server.py +245 -0
- ausecon_mcp_server-0.5.0/src/ausecon_mcp/validation.py +150 -0
- ausecon_mcp_server-0.5.0/tests/conftest.py +8 -0
- ausecon_mcp_server-0.5.0/tests/fixtures/abs_ana_agg_sample.csv +4 -0
- ausecon_mcp_server-0.5.0/tests/fixtures/abs_cpi_sample.csv +4 -0
- ausecon_mcp_server-0.5.0/tests/fixtures/abs_cpi_structure.xml +133 -0
- ausecon_mcp_server-0.5.0/tests/fixtures/rba_a2_sample.csv +14 -0
- ausecon_mcp_server-0.5.0/tests/fixtures/rba_g1_sample.csv +14 -0
- ausecon_mcp_server-0.5.0/tests/test_abs_provider.py +132 -0
- ausecon_mcp_server-0.5.0/tests/test_catalogue.py +127 -0
- ausecon_mcp_server-0.5.0/tests/test_parsers.py +88 -0
- ausecon_mcp_server-0.5.0/tests/test_rba_provider.py +155 -0
- ausecon_mcp_server-0.5.0/tests/test_repository_hygiene.py +84 -0
- ausecon_mcp_server-0.5.0/tests/test_resolver.py +214 -0
- ausecon_mcp_server-0.5.0/tests/test_server.py +348 -0
- ausecon_mcp_server-0.5.0/uv.lock +1624 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.10', '3.12']
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Verify public repository hygiene
|
|
21
|
+
shell: bash
|
|
22
|
+
run: |
|
|
23
|
+
test -f LICENSE
|
|
24
|
+
if rg -n "rba_abs_mcp|<your-repo-url>" README.md examples pyproject.toml; then
|
|
25
|
+
echo "Found stale public references"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
- uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.python-version }}
|
|
32
|
+
|
|
33
|
+
- uses: astral-sh/setup-uv@v6
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync --python ${{ matrix.python-version }} --extra dev
|
|
37
|
+
|
|
38
|
+
- name: Lint
|
|
39
|
+
run: uv run ruff check src tests
|
|
40
|
+
|
|
41
|
+
- name: Test
|
|
42
|
+
run: uv run pytest
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.12'
|
|
18
|
+
|
|
19
|
+
- name: Install build tooling
|
|
20
|
+
run: python -m pip install --upgrade build
|
|
21
|
+
|
|
22
|
+
- name: Build sdist and wheel
|
|
23
|
+
run: python -m build
|
|
24
|
+
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: dist
|
|
28
|
+
path: dist/
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
needs: build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: dist
|
|
40
|
+
path: dist/
|
|
41
|
+
|
|
42
|
+
- name: Publish to PyPI
|
|
43
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
uv sync --python 3.12
|
|
10
|
+
|
|
11
|
+
# Run all tests
|
|
12
|
+
uv run pytest
|
|
13
|
+
|
|
14
|
+
# Run a single test file
|
|
15
|
+
uv run pytest tests/test_catalogue.py
|
|
16
|
+
|
|
17
|
+
# Run a single test by name
|
|
18
|
+
uv run pytest tests/test_catalogue.py::test_search_catalogue_prefers_high_value_alias_matches
|
|
19
|
+
|
|
20
|
+
# Lint and format
|
|
21
|
+
uv run ruff check src tests
|
|
22
|
+
uv run ruff format src tests
|
|
23
|
+
|
|
24
|
+
# Run the MCP server (stdio mode)
|
|
25
|
+
uv run ausecon-mcp-server
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Architecture
|
|
29
|
+
|
|
30
|
+
This is a **FastMCP server** that wraps ABS (Australian Bureau of Statistics) and RBA (Reserve Bank of Australia) data APIs. The design is intentionally thin on the MCP surface and delegates all logic to internal layers.
|
|
31
|
+
|
|
32
|
+
### Layer structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
server.py → FastMCP tool definitions, AuseconService orchestrator
|
|
36
|
+
providers/ → Async httpx clients for each source (ABS, RBA), TTLCache wrappers
|
|
37
|
+
parsers/ → Pure functions: raw HTTP response text → normalised dicts
|
|
38
|
+
catalogue/ → Static curated dicts (abs.py, rba.py) + search.py ranking logic
|
|
39
|
+
models.py → SeriesDescriptor and Observation dataclasses; shared to_dict() helpers
|
|
40
|
+
cache.py → In-memory TTLCache (monotonic clock, per-instance, no persistence)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Data flow
|
|
44
|
+
|
|
45
|
+
1. MCP tool call → `AuseconService` method
|
|
46
|
+
2. `AuseconService` → `ABSProvider` or `RBAProvider` (checks TTLCache first)
|
|
47
|
+
3. Provider → httpx GET → raw CSV or XML response
|
|
48
|
+
4. Parser (`parse_abs_csv`, `parse_rba_csv`, `parse_abs_structure`) → `{metadata, series, observations}` dict
|
|
49
|
+
5. Optional post-fetch filtering (`_slice_observations`, `_filter_rba_payload`) for `last_n`, date ranges, series IDs
|
|
50
|
+
6. Result cached and returned as dict (not model instances)
|
|
51
|
+
|
|
52
|
+
### ABS vs RBA differences
|
|
53
|
+
|
|
54
|
+
- **ABS** uses SDMX REST (`data.api.abs.gov.au/rest`): structure endpoint returns XML, data endpoint returns CSV with `format=csvfile`.
|
|
55
|
+
- **RBA** serves static CSVs at `rba.gov.au/statistics/tables/csv/{table_id}-data.csv`; all filtering is done client-side after download.
|
|
56
|
+
|
|
57
|
+
### Tool injection pattern
|
|
58
|
+
|
|
59
|
+
`build_server()` in `server.py` creates the FastMCP instance and registers all tools as closures over an `AuseconService`. Tests inject mock providers directly into `AuseconService`, which is then passed to `build_server()`.
|
|
60
|
+
|
|
61
|
+
### Catalogue search scoring
|
|
62
|
+
|
|
63
|
+
`search_catalogue` in `catalogue/search.py` ranks entries by weighted keyword matching: exact alias match (+120) > exact name match (+100) > substring in name (+45) > substring in description (+25) > alias term overlap (+20 per term). Source filtering (`source="abs"` or `"rba"`) is applied before scoring.
|
|
64
|
+
|
|
65
|
+
### Response shape
|
|
66
|
+
|
|
67
|
+
All retrieval tools return `{metadata: {...}, series: [...], observations: [...]}`. Provenance fields (`retrieval_url`, `truncated`, `updated_after`) are added to `metadata` after parsing.
|
|
68
|
+
|
|
69
|
+
## Key conventions
|
|
70
|
+
|
|
71
|
+
- All provider methods are `async`; `list_tables` on `RBAProvider` is the only sync exception (no I/O).
|
|
72
|
+
- `asyncio_mode = "auto"` is set in `pyproject.toml` — no `@pytest.mark.asyncio` decorator needed.
|
|
73
|
+
- Tests use `respx` for HTTP mocking and fixture files in `tests/fixtures/`.
|
|
74
|
+
- Ruff target is Python 3.10 with `E, F, I, B, UP` rules and line length 100.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `ausecon-mcp-server` are recorded here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres
|
|
5
|
+
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.5.0] - 2026-04-17
|
|
8
|
+
|
|
9
|
+
Semantic-defaults and release-readiness release. Curated
|
|
10
|
+
`get_economic_series` concepts now resolve to concrete series by default, and
|
|
11
|
+
the public onboarding docs now cover the main local MCP clients.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `cash_rate_target`, `headline_cpi`, `trimmed_mean_inflation`, and
|
|
15
|
+
`gdp_growth` now resolve to narrowed default series instead of broad ABS
|
|
16
|
+
datasets or RBA tables.
|
|
17
|
+
- Curated catalogue entries for `CPI`, `ANA_AGG`, `a2`, and `g1` now include
|
|
18
|
+
populated default semantic variants used by the resolver.
|
|
19
|
+
- `README.md` now documents the actual `get_economic_series` inputs and
|
|
20
|
+
provides self-serve local setup instructions for Claude Desktop, Claude Code,
|
|
21
|
+
and Codex.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- ABS structure parsing now handles the current SDMX structure shape where
|
|
25
|
+
dimension metadata is nested under `ConceptIdentity` / `LocalRepresentation`
|
|
26
|
+
and includes `TimeDimension` entries.
|
|
27
|
+
- ABS CSV parsing now handles current upstream column names such as
|
|
28
|
+
`TIME_PERIOD`, `UNIT_MEASURE`, `UNIT_MULT`, and `OBS_STATUS`, rather than
|
|
29
|
+
only the older labelled column variants.
|
|
30
|
+
- Repository hygiene and behavioural tests now pin the `v0.5.0` semantic
|
|
31
|
+
shortcut contract and public onboarding text.
|
|
32
|
+
|
|
33
|
+
## [0.4.0] - 2026-04-17
|
|
34
|
+
|
|
35
|
+
Semantic resolver release. `get_economic_series` accepts variant / geography /
|
|
36
|
+
frequency and dispatches to narrowed ABS or RBA retrievals.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- `ausecon_mcp.catalogue.resolver` module exposing `resolve()`, `build_abs_key()`,
|
|
40
|
+
`ResolvedQuery`, and the `CURATED_SHORTCUTS` map (replaces the removed
|
|
41
|
+
`CURATED_SERIES` dict on `server`).
|
|
42
|
+
- ABS SDMX key construction that orders dimensions by `position`, composes from
|
|
43
|
+
literal dot-keys or `DIM=code;DIM=code` variant fragments, and validates each
|
|
44
|
+
emitted code against the live codelist.
|
|
45
|
+
- RBA variant resolution returns the variant's `rba_series_ids` as the
|
|
46
|
+
`get_rba_table` filter.
|
|
47
|
+
- `tests/test_resolver.py` — 19 unit tests covering unknown/ambiguous concepts,
|
|
48
|
+
unknown/unpopulated variants, frequency/geography validation, key composition,
|
|
49
|
+
and codelist mismatches.
|
|
50
|
+
- First populated variant: `g1.headline` → `["GCPIAG"]`. Additional variants are
|
|
51
|
+
populated progressively as `scripts/dump_variant_candidates.py` output is
|
|
52
|
+
reviewed.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- `get_economic_series` no longer rejects `variant` / `geography` / `frequency`;
|
|
56
|
+
it routes through the new resolver. Unknown values raise actionable errors
|
|
57
|
+
listing what is available.
|
|
58
|
+
- When a curated shortcut has no variant supplied and no explicit variant is
|
|
59
|
+
declared, the response is identical to v0.3.2 (whole dataset or whole table).
|
|
60
|
+
|
|
61
|
+
### Removed
|
|
62
|
+
- `CURATED_SERIES` dict and `_unsupported_semantic_options` helper from
|
|
63
|
+
`server.py`.
|
|
64
|
+
|
|
65
|
+
## [0.3.2] - 2026-04-17
|
|
66
|
+
|
|
67
|
+
Bridge release between the v0.3.x discovery work and the upcoming v0.4.0 semantic
|
|
68
|
+
resolver. No tool-surface changes.
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- `CHANGELOG.md` seeded from git history. Earlier releases are reconstructed from
|
|
72
|
+
commit history and the README version notes.
|
|
73
|
+
- `scripts/dump_variant_candidates.py` — dev-only helper that fetches each curated
|
|
74
|
+
RBA table and ABS dataflow structure, then writes a reviewable reference doc at
|
|
75
|
+
`docs/variant_candidates.md`. Used to hand-populate `variants[*].abs_key` and
|
|
76
|
+
`variants[*].rba_series_ids` in preparation for the v0.4.0 resolver.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
- `get_economic_series` now raises a version-neutral message when `variant`,
|
|
80
|
+
`geography`, or `frequency` are supplied. The previous message referenced
|
|
81
|
+
`v0.3.0` even in v0.3.1.
|
|
82
|
+
|
|
83
|
+
## [0.3.1] - 2026-04-16
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
- Support Python 3.10 by depending on `tomli` for pre-3.11 interpreters.
|
|
87
|
+
- Allow `pytest >= 9`.
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
- README now displays a release badge.
|
|
91
|
+
|
|
92
|
+
## [0.3.0] - 2026-04-14
|
|
93
|
+
|
|
94
|
+
Discovery release. Same six-tool surface, materially expanded catalogue and
|
|
95
|
+
deterministic search ranking.
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
- Expanded ABS catalogue to ~30 curated dataflows across prices, labour, national
|
|
99
|
+
accounts, activity, housing & construction, external sector, credit & finance,
|
|
100
|
+
and demographics.
|
|
101
|
+
- Expanded RBA catalogue to ~30 active tables (plus `discontinued: True` tagging
|
|
102
|
+
where applicable) across monetary policy, payments, money & credit, interest
|
|
103
|
+
rates, exchange rates, inflation, output & labour, external sector, and
|
|
104
|
+
household finance.
|
|
105
|
+
- `search_datasets` uses deterministic tiered scoring: exact id > exact alias >
|
|
106
|
+
exact name > full-term match > partial-term match > description match.
|
|
107
|
+
- Catalogue entries declare resolver schema fields (`frequencies`, `geographies`,
|
|
108
|
+
`variants`) that stay inert until the v0.4.0 resolver consumes them.
|
|
109
|
+
- Catalogue-coverage and search-ranking tests in `tests/test_catalogue.py`.
|
|
110
|
+
|
|
111
|
+
## [0.2.0] - 2026-04-12
|
|
112
|
+
|
|
113
|
+
Hardening release.
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
- `validation.py` — input validation for dataflow IDs, keys, ABS periods, ISO
|
|
117
|
+
dates, positive integers, series IDs, categories, and `updated_after`
|
|
118
|
+
timestamps. Applied at every tool boundary.
|
|
119
|
+
- `providers/_retry.py` — exponential backoff (0.1s → 0.2s → 0.4s, 3 attempts)
|
|
120
|
+
with 4xx-no-retry / 5xx-retry / timeout-retry behaviour.
|
|
121
|
+
- Provider-level error wrapping: `AuseconParseError` for malformed upstream
|
|
122
|
+
payloads, `AuseconUpstreamError` for HTTP failures.
|
|
123
|
+
- Per-provider TTLCache (3600s default) for raw upstream payloads.
|
|
124
|
+
- Support for ABS `a2` event-style tables.
|
|
125
|
+
|
|
126
|
+
## [0.1.0] - 2026-04-12
|
|
127
|
+
|
|
128
|
+
Initial public release.
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
- FastMCP server exposing six tools (`search_datasets`, `get_abs_data`,
|
|
132
|
+
`get_abs_dataset_structure`, `get_rba_table`, `list_rba_tables`,
|
|
133
|
+
`get_economic_series`).
|
|
134
|
+
- Async httpx providers for ABS SDMX REST and RBA statistical CSVs.
|
|
135
|
+
- Pure-function parsers for ABS SDMX CSV, ABS structure XML, and RBA CSVs.
|
|
136
|
+
- Initial curated catalogues for ABS and RBA, plus a four-concept
|
|
137
|
+
`CURATED_SERIES` semantic shortcut map.
|
|
138
|
+
|
|
139
|
+
[0.5.0]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.4.0...v0.5.0
|
|
140
|
+
[0.4.0]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.3.2...v0.4.0
|
|
141
|
+
[0.3.2]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.3.1...v0.3.2
|
|
142
|
+
[0.3.1]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.3.0...v0.3.1
|
|
143
|
+
[0.3.0]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.2.0...v0.3.0
|
|
144
|
+
[0.2.0]: https://github.com/AnthonyPuggs/ausecon-mcp-server/compare/v0.1.0...v0.2.0
|
|
145
|
+
[0.1.0]: https://github.com/AnthonyPuggs/ausecon-mcp-server/releases/tag/v0.1.0
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
uv sync --python 3.12
|
|
10
|
+
|
|
11
|
+
# Run all tests
|
|
12
|
+
uv run pytest
|
|
13
|
+
|
|
14
|
+
# Run a single test file
|
|
15
|
+
uv run pytest tests/test_catalogue.py
|
|
16
|
+
|
|
17
|
+
# Run a single test by name
|
|
18
|
+
uv run pytest tests/test_catalogue.py::test_search_catalogue_prefers_high_value_alias_matches
|
|
19
|
+
|
|
20
|
+
# Lint and format
|
|
21
|
+
uv run ruff check src tests
|
|
22
|
+
uv run ruff format src tests
|
|
23
|
+
|
|
24
|
+
# Run the MCP server (stdio mode)
|
|
25
|
+
uv run ausecon-mcp-server
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Architecture
|
|
29
|
+
|
|
30
|
+
This is a **FastMCP server** that wraps ABS (Australian Bureau of Statistics) and RBA (Reserve Bank of Australia) data APIs. The design is intentionally thin on the MCP surface and delegates all logic to internal layers.
|
|
31
|
+
|
|
32
|
+
### Layer structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
server.py → FastMCP tool definitions, AuseconService orchestrator
|
|
36
|
+
providers/ → Async httpx clients for each source (ABS, RBA), TTLCache wrappers
|
|
37
|
+
parsers/ → Pure functions: raw HTTP response text → normalised dicts
|
|
38
|
+
catalogue/ → Static curated dicts (abs.py, rba.py) + search.py ranking logic
|
|
39
|
+
models.py → SeriesDescriptor and Observation dataclasses; shared to_dict() helpers
|
|
40
|
+
cache.py → In-memory TTLCache (monotonic clock, per-instance, no persistence)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Data flow
|
|
44
|
+
|
|
45
|
+
1. MCP tool call → `AuseconService` method
|
|
46
|
+
2. `AuseconService` → `ABSProvider` or `RBAProvider` (checks TTLCache first)
|
|
47
|
+
3. Provider → httpx GET → raw CSV or XML response
|
|
48
|
+
4. Parser (`parse_abs_csv`, `parse_rba_csv`, `parse_abs_structure`) → `{metadata, series, observations}` dict
|
|
49
|
+
5. Optional post-fetch filtering (`_slice_observations`, `_filter_rba_payload`) for `last_n`, date ranges, series IDs
|
|
50
|
+
6. Result cached and returned as dict (not model instances)
|
|
51
|
+
|
|
52
|
+
### ABS vs RBA differences
|
|
53
|
+
|
|
54
|
+
- **ABS** uses SDMX REST (`data.api.abs.gov.au/rest`): structure endpoint returns XML, data endpoint returns CSV with `format=csvfile`.
|
|
55
|
+
- **RBA** serves static CSVs at `rba.gov.au/statistics/tables/csv/{table_id}-data.csv`; all filtering is done client-side after download.
|
|
56
|
+
|
|
57
|
+
### Tool injection pattern
|
|
58
|
+
|
|
59
|
+
`build_server()` in `server.py` creates the FastMCP instance and registers all tools as closures over an `AuseconService`. Tests inject mock providers directly into `AuseconService`, which is then passed to `build_server()`.
|
|
60
|
+
|
|
61
|
+
### Catalogue search scoring
|
|
62
|
+
|
|
63
|
+
`search_catalogue` in `catalogue/search.py` ranks entries by weighted keyword matching: exact alias match (+120) > exact name match (+100) > substring in name (+45) > substring in description (+25) > alias term overlap (+20 per term). Source filtering (`source="abs"` or `"rba"`) is applied before scoring.
|
|
64
|
+
|
|
65
|
+
### Response shape
|
|
66
|
+
|
|
67
|
+
All retrieval tools return `{metadata: {...}, series: [...], observations: [...]}`. Provenance fields (`retrieval_url`, `truncated`, `updated_after`) are added to `metadata` after parsing.
|
|
68
|
+
|
|
69
|
+
## Key conventions
|
|
70
|
+
|
|
71
|
+
- All provider methods are `async`; `list_tables` on `RBAProvider` is the only sync exception (no I/O).
|
|
72
|
+
- `asyncio_mode = "auto"` is set in `pyproject.toml` — no `@pytest.mark.asyncio` decorator needed.
|
|
73
|
+
- Tests use `respx` for HTTP mocking and fixture files in `tests/fixtures/`.
|
|
74
|
+
- Ruff target is Python 3.10 with `E, F, I, B, UP` rules and line length 100.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anthony P
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|