Skip to content

Changelog

All notable changes to tc39-mcp are recorded here. Versions follow Semantic Versioning: tool-schema or behavior changes that aren't backward-compatible bump the major; new tools or optional schema fields bump the minor; internal fixes bump the patch.

A note on auto-refresh PATCH versions

This file only records code changes — new tools, schema tweaks, internal fixes. The refresh.yml workflow also publishes PATCH bumps every few hours when upstream tc39/ecma262, tc39/ecma402, tc39/test262, or tc39/proposals move. Those releases ship identical code with a refreshed spec-data payload and do not get an entry here — otherwise the file would balloon by dozens of entries per month, all saying "spec moved."

To see which SHA a given published version is pinned to:

  • Live — call spec.about or spec.snapshots; the response carries the per-snapshot sha + fetched_at.
  • Browse — the /snapshots page on the hosted Worker (same origin that serves /mcp), regenerated on every refresh, lists every parsed (spec, edition, sha, fetched_at) tuple.
  • Historical — the hosted Cloudflare Worker accepts at: "<sha>" to address a specific upstream commit; the npm tarball pins to whatever was current at publish time.

[0.1.3] — 2026-05-31

Two non-runtime additions on top of 0.1.2:

  • package.json carries the mcpName field pointing at io.github.xyzzylabs/tc39-mcp. The MCP Registry uses this to verify that the npm package and the registry namespace are controlled by the same party; without it, publishing the server.json to the registry fails the anti-squatting check.
  • README rebalanced. 0.1.2 led the README with offline-first; this version leads with the agentic spec-lookup framing (offline becomes a supporting bullet). The README that lands on npmjs.com with this publish is the one currently rendered on the docs site.

No runtime behavior change — the MCP server speaks the same protocol against the same parsed snapshots as 0.1.2.

[0.1.2] — 2026-05-31

No changes to the published npm package's runtime behavior — the MCP server speaks the same protocol against the same parsed snapshots as 0.1.1. This release tightens the README to lead with the offline-first positioning, adds new docs site pages, completes the tool-schema documentation, and ships deployment-side improvements for the hosted Cloudflare Worker that are exercised when you self-host or use the public deployment.

