Skip to content

taxcode changelog

io.github.christianclaudio/taxcode

16 changes recorded. MCP Harbor re-reads this listing from the official registry every six hours and asks the live server what it exposes, and keeps what changed between one look and the next.

  • server.json 1 field changed
    version
    1.3.0 1.4.0

  • server.json 1 field changed
    version
    1.2.0 1.3.0

  • AGENTS.md +3 −3

    https://raw.githubusercontent.com/christianclaudio/mcp-server-taxcode/HEAD/AGENTS.md

    − - `src/taxcode_mcp/paging.py` — hard response cap (32,000 characters of JSON) and paging for the statutes tools: `statutes_lookup_statute` pages long text (`page_cursor` / `next_cursor`), search and publications clamp `limit` to 1..25 items per call (`offset` / `next_offset`), and the `taxcode://statutes/{jurisdiction}/{section}{?page_cursor}` resource returns the same 8,000-character pages, ending a non-final page with the full URI of the next one (`...?page_cursor=`). The template has no `stat−    - Runtime dependencies install from `uv.lock`, so the image runs the versions CI tests: the builder installs uv from `docker/uv-bootstrap.txt` (hash-pinned, `--require-hashes`, into `/tmp/uv` outside the venv, so the runtime image has no uv), runs `uv export --locked --no-dev --no-emit-project --format requirements.txt` (base dependencies only, a hash for every package, and the build fails if `uv.lock` is stale), installs that file with pip in hash-checking mode, then installs the project wit− CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.11–3.14, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing, checks its MCP server-name label against `server.json`, and checks that the builder stage fails at its `ca-certificates` floor check, before any pip step, when the floor is above the installed version), and `drift-check` (the same OpenAPI drift check as its own job; scheduled and manual runs only)). It runs on pushes an+ - `src/taxcode_mcp/paging.py` — hard response cap (32,000 characters of JSON) and paging for the statutes tools: `statutes_lookup_statute` pages long text (`page_cursor` / `next_cursor`), search and publications clamp `limit` to 1..25 items per call (`offset` / `next_offset`), and the `taxcode://statutes/{jurisdiction}/{section*}{?page_cursor}` resource returns the same 8,000-character pages, ending a non-final page with the full URI of the next one (`...?page_cursor=`). The template has no `sta+    - Runtime dependencies install from `uv.lock`, so the image runs the versions CI tests: the builder installs uv from `docker/uv-bootstrap.txt` (hash-pinned, `--require-hashes`, into `/tmp/uv` outside the venv, so the runtime image has no uv), runs `uv export --locked --no-dev --no-emit-project --format requirements.txt` (base dependencies only, a hash for every package, and the build fails if `uv.lock` is stale), installs that file with pip in hash-checking mode, then installs the project bui+ CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.11–3.14, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing, checks its MCP server-name label against `server.json`, checks that the runtime image has the project and none of the build-only packages (runtime dependencies such as `packaging` stay), checks that the image answers `initialize` and `tools/list` over stdio with no network, and checks that the builder stage fails at its

  • server.json 1 field changed
    version
    1.1.0 1.2.0

  • AGENTS.md +14 −4

    https://raw.githubusercontent.com/christianclaudio/mcp-server-taxcode/HEAD/AGENTS.md

    − - `.github/workflows/` — `ci.yml`, `drift-monitor.yml`, `dependabot-automerge.yml`, and `release.yml` (on a `v*` tag: build with full history, verify the wheel version matches the tag, publish to PyPI via OIDC, create the GitHub Release from `scripts/release_notes.py`, build and push the container image to GHCR, attest build provenance for both wheel and container digests, and publish `server.json` to the MCP Registry). `ci.yml`'s `docker-build` job builds the image on every PR and checks its `i−    - The `Dockerfile` must use a multi-stage build (`python:3.14-slim AS builder` $\rightarrow$ runtime, pulled from Docker Hub by tag) creating and executing under non-root `USER mcp` with virtual environment `/opt/venv`. The runtime stage carries `LABEL io.modelcontextprotocol.server.name` equal to the `server.json` `name` (MCP Registry OCI ownership check), and the default command stays stdio.−    - Outbound requests must enforce HTTPS, disallow loopback/private/internal IP addresses, and offload DNS hostname verification to worker threads via `asyncio.to_thread` in `SSRFSafeAsyncTransport` to protect event loop responsiveness.− CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.10–3.14, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing and checks its MCP server-name label against `server.json`)). It runs on pushes and pull requests to `main`, daily on `main` at 09:29 UTC (`schedule`), and on manual dispatch (`workflow_dispatch`); the daily run exists because merges by `dependabot-automerge.yml` use `GITHUB_TOKEN`, and pushes made with `GITHUB_TOKEN` do+ - `src/taxcode_mcp/data/` — the single source of truth for statute and publication rows: `jurisdictions.json` (catalog order), `statutes/<code>.json`, `publications/<code>.json`, `manifest/<code>.json` (one source record per row), and `rates/<code>.json` (the compliance tools' rate tables, one per state in `RATE_TABLE_MODELS`). `src/taxcode_mcp/catalog.py` loads and validates them; `db.py` seeds DuckDB from the rows, and `tools/compliance.py` reads every rate from the rate tables. Row layout, ma+ - `scripts/build_catalog.py` — rewrites the data files in canonical form and generates `docs/<code>/*.md`, `docs/<code>/llms-full.txt` (one jurisdiction's full text), `docs/llms.txt` and `docs/llms-full.txt` (the index of the per-jurisdiction files) from them; `--check` (run in CI and by `tests/test_catalog.py`) fails on a schema or canonical-form error (rate tables included, and a missing or stray rate table), an incomplete or mismatched manifest entry, or docs that differ from the generated ou+ - `src/taxcode_mcp/paging.py` — hard response cap (32,000 characters of JSON) and paging for the statutes tools: `statutes_lookup_statute` pages long text (`page_cursor` / `next_cursor`), search and publications clamp `limit` to 1..25 items per call (`offset` / `next_offset`), and the `taxcode://statutes/{jurisdiction}/{section}{?page_cursor}` resource returns the same 8,000-character pages, ending a non-final page with the full URI of the next one (`...?page_cursor=`). The template has no `stat+ - `.github/workflows/` — `ci.yml`, `dependabot-automerge.yml`, and `release.yml` (on a `v*` tag: build with full history, verify the wheel version matches the tag, publish to PyPI via OIDC, create the GitHub Release from `scripts/release_notes.py`, build and push the container image to GHCR, attest build provenance for both wheel and container digests, and publish `server.json` to the MCP Registry). `ci.yml`'s `docker-build` job builds the image on every PR and checks its `io.modelcontextprotoco+    - The `Dockerfile` must use a multi-stage build (`python:3.14-slim AS builder` $\rightarrow$ runtime, pulled from Docker Hub and pinned by digest) creating and executing under non-root `USER mcp` with virtual environment `/opt/venv`. The runtime stage carries `LABEL io.modelcontextprotocol.server.name` equal to the `server.json` `name` (MCP Registry OCI ownership check), and the default command stays stdio.+    - Trust stores follow FastMCP's [certificate authority incident notice (October 2026)](https://github.com/PrefectHQ/fastmcp/blob/main/SECURITY.md#certificate-authority-incident-october-2026): both stages upgrade the OS `ca-certificates` package and fail the build below the patched Debian version (`ARG CA_CERTIFICATES_FLOOR`, declared once), the builder does so before any pip runs because pip trusts the OS store as well as its bundled certifi, the builder bootstraps pip 26.2.2, and `certifi>=2+    - The pip bootstrap is hash-pinned in `docker/pip-bootstrap.txt` and installed with `--require-hashes`, so it does not depend on the TLS trust of the base image's older pip and certifi; whoever raises the pip floor updates that pin and its sha256 from PyPI (`https://pypi.org/pypi/pip/<version>/json`, the `py3-none-any` wheel's `digests.sha256`), because Dependabot does not track the file.+    - Runtime dependencies install from `uv.lock`, so the image runs the versions CI tests: the builder installs uv from `docker/uv-bootstrap.txt` (hash-pinned, `--require-hashes`, into `/tmp/uv` outside the venv, so the runtime image has no uv), runs `uv export --locked --no-dev --no-emit-project --format requirements.txt` (base dependencies only, a hash for every package, and the build fails if `uv.lock` is stale), installs that file with pip in hash-checking mode, then installs the project wit+    - Lowering `CA_CERTIFICATES_FLOOR` with `--build-arg` is unsupported; the build-arg exists only so CI can raise it for the negative floor check, and CI and the release workflow never pass it otherwise.+    - Outbound requests must enforce HTTPS, disallow loopback/private/internal IP addresses, and offload DNS hostname verification to worker threads via `asyncio.to_thread` in `SSRFSafeAsyncTransport` to protect event loop responsiveness. The transport then connects only to an address it checked, trying the next checked address if a connect fails while the request's connect timeout lasts (one deadline shared by all the addresses, not a fresh timeout for each), and keeps the hostname in the URL fo+ uv 0.13.4 or later is required (`[tool.uv] required-version` in `pyproject.toml`, from FastMCP's certificate authority incident notice); older uv refuses to run, and CI's `setup-uv` installs from that setting.+ # Data files, source manifest and generated docs are current+ uv run python scripts/build_catalog.py --check+ CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.11–3.14, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing, checks its MCP server-name label against `server.json`, and checks that the builder stage fails at its `ca-certificates` floor check, before any pip step, when the floor is above the installed version), and `drift-check` (the same OpenAPI drift check as its own job; scheduled and manual runs only)). It runs on pushes an

  • server.json 1 field changed
    version
    1.0.0 1.1.0

  • server.json 1 field changed
    version
    0.8.0 1.0.0

  • server.json 1 field changed
    version
    0.7.2 0.8.0

  • AGENTS.md +4 −4

    https://raw.githubusercontent.com/christianclaudio/mcp-server-taxcode/HEAD/AGENTS.md

    − - `.github/workflows/` — `ci.yml`, `drift-monitor.yml`, `dependabot-automerge.yml`, and `release.yml` (on a `v*` tag: build with full history, check the wheel version matches the tag, create the GitHub Release from `scripts/release_notes.py`; then `docker` builds the image and pushes it to GHCR (`contents: read`, `packages: write`), `attest` attests the pushed digest (`contents: read`, `id-token: write`, `attestations: write`), and `registry` publishes `server.json` to the MCP Registry last (`co−    - The `Dockerfile` must use a multi-stage build (`python:3.12-slim AS builder` $\rightarrow$ runtime, pulled from the ECR Public mirror of Docker Official Images and pinned by digest) creating and executing under non-root `USER mcp` with virtual environment `/opt/venv`. The runtime stage carries `LABEL io.modelcontextprotocol.server.name` equal to the `server.json` `name` (MCP Registry OCI ownership check), and the default command stays stdio.−    - Do not create tags or releases unless the maintainer asks. Releases go out on any weekday on the maintainer's go; no fixed release day. Before the tag, the release owner previews `uv run python scripts/release_notes.py` on `main` and posts it with the release Ask, and the reviewer checks the proposed version against the commit types since the last tag (`!` / `BREAKING CHANGE:` → major, `feat` → minor, otherwise patch, except the template rule above), that the version is unused on all three − CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.10–3.13, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing and checks its MCP server-name label against `server.json`)). It runs on pushes and pull requests to `main`, daily on `main` at 09:17 UTC (`schedule`), and on manual dispatch (`workflow_dispatch`); the daily run exists because merges by `dependabot-automerge.yml` use `GITHUB_TOKEN` and so never trigger the `push` run. Ru+ - `.github/workflows/` — `ci.yml`, `drift-monitor.yml`, `dependabot-automerge.yml`, and `release.yml` (on a `v*` tag: build with full history, verify the wheel version matches the tag, publish to PyPI via OIDC, create the GitHub Release from `scripts/release_notes.py`, build and push the container image to GHCR, attest build provenance for both wheel and container digests, and publish `server.json` to the MCP Registry). `ci.yml`'s `docker-build` job builds the image on every PR and checks its `i+    - The `Dockerfile` must use a multi-stage build (`python:3.14-slim AS builder` $\rightarrow$ runtime, pulled from Docker Hub by tag) creating and executing under non-root `USER mcp` with virtual environment `/opt/venv`. The runtime stage carries `LABEL io.modelcontextprotocol.server.name` equal to the `server.json` `name` (MCP Registry OCI ownership check), and the default command stays stdio.+    - Do not create tags or releases unless the maintainer asks. Releases go out on any weekday on the maintainer's go; no fixed release day. Before the tag, the release owner previews `uv run python scripts/release_notes.py` on `main` and posts it with the release Ask, and the reviewer checks the proposed version against the commit types since the last tag (`!` / `BREAKING CHANGE:` → major, or minor below 1.0.0 per [SemVer §4](https://semver.org/#spec-item-4), `feat` → minor, otherwise patch, ex+ CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.10–3.14, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing and checks its MCP server-name label against `server.json`)). It runs on pushes and pull requests to `main`, daily on `main` at 09:29 UTC (`schedule`), and on manual dispatch (`workflow_dispatch`); the daily run exists because merges by `dependabot-automerge.yml` use `GITHUB_TOKEN`, and pushes made with `GITHUB_TOKEN` do

  • server.json 1 field changed
    version
    0.7.1 0.7.2

  • server.json 1 field changed
    version
    0.7.0 0.7.1
  • server.json 1 field changed
    version
    0.6.1 0.7.0
  • server.json 1 field changed
    version
    0.6.0 0.6.1

  • server.json 1 field changed
    version
    0.5.1 0.6.0
  • server.json 1 field changed
    version
    0.5.0 0.5.1

  • server.json 1 field changed
    version
    0.1.3 0.5.0