wasm-mcp
Model Context Protocol server for the
WebAssembly core specification.
SHA-pinned, read-only, deterministic — safe to host as a public
unauthenticated endpoint.
Not affiliated with, endorsed by, or sponsored by the W3C
WebAssembly Community Group or Working Group.
What it gives you
spec_version — the pinned upstream commit and package version.
instruction_get — opcode bytes, category, introducing version,
stack type signature, validation + execution prose anchors / URLs,
and trap conditions (traps + can_trap), by mnemonic (i32.add)
or binary opcode (0x6a).
instruction_list — enumerate, filterable by category (numeric,
vector, reference, parametric, variable, table, memory, control,
ref, i31, struct, array, extern), introducing version, or prefix.
instruction_search — ranked free-text search across mnemonics,
categories, and opcodes.
type_get — value types (number / vector / reference) and type
forms (functype, limits, memtype, …) with defining prose.
section_get — one spec clause by id / anchor (structure,
validation, execution, binary, text), with prose, cross-references,
SpecTec formal-rule references, and the rendered URL.
section_list — navigate the clause tree by area or anchor prefix.
spec_search — full-text search across anchors, titles, and prose.
proposal_list — WebAssembly proposals and their phases (from the
pinned WebAssembly/proposals repo), filterable by status, phase,
champion, or affected spec.
section_get, section_list, and spec_search take a spec
argument covering all three specs in the WebAssembly/spec repo:
core (default), js-api (the JavaScript embedding API), and
web-api (Web-platform integration). The instruction and type tools
are core-only.
Contract
Every tool is:
- Read-only. No state mutation, no writes outside an optional
local cache.
- Deterministic. Same input → same output, over the pinned spec
commit recorded in
vendor/PINNED.txt.
- No execution. Never compiles, validates-by-running,
instantiates, or runs any WebAssembly or arbitrary code. Validation
and reduction rules are returned as data.
- No auth, no secrets, no PII. Usable anonymously.
- No network at request time. All spec data is fetched and
indexed at build time and baked into the package.
Install (stdio, local)
npx wasm-mcp
Wire it into any MCP client by adding the server to its config (the
launch command is the same everywhere; only the config file differs):
{
"mcpServers": {
"wasm": {
"type": "stdio",
"command": "npx",
"args": ["wasm-mcp"]
}
}
}
Hosted Worker
The Cloudflare Worker in worker/ exposes the same tool
surface as the stdio package over streamable HTTP at a single
unauthenticated endpoint, rate-limited per source IP (30 req / 60 s):
https://mcp.xyzzylabs.ai/wasm/mcp
GET /wasm/health reports status and the pinned SHAs; GET /wasm/privacy
states the anonymous, no-storage posture. All spec data is bundled
into the Worker, so it does pure in-memory lookups — no storage, no
network at request time.
Releases & data refresh
The pinned commits live in vendor/PINNED.txt
and are reported by spec_version. A scheduled GitHub Actions
workflow (refresh.yml) SHA-diffs
the upstream repos daily; when a pin moves it re-pins, bumps the patch
version, and tags a release, which publishes the npm package
(release.yml) and redeploys the
Worker (deploy-worker.yml).
Maintainers:
- npm publish uses Trusted Publishing
(OIDC) — no
NPM_TOKEN. Configure it once on npmjs.com (wasm-mcp →
Settings → Trusted Publisher → GitHub Actions: org xyzzylabs, repo
wasm-mcp, workflow release.yml).
- Worker deploy needs
CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID,
stored as environment secrets on the cloudflare GitHub
Environment (not repo-wide) with a main + v* deployment rule —
see Securing the deploy credentials.
- For the refresh workflow's tag push to trigger release + deploy,
add a
WORKFLOW_PAT PAT (contents: write + workflows) —
without it, refresh still re-pins and tags, but you run release /
deploy manually. (Same secret name tc39-mcp uses, so one PAT — or an
xyzzylabs org secret — can serve both repos.)
License
MIT — see LICENSE.