Show HN: Static MCP – publish MCP tools as static files, run them sandboxed Static MCP, a new open-source project, lets developers publish MCP tools as static, hash-verified files executed sandboxed on demand, eliminating the need for server infrastructure. The reference implementation, mcpwasm, runs untrusted tool code inside QuickJS-wasm on Cloudflare Workers and integrates with the llms-txt-skills standard. Users can run tools from any static site via a single npx command, with no account or deploy required. Static MCP: your tools are files, not servers. Tools are published as static, hash-verified content and executed sandboxed on demand. What static site hosting did to web servers — "don't run Apache, publish HTML" — this does to MCP servers: don't run an MCP server, publish files. The publisher needs zero infrastructure; the MCP server is materialized per request from those files and evaporates after responding ephemeral instance, durable definition . mcpwasm is the reference implementation: a sandboxed runtime for third-party MCP tools untrusted tool code inside QuickJS-wasm on Cloudflare Workers , plus a gateway that turns any static site publishing llms.txt with executable skills into an MCP server. Think "php-wasm, but for MCP tools": the platform owner embeds the host, loads tool.js files, and each tool runs isolated in a QuickJS WebAssembly sandbox. The only bridge from the sandbox to the platform's internals is an explicit capability the host injects. No capability, no access. This repo integrates with the llms-txt-skills https://github.com/MauricioPerera/llms-txt-skills standard via two provisional extensions adopted in the spec: executable skills v0.4, with origin memory and skill attestations v0.4 . See the dedicated sections below. Point the local runtime at any origin that publishes llms.txt with executable skills. It fetches /llms.txt , verifies every tool sha256 , sandboxes each skill in QuickJS-wasm, and speaks MCP over stdio — no account, no deploy, no infrastructure on either side : npx -y @rckflr/mcpwasm https://usuario.github.io Wire it into an MCP client Claude Code, Cursor, Cline, … : { "mcpServers": { "misitio": { "command": "npx", "args": "-y", "@rckflr/mcpwasm", "https://usuario.github.io" } } } That is the whole path from a static site to a running MCP server. The two other ways to use mcpwasm are for when you specifically need them: the hosted gateway multi-tenant, on Cloudflare Workers — serves many origins behind one endpoint, with an onboarding step per origin and the embeddable library @rckflr/mcpwasm — for building your own host . Both are documented below; the local runtime above needs none of it. Its honest limits and the index.json /attestation options are detailed under " Local MCP runtime local-mcp-runtime--no-gateway-at-all ". The runtime is a standard MCP stdio server, so every MCP host can use it. Replace the origin with any publisher find more in the registry https://github.com/MauricioPerera/llms-skills-registry ; add --lock skills.lock for pin-on-first-use. Claude Code one command : claude mcp add static-skills -- npx -y @rckflr/mcpwasm https://mauricioperera.github.io Claude Desktop claude desktop config.json / Cursor .cursor/mcp.json / project-scoped .mcp.json — same JSON shape: { "mcpServers": { "static-skills": { "command": "npx", "args": "-y", "@rckflr/mcpwasm", "https://mauricioperera.github.io", "--lock", "skills.lock" } } } Restart the session and the origin's verified tools plus their SKILL.md recipes as resources appear like any other MCP server's. The embeddable host — what the gateway itself builds on — ships as @rckflr/mcpwasm https://www.npmjs.com/package/@rckflr/mcpwasm : npm install @rckflr/mcpwasm js import { AsyncToolHost } from "@rckflr/mcpwasm"; const host = new AsyncToolHost { allowedOrigin: "https://example.com" } ; await host.init ; host.loadToolSource toolJsSource ; // a tool.js that calls registerTool {...} const tools = host.listTools ; const result = await host.callTool "sum numbers", { a: 2, b: 40 } ; host.dispose ; Notes: - In Cloudflare Workers, pass a pre-built asyncify module via the quickjs option see worker-gateway.mjs for the CompiledWasm import pattern and import @rckflr/mcpwasm/shim first . - Subpath exports: /host sync ToolHost , /host-async , /mcp-core , /mcp-core-async , /llmstxt-parse , /shim . - The sync ToolHost lazy-imports the optional peer quickjs-emscripten unless you pass a pre-built module; the async host's dependencies install with the package. - The package contains only the host/core/parser files plus the local runtime binary; the workers, publisher sites and test suites stay in this repo they are the deployed reference, not the library . The package also ships a stdio MCP server that runs an origin's skills locally : it fetches /llms.txt , verifies every tool sha256 , loads each verified skill into its own QuickJS-wasm context, and speaks MCP over stdin/stdout — so a static site e.g. a GitHub Pages user site becomes an MCP server on your machine with zero deployed infrastructure on either side: npx -y @rckflr/mcpwasm https://usuario.github.io MCP client configuration Claude Code, Cursor, … : { "mcpServers": { "misitio": { "command": "npx", "args": "-y", "@rckflr/mcpwasm", "https://usuario.github.io" } } } Publishers under a path work. The origin may carry one — a GitHub Pages project site https://user.github.io/REPO is discovered at