spec.about
Self-description of this MCP server: package name + version, per-snapshot pin metadata (sha, fetched_at, biblio_commit, clause_count) for every supported (spec, edition), plus test262 + proposals index headers when present.
無需輸入參數。

io.github.xyzzylabs由 GitHub 帳號 xyzzylabs 發布v0.6.6更新於 Nov 8, 2026
Independent MCP server for the TC39 specs (ECMA-262 + ECMA-402): clauses, search, diffs, history.
唯讀的 MCP 伺服器,讓助理以結構化、以 SHA 固定的方式存取 ECMAScript 規格(ECMA-262 與 ECMA-402):條款、搜尋、文法、差異與 test262。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.xyzzylabs%2Ftc39-mcp/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。把它新增到你客戶端的 mcpServers 設定中。
{
"mcpServers": {
"tc39": {
"type": "http",
"url": "https://mcp.xyzzylabs.ai/tc39/mcp"
}
}
}[Test] [npm version] [License: MIT]
📖 Docs: mcp.xyzzylabs.ai/tc39 — Get started · Tools · Cookbook · Editions · Architecture · Hosting
Independent project — not an official Ecma International or TC39 publication. Reads the publicly published ECMAScript specs (ECMA-262 + ECMA-402).
Give MCP-speaking AI agents structural access to the JS spec.
Any client that speaks the Model Context Protocol can call
clause.get sec-tonumber and get back parsed JSON (algorithm
steps as discrete arrays, cross-references as ids, signatures as
typed values) instead of being handed a 4 MB spec.html to grep
through. Tools cover ECMA-262
(the core language) and ECMA-402
(the Intl API): clauses, algorithm steps, cross-references both
ways, edition diffs, upstream git history, test262 search,
proposal lookup. Every response is SHA-pinned to a specific
upstream commit so anything an agent cites stays reproducible.
Snapshots resolve through a local cache → hosted Worker →
bundled fallback chain. The stdio transport (npx tc39-mcp)
fetches each snapshot from the hosted Cloudflare Worker on a cold
cache, writes it under ~/.cache/tc39-mcp/, and serves it from
disk thereafter — revalidating only when the local copy is older
than ~4 hours (a conditional If-None-Match request). The npm
package also bundles the latest stable + main editions of both
specs plus the test262 and proposals indexes; when the Worker is
unreachable, those are served straight from the package (the
offline fallback — not written to the cache). The hosted Worker
is also the HTTP alternative when you want a shared network
endpoint; its R2 data refreshes from upstream every ~4 hours.
Wire it into any MCP client — the stdio launch command is the same everywhere, only the config file differs:
A global install works too — npm i -g tc39-mcp, then run tc39-mcp.
The first run downloads the npm package (latest stable + main editions plus the proposals and test262 indexes are bundled). The first call for a given snapshot fetches it from the hosted Worker and caches it locally; subsequent calls are served from disk, revalidated against the Worker only after the ~4-hour freshness window. If the Worker is unreachable, the bundled editions still answer offline. Then in your client:
use
clause.getto readsec-tonumberand show me the steps
You should see structured JSON back:
Five-minute walkthrough: docs/getting-started.md.
Point your client at the hosted Cloudflare Worker instead of running a local subprocess — same MCP protocol, no install:
Traffic is rate-limited to 30 req/min per IP.
spec.search ranks
AOID-exact matches first; spec.symbol_resolve decodes
[[Prototype]] / %Object.prototype% / ~enumerate~.spec.crossrefs returns
what a clause cites AND who cites it. AOID-densified so bare
mentions in step text count, not just <emu-xref> hrefs.
include_cross_spec resolves 262 ↔ 402 hops.
(Cookbook recipe 1.)spec.diff
between any two editions back to ES2016; spec.history walks
the upstream git log via pickaxe search.
(Cookbook recipe 2.)test262.search
with prefix-matched esid: catches sec-tonumber AND
sec-tonumber-applied-to-the-string-type in one call.proposal.list /
proposal.get from a structured index of tc39/proposals,
covering both ECMA-262 and ECMA-402 (Intl) proposals — filter by
spec. Refreshed on the same 4-hour cadence as the specs.~/.cache/tc39-mcp/, tool calls are served from
disk and only revalidated against the hosted Worker after the
~4-hour freshness window (a conditional If-None-Match request
that carries the R2 object key, never a clause-id). Bundled
editions answer offline when the Worker is unreachable. The
hosted Worker is the HTTP alternative for shared / multi-tenant
use.Full reference (input schemas, output types, example calls per
tool): docs/tools.md — auto-generated from
the schemas so it never drifts.
Every spec-reading tool accepts spec ("262" or "402", default
"262") and edition (default "latest").
es2016 – es2026, main. (ES5 / ES5.1 / ES6
have no upstream tags and aren't supported.)es2016 – es2026, main. (402 publishes each
annual edition as an esYYYY branch rather than a tag; the fetch
step resolves a branch or a tag the same way.)latest is spec-aware (each spec → its current
stable release, es2026 today). draft / next → main on both.Full table + how to add new releases: docs/editions.md.
The stdio server fetches snapshots from the public hosted Worker
at https://mcp.xyzzylabs.ai/tc39/r2/<key> (cache →
Worker → bundled fallback), so on a strict-egress network it falls
back to the bundled editions and can't reach the others. Override
the base URL via TC39_MCP_BASE_URL to point at a private mirror
— useful for strict-egress networks, air-gapped environments, or
running against a self-hosted Worker:
The endpoint just needs to serve the same key structure
(spec-<spec>-<edition>.json, test262-index.json,
proposals-index.json) — a plain static file server works. If it
returns ETags, the server revalidates with If-None-Match
(cheap 304s); without them it just refetches the full object
when a cached copy goes stale. To populate a mirror, run
npm run parse against a local checkout (see below) and upload
build/*.json to your bucket of choice.
The cache lives at $XDG_CACHE_HOME/tc39-mcp (or
~/.cache/tc39-mcp when XDG_CACHE_HOME is unset).
End users don't need this — the npm package and the hosted Worker are the supported surfaces above. This is for working on the server itself.
Point your MCP client at your local source instead of the published bin:
--silentkeeps npm's lifecycle banner off stdout, so the MCP client receives a clean JSON-RPC stream.
Hosted at mcp.xyzzylabs.ai/tc39
— searchable, dark-mode-friendly, auto-rebuilt on every refresh so
/snapshots always reflects the live SHAs.
In-repo (also browseable on GitHub):
docs/getting-started.md — install →
wire → first call → verify. Five minutes.docs/tools.md — every tool, every field, every
example. Auto-generated from source.docs/cookbook.md — multi-tool recipes:
cross-spec lookups, prose-drift tracking, grammar/SDO
cross-references, test262 coverage, proposal-to-clause mapping.docs/editions.md — supported editions +
alias resolution.docs/architecture.md — data pipeline,
parser, cache, memory model.docs/deployment.md — local stdio, npm
CLI, hosted Cloudflare Worker, refresh model, observability.CONTRIBUTING.md — what kinds of changes
land easily, what won't.SECURITY.md — threat model + responsible
disclosure.CHANGELOG.md — version history + auto-refresh
convention.tc39-mcp is a read-only spec lookup service. The stdio transport
(npx tc39-mcp) sends no telemetry and never transmits your
queries — snapshots are fetched from the hosted Worker on a cold
or stale cache and served from local disk otherwise; those fetches
carry R2 object keys, never clause-ids or tool arguments. The hosted Cloudflare Worker collects only standard
request metadata (IP for rate limiting, timestamps, request
headers); it does not log request bodies, set cookies, or share
data with third parties.
Full policy: mcp.xyzzylabs.ai/tc39/privacy
For privacy questions, open an issue with the privacy label on
GitHub.
MIT
來源:README.md,提交 286e9bc
Self-description of this MCP server: package name + version, per-snapshot pin metadata (sha, fetched_at, biblio_commit, clause_count) for every supported (spec, edition), plus test262 + proposals index headers when present.
無需輸入參數。
Fetch a parsed TC39 clause as structured JSON. `spec` selects '262' (default) or '402'. `edition` defaults to 'latest'. `at: '<sha>'` pins to a historical main snapshot (only valid for edition='main'); omit to query the live snapshot.
atid必填speceditionList parsed spec clauses with optional filters (kind, section prefix, has_algorithm). `spec` selects '262' or '402'. `at: '<sha>'` queries a historical main snapshot.
atkindspeclimiteditionsectionhas_algorithmSearch the parsed spec by clause id / aoid / title (+ step text with `search_steps`). Aoid-exact ranks first. `at: '<sha>'` searches a historical main snapshot.
atspeclimitquery必填editionsearch_stepsList TC39 proposals from the static index (tc39/proposals). Filter by spec ('262'|'402'), stage ('0'|'1'|'2'|'2.7'|'3'|'finished'|'inactive'|'active'), champion (substring), or contains (name/slug substring).
speclimitstagechampioncontainsFetch one TC39 proposal by slug (exact) or name (case-insensitive).
name必填Query grammar productions captured from the spec's `<emu-grammar>` blocks. `{ nonterminal }` returns every production for that non-terminal (exact match); `{ contains }` filters by RHS / name substring; neither lists all non-terminals + their production counts. `include_sdo` folds in SDO-attached productions (off by default).
speclimiteditioncontainsinclude_sdononterminalList or fetch parsed `<emu-table>` content. `{ id }` returns exactly that table (full columns + rows); otherwise list table summaries, optionally narrowed by a `filter` substring over the caption or id.
idspeclimitfiltereditionIndex Syntax-Directed Operations by the grammar production they're defined on. `by: 'production'` (default) groups SDOs under each production; `by: 'sdo'` groups productions under each SDO title. `filter` narrows to keys containing a substring (case-insensitive).
byspeclimitfiltereditionReturn the section tree (table of contents) for a parsed (spec, edition). `depth` caps how deep the tree descends (1 = top-level only); `under` limits the tree to descendants of one clause id.
specdepthundereditionRun spec.search across both ECMA-262 and ECMA-402 in one call and interleave hits by score. Each hit is tagged with the spec it came from. Use it when you don't know which spec defines a symbol. `search_steps` also matches algorithm step text.
limitquery必填search_stepsList the live (spec, edition, sha, fetched_at) snapshots the hosted Worker is serving from R2. Filter by `spec` ('262'|'402') or `edition` (e.g. 'main', 'es2026'). Historical SHA-pinned copies are reachable via `at:` on clause.get / spec.search but aren't enumerated here.
speceditionResolve spec notation like `[[Prototype]]` (internal slot), `%Object.prototype%` (well-known intrinsic), or `~number~` (sigil enum): return clauses that mention or define it, ranked by occurrence with a bump for definition-y sections.
speclimiteditionnotation必填Enumerate the well-known intrinsics in a spec with their probable defining clauses. Driven from the canonical §6.1.7.4 WKI table when present (ECMA-262), else a `%X%` prose scan (e.g. ECMA-402). `filter` narrows by bare-name substring.
speclimitfiltereditionClause-level diff of one clause across two editions of a spec. Reports identical / modified / added / removed plus a field-level breakdown (title, signature, step count, reworded step indices, notes, crossrefs). `from` defaults to the latest stable release, `to` to main.
id必填tofromspecFor a clause id, return its outgoing references (clauses it cites) and/or incoming references (clauses that cite it — the back-reference index the parse alone doesn't expose). The reverse index is AOID-densified from step text. `direction`: 'in' | 'out' | 'both' (default). Outgoing also carries an `external` category: the clause's citations to external specs (Unicode, IETF, WHATWG) as resolvable URLs. Set `include_cross_spec: true` to also resolve outgoing references from ECMA-262 → ECMA-402 (or vice versa).
id必填speclimiteditiondirectioninclude_cross_specSearch the tc39/test262 conformance suite from its indexed front-matter. `query` AND-matches whitespace tokens (case-insensitive) across each test's description + path; `esid` prefix-matches the front-matter esid. Returns ranked hits (path, GitHub url at the indexed SHA, esid, description, features, flags), capped at `limit` (default 20). Supply at least one of `query` / `esid`.
esidlimitquery已滿足適用檢查項的 100%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
{ "mcpServers": { "tc39": { "command": "npx", "args": ["tc39-mcp"] } }}{ "meta": { "id": "sec-tonumber", "aoid": "ToNumber", "title": "ToNumber ( argument )", "number": "7.1.4", "kind": "op" }, "signatureRaw": "ToNumber ( _argument_: an ECMAScript language value, ): either a normal completion containing a Number or a throw completion", "algorithms": [ { "steps": [ { "text": "If _argument_ is a Number, return _argument_." }, { "text": "If _argument_ is either *undefined* or a Symbol, throw a *TypeError* exception." }, { "text": "If _argument_ is *null*, return *+0*<sub>𝔽</sub>." }, "..." ]} ], "crossrefs": ["sec-tonumber-applied-to-the-string-type", "..."]}{ "mcpServers": { "tc39": { "type": "http", "url": "https://mcp.xyzzylabs.ai/tc39/mcp" } }}TC39_MCP_BASE_URL=https://my-mirror.example.com npx tc39-mcpgit clone https://github.com/xyzzylabs/tc39-mcpcd tc39-mcpnpm installnpm run fetch-spec # ~2 min, ~150 MB — both specs at every supported editionnpm run parse # spec.html → build/spec-<spec>-<edition>.jsonnpm run fetch-test262 # optional, enables test262.* (~300 MB)npm run build-test262-indexnpm run fetch-proposals # optional, enables proposal.* (~50 MB)npm run build-proposals-indexnpm run mcp # start the stdio MCP server against your source{ "mcpServers": { "tc39": { "type": "stdio", "command": "npm", "args": ["run", "--silent", "mcp"], "cwd": "/abs/path/to/tc39-mcp" } }}