Documentation

  • docs/getting-started.md — new five-minute walkthrough from install through wiring an MCP client through making the first call and verifying the response.
  • docs/cookbook.md — six multi-tool recipes: cross-spec lookups, prose drift across editions, notation → definition, test262 coverage for one clause, grammar / SDO joins, and proposal-to-clause mapping.
  • docs/tools.md — now auto-generated by src/docs/build_api_reference.ts (uses the TypeScript Compiler API to walk src/mcp/server.ts + src/mcp/tools/*.ts). Each tool section carries a "What it answers" block of co-located example calls, full input schema, and the handler's declared return type expanded into a field table when it names a local interface.
  • docs/sponsor.md — describes the optional sponsorship model: anonymous use stays free at 30 req/min/IP; sponsors at any tier ≥ $5/mo get a tcms_… key giving 300 req/min bucketed per-key on the hosted Worker.
  • README rewrite — leads with offline-first positioning and a worked clause.get sec-tonumber response example. Drops the per-namespace tool breakdown that had grown to duplicate docs/tools.md. Adds a Sponsorship section.
  • docs/index.md — new ✈️ "Offline-first by default" feature card; tagline expanded to lead with the offline angle.

Tool schemas

Code-side improvements that flow into the regenerated tools.md:

  • Every tool's input Zod schema now has .describe() on every field. Shared spec / edition / limit parameters in particular were spotty before and are now uniform.
  • Every output TypeScript interface (and the shared types in src/parser/schema.ts) carries JSDoc on every field; the generated tools.md surfaces this verbatim.
  • Each tool file now exports a <name>Examples array of { q, input, note? } triples. The generator renders these as a "What it answers" section under each tool — example calls tagged with the natural-language question they answer, with an optional italic note.

Hosted Worker (deployment-only)

These changes ship when the Worker is redeployed; they do not affect the published npm package:

  • Two-layer read cache in front of R2. New per-colo edge cache wrapping every R2 GET. Per-SHA snapshots cache as public, max-age=86400, immutable; live mains cache as max-age=300. Cuts repeat R2 reads dramatically.
  • Tighter rate limiter — 100 → 30 req/min/IP for anonymous traffic. Math sized to keep worst-case per-IP load under the R2 Class B free allowance even cold.
  • Sponsor auth middleware. Optional Authorization: Bearer tcms_… header is checked against a SHA-256 hash in a Cloudflare KV namespace (binding SPONSORS). Recognized keys land in a separate per-key 300/60s rate-limit bucket; missing / malformed / unrecognized keys fall through to the anonymous path transparently — auth never blocks access.
  • Sponsor key issuance + revocation scripts in worker/: npm run issue-sponsor-key -- --github=<login> mints a random tcms_… key, stores its hash + metadata in KV, prints the raw key once. npm run revoke-sponsor-key -- --github=<login> removes the KV entry.

Internal

  • Workflow permissions scoped explicitly on every CI job; CodeQL alerts addressed (actions/missing-workflow-permissions, js/incomplete-sanitization).
  • Dependabot: pinned esbuild >= 0.25.0 via package.json overrides (closes GHSA-67mh-4wv8-2f99).
  • AGENTS.md rewritten as a standalone project rules file.

[0.1.0] — 2026-05-30

Initial release. 19 tools across 5 namespaces, two TC39 specs covered (ECMA-262 + ECMA-402), 13 supported parsed snapshots in total (11 for 262 + 2 for 402), plus offline indices for test262 and tc39/proposals.

Three deploy shapes:

  • Local stdio via npx tc39-mcp (default — wires into Claude Code via .mcp.json).
  • Local CLI via npm i -g tc39-mcp + the tc39-mcp bin.
  • Hosted HTTP via the Cloudflare Worker in worker/. Bundles to ~12 KB; reads parsed JSONs from R2; ships 6 of the 19 tools (the rest are stdio-only for v0.1). The same Worker also serves the docs site as static assets — one origin for both /mcp and /. See docs/deployment.md.

Freshness is automatic: .github/workflows/refresh.yml runs every 4 hours, diffs upstream tc39/* mains against the last published SHAs, and republishes a PATCH bump when anything moved. The hosted Worker rebuilds both API + docs together on every PATCH.

Tools

Every spec-reading tool accepts a spec argument selecting "262" (default) or "402".

ToolNotes
spec.aboutSelf-describe the running server: package version, per-snapshot pin metadata, test262 + proposals index headers. Use first to verify what you're reading.
spec.snapshotsEnumerate every (spec, edition, sha, fetched_at) parsed snapshot the server has available. Useful for discovering historical SHAs queryable via at: (hosted Worker only in v0.1).
clause.getFull structured clause: signature, numbered steps + substeps, notes, crossrefs.
clause.listBrowse by kind / section prefix / has_algorithm.
clause.outlineSection tree / table of contents for a parsed (spec, edition). depth + under controls.
spec.searchaoid / title / id ranking; optional step-text scan via search_steps.
spec.crossrefsForward AND backward refs. Reverse index is AOID-densified (catches "who calls ToNumber" without <emu-xref>). Opt-in include_cross_spec resolves outgoing 262 ↔ 402 references.
spec.diffGeneric clause-level diff with from / to editions of a single spec.
spec.historyRecent commits in the vendored spec that touched a clause's opening tag (git pickaxe).
spec.symbol_resolveResolve [[X]] / %X% / ~X~ notation to defining clauses.
spec.tablesParsed <emu-table> content (well-known intrinsics, symbols, completion record fields, etc.).
spec.grammarStandalone <emu-grammar> productions captured from §11-15.
spec.global_searchCross-spec search across both 262 + 402, results tagged by spec. Convenience over running spec.search twice.
spec.sdo_indexIndex Syntax-Directed Operations by grammar production (or by SDO title).
spec.well_known_intrinsicsEnumerate %X% notations + probable defining clause (title-substring heuristic, honest about confidence).
test262.searchReads build/test262-index.json (built from a vendored test262 checkout). test262 covers both 262 and 402. Index-only — no auth, no network, no subprocess. esid is a case-insensitive prefix match; multi-word query is token-AND across description + path.
test262.getFetch one test's source + parsed front-matter by path. Pairs with test262.search.
proposal.listList TC39 proposals from a static index built from tc39/proposals. Filter by stage / champion / name substring.
proposal.getFetch one TC39 proposal by slug (canonical) or name (case-insensitive).

Specs + editions

ECMA-262:

Resolved at loadValue(s)
Concrete releaseses2016, es2017, es2018, es2019, es2020, es2021, es2022, es2023, es2024, es2025
Working draftmain

ECMA-402:

Resolved at loadValue(s)
Concrete candidateses2025-candidate
Working draftmain

Aliases (resolved spec-aware):

AliasResolves to (262)Resolves to (402)
latestcurrent stable release (es2025 today)main (no annual final-release tag exists upstream)
draft / nextmainmain

Floor for ECMA-262 is es2016 because tc39/ecma262 has no earlier release tag. ES5/ES5.1 predate the GitHub repo; ES2015/ES6 was authored there but never tagged.

ECMA-402 doesn't tag annual releases at all — the candidates plus main are the entire universe of published refs.

Notes

  • The loadSpec cache is keyed on (spec, concrete edition), so { spec: "262", edition: "latest" } and { spec: "262", edition: "es2025" } share one in-memory parse.
  • spec.history detects shallow vendor clones (the default fetch-spec.sh uses --depth=1) and returns a hint field telling the caller to git fetch --unshallow for deep history.
  • test262.search is offline-tolerant: if the index hasn't been built it returns an empty hit list with a hint field pointing at the setup command. No subprocess fallback — local and hosted behave identically.

Docs included

  • README.md — quick start + tool table + edition table.
  • docs/architecture.md — pipeline, modules, edition + alias resolution.
  • docs/tools.md — full reference for every tool.
  • docs/editions.md — spec + edition model, adding new releases.
  • docs/deployment.md — local stdio, npm CLI, hosted Cloudflare Worker sketch.
  • CONTRIBUTING.md — change-shape guidance.
  • SECURITY.md — threat model + reporting path.

Out of scope

This release deliberately ships no execution, no write paths, no authentication. See CONTRIBUTING.md for the boundary.

Released under the MIT License.