{"_id":"@astral-mcp/projection","_rev":"6-2d6a02a929154189e6c8c0f4534aa9f9","name":"@astral-mcp/projection","dist-tags":{"latest":"0.6.0"},"versions":{"0.2.0":{"name":"@astral-mcp/projection","version":"0.2.0","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"license":"MIT","_id":"@astral-mcp/projection@0.2.0","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"homepage":"https://github.com/astralMCP/projection#readme","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"f0afe5508caec6793b9b17c1238b6cf5252704eb","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.2.0.tgz","fileCount":7,"integrity":"sha512-X8b77v0w3Q/I7G2o1m8LnVJ3zdFa69n1z3IYDmAo4SRdd4oeMpTbivxu/vSieyI2OhL75mexGgpFD0my4PgAtQ==","signatures":[{"sig":"MEUCIQDM/qyEMrwX6PUMPVaE7dG3Z7eOiZ7mH5hgzuWQD2UVxAIgWRb4ZPSLx0wPltrOwG12WkSO7HRXZvvVC1g2yAoQcQc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":407182},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"tmp":"tmp/projection_0.2.0_1786304075371_0.7276336564509147","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@astral-mcp/projection","version":"0.3.0","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"license":"MIT","_id":"@astral-mcp/projection@0.3.0","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"homepage":"https://github.com/astralMCP/projection#readme","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"d46ed01e130b2777d26839929e7892aa381d22a0","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.3.0.tgz","fileCount":7,"integrity":"sha512-9iD7pS0GdpO+nE8o2VGJXBDixJvuEfRBa2NOkQi3O4KWzGlXo6S9qS/0HTcWoEVDpIthhZfmDtzBmcHZSLdlfg==","signatures":[{"sig":"MEQCIGyqYGyL4A3m9+X3jl3VaXQUJFxDFl5cAONB9ROdQ+RDAiAS3tLv2kFmD80nbeaol7DR+2SCB9OpfXF8xKT87V5hFg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCVQeK033FrMRZb/tSmE/nEJW7uaGvtJX1cNNhobkAWfwIgNZ1nW/BwnkHDbrSwV5lC5Ld9XfBT4eogR+Mejl1bwwU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":438012},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"tmp":"tmp/projection_0.3.0_1788558585401_0.5329653994730714","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@astral-mcp/projection","version":"0.4.0","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"license":"MIT","_id":"@astral-mcp/projection@0.4.0","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"homepage":"https://github.com/astralMCP/projection#readme","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"e52c8f81e694c517733c440ae25fff8062a5b94b","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.4.0.tgz","fileCount":7,"integrity":"sha512-4+WTb4E7zdWAYV8cJmcMr1UqURftE8bzN4BD3hQhobNZnEl7PqQ7MzrDcbhYG0a43i2GIlDBfbEQCbjta1RrRg==","signatures":[{"sig":"MEUCIGPNJqzMJD6v2Z1V+58aClso+dnPVUebNsoPm3TS79TsAiEAu38MxNaNlVpBhjguMIVsleJ7LTaaq2rlQnOcStoYALU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCWnT5bXNyxVUy4AmRoE8XrzzW7eqi2B20dNb3b+TiPBAIgBXbHRKU8DuH2tM8znoaAYmKdKmGcJIAbtfzzIeDweg0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":441816},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"tmp":"tmp/projection_0.4.0_1789246915251_0.15560949535121216","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@astral-mcp/projection","version":"0.5.0","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"license":"MIT","_id":"@astral-mcp/projection@0.5.0","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"homepage":"https://github.com/astralMCP/projection#readme","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"db3d247f353d911da1f050d5bd49611d0db47d74","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.5.0.tgz","fileCount":7,"integrity":"sha512-PkxuPoKYd7NTl2osSI5riHV0PaOdvnMSm7hGFn8ms3Lxsd6OD1jPHJklWev1tpooyAgonTT0q7Gd6sr7B3j5Lw==","signatures":[{"sig":"MEQCIH0BO8rqNIjbSfZ9OhWi8bQNQ0BZ9ZDxjEca8lgLRvhGAiAFNOWBpCtOzr0e/EJeoZzcpKEIECXpcecGWUAKg8ZB1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIEtVq0DZlL4VzE+CZE209D7WypXhnjUkQy6vm6l+5scHAiEAgn7R45MbDeWtyB3YR2oPQz+U3i9yfI9Z7ZRoztK9n18=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":457294},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"tmp":"tmp/projection_0.5.0_1789253633863_0.7419079600283935","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@astral-mcp/projection","version":"0.5.1","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"license":"MIT","_id":"@astral-mcp/projection@0.5.1","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"homepage":"https://github.com/astralMCP/projection#readme","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"496530314cf8e1d8fff7dd858e72f1c120357115","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.5.1.tgz","fileCount":7,"integrity":"sha512-ydFI9OVyMZQuU7q70PdbY5V+ITzFS8hCM2zRD4XFAwvk2aQznuzabU1aLVPhfjZTIPo8oIpIukn9xLu856koEw==","signatures":[{"sig":"MEYCIQDq/6iiGuDH1Jfn1RzYoAAH5ULAUVgIoYtg2ZCU0kMyyAIhALha1KWthUWiHmpMcJwyHmNELkzjNlMZG4ETJSHuDCMg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGLaJKgM4ehzJoqj7otFSmg42vVNZstyoilRQsoNzaTKAiEAmmqG1A6UeJ28CmnN5IbU/3M0VXiTT8kxb7kepJW4J/Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":460178},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"tmp":"tmp/projection_0.5.1_1789257985213_0.07813669155242708","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"_id":"@astral-mcp/projection@0.6.0","bugs":"https://github.com/astralMCP/projection/issues","dist":{"shasum":"59856b10c28b0a49af73a05adba0e2c3019b4577","tarball":"https://registry.npmjs.org/@astral-mcp/projection/-/projection-0.6.0.tgz","fileCount":7,"integrity":"sha512-XVmObDaMoIPFl6E25uGDn3JP/xPsMu9I1SwJtca5UgasAFLV5lTEiEpumZekoQr7SsuAcr6LQdf6a+bghudfbA==","signatures":[{"sig":"MEUCIA1BoDTF0bAgmfmDmfFS9Cw/LIL/nGuQIG/1q8eQ8eUaAiEAqEss+YK4InCg04S8Gpawb1JwpOppe/45SSeiOTKa+XQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGA7roIRlwarvV4BXXFCAM58RSVqm+T97w1+KMjn9CklAiBrjnJhEANyYLQaVKquxd5yAMU3xJCFNJZl5gGV3kW0Gg=="}],"unpackedSize":478119},"main":"./dist/index.mjs","name":"@astral-mcp/projection","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./package.json":"./package.json"},"license":"MIT","scripts":{"lint":"oxlint","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest"},"version":"0.6.0","_npmUser":{"name":"vibdev","email":"matt@vibdev.com"},"homepage":"https://github.com/astralMCP/projection#readme","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","directories":{},"maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"zod":"^4.2.0","xstate":"5.32.5","typescript":"^5.7.0","@sebastianwessel/quickjs":"3.1.0","@modelcontextprotocol/client":"2.0.0","@modelcontextprotocol/server":"2.0.0","@jitl/quickjs-ng-wasmfile-release-sync":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"unrun":"^0.3.1","tsdown":"^0.22.14","vitest":"^3.2.0","@types/node":"^22.15.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/projection_0.6.0_1789525172730_0.5569688998408582"}}},"time":{"created":"2026-08-09T19:34:35.142Z","modified":"2026-09-16T02:19:33.071Z","0.2.0":"2026-08-09T19:34:35.520Z","0.3.0":"2026-09-04T21:49:45.481Z","0.4.0":"2026-09-12T21:01:55.349Z","0.5.0":"2026-09-12T22:53:53.993Z","0.5.1":"2026-09-13T00:06:25.321Z","0.6.0":"2026-09-16T02:19:32.857Z"},"bugs":"https://github.com/astralMCP/projection/issues","license":"MIT","homepage":"https://github.com/astralMCP/projection#readme","keywords":["mcp","code-mode","xstate","quickjs","sandbox","mrtr"],"repository":{"url":"git+https://github.com/astralMCP/projection.git","type":"git","directory":"packages/projection"},"description":"Turn any MCP server into a code-mode server with human-approved side effects, built on MCP MRTR and XState v5.","maintainers":[{"name":"vibdev","email":"matt@vibdev.com"}],"readme":"# @astral-mcp/projection\n\nTurn any MCP server into a **code-mode** server with **human-approved side\neffects**, built on MCP MRTR (Multi Round-Trip Requests, revision\n2026-07-28) and XState v5.\n\nProjection wraps an existing MCP server and exposes exactly two tools:\n\n- **`execute_machine`** — runs an LLM-authored XState v5 state machine in a\n  QuickJS WebAssembly sandbox. Read-only tool calls execute immediately;\n  any write suspends the machine into a sealed, encrypted blob and asks the\n  human to approve that exact call via MRTR elicitation.\n- **`discover_apis`** — returns generated TypeScript definitions and the\n  authoring contract for the wrapped server's tools.\n\nAll suspension state rides the MRTR `requestState` payload, so Projection is\nfully stateless: any server instance can resume any workflow.\n\n## Usage\n\n```ts\nimport { createMcpHandler } from '@modelcontextprotocol/server';\nimport { wrapMcpServer } from '@astral-mcp/projection';\n\nconst facade = await wrapMcpServer(myMcpServer, {\n  blob: { key: myThirtyTwoByteKey }, // shared across instances\n  policy: { query: 'ask' }, // override annotations per tool\n  redact: (tool, args) => ({ ...args, token: '[redacted]' }),\n});\n\nexport default createMcpHandler(facade.serverFactory);\n```\n\n`serverFactory` carries the negotiated protocol era into each serving unit:\nmodern (2026-07-28) clients get MRTR approval round trips; legacy clients\nstill run read-only machines and get a structured error the moment a\nmachine needs approval. You can also wrap a connected SDK `Client` to put\nProjection in front of a server you don't own.\n\n## Security model\n\n| Invariant                                               | How it holds                                                                                         |\n| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| The tools bridge is the only way out of the sandbox     | No `fetch`, no filesystem, no host globals; only `xstate` and `@astral-mcp/tools` resolve as imports |\n| No gated call runs without a matching approval          | The approved name and arguments are sealed in the blob and executed from there                       |\n| Clients are untrusted couriers                          | Blobs are AES-256-GCM encrypted under a per-blob HKDF-derived key and authenticated                  |\n| A snapshot cannot resume under different code           | The blob binds a SHA-256 hash of the original `code`                                                 |\n| A wrapped server's annotations are hints, not authority | Unannotated tools default to asking; developer overrides always win                                  |\n| Approval prompts cannot be forged                       | Prompt text comes from the catalog and redacted arguments, rendered inert                            |\n\n## Documentation\n\n- [Server-author integration guide](https://github.com/astralMCP/projection/blob/main/docs/server-authors.md)\n  — policy, blob-key operations, resource caps, lifecycle\n- [Product requirements](https://github.com/astralMCP/projection/blob/main/docs/PRD.md)\n  and [engineering decisions](https://github.com/astralMCP/projection/blob/main/docs/DECISIONS.md)\n- [Repository](https://github.com/astralMCP/projection) — scenario test\n  harness, self-heal benchmark, and an interactive demo TUI live alongside\n  the library\n\nRequires Node ≥ 22. MIT licensed.\n","readmeFilename":""}