# @cinch-codes/mcp MCP server for [Cinch](https://cinch.codes). Gives your AI assistant a real sandbox to run code in. Without it, an assistant writes code and you run it yourself. With it, the assistant runs the code and reads the actual output — inside a gVisor-isolated container on Cinch's infrastructure, with no access to your machine, filesystem, or local network. Pay per execution. No subscription floor. ## Setup Get an API key at [cinch.codes](https://cinch.codes), then add the server to your MCP client. **Claude Desktop** — `claude_desktop_config.json`: ```json { "mcpServers": { "cinch": { "command": "npx", "args": ["-y", "@cinch-codes/mcp"], "env": { "CINCH_API_KEY": "cinch_live_..." } } } } ``` **Claude Desktop on Windows** — same file, but Windows can't spawn `npx` directly, so wrap it with `cmd /c`: ```json { "mcpServers": { "cinch": { "command": "cmd", "args": ["/c", "npx", "-y", "@cinch-codes/mcp"], "env": { "CINCH_API_KEY": "cinch_live_..." } } } } ``` **Claude Code** (macOS/Linux): ```bash claude mcp add --scope user cinch -e CINCH_API_KEY=cinch_live_... -- npx -y @cinch-codes/mcp ``` **Claude Code** (Windows): ```cmd claude mcp add --scope user cinch -e CINCH_API_KEY=cinch_live_... -- cmd /c npx -y @cinch-codes/mcp ``` **Cursor** — `.cursor/mcp.json`, same shape as the Claude Desktop config above. Restart the client. That's it — no install step, `npx` fetches it on first run. ## What it exposes ### `execute_code` Runs a self-contained Python or JavaScript program and returns stdout, stderr, exit code, and duration. | Parameter | Type | Default | Description | |---|---|---|---| | `code` | string | — | The complete program to run. Must print to stdout to return anything. | | `language` | `python` \| `javascript` | `python` | Runtime to execute in. | Each call gets a clean sandbox. State does not persist between calls, so every snippet needs to stand on its own. ## The sandbox environment Deliberately minimal. Worth knowing before you wonder why an import failed: | | | |---|---| | Runtimes | Python 3.12, Node 20 | | Packages | **Standard library only.** No pip or npm packages are installed, and none can be installed at runtime. | | Network | **None.** HTTP, DNS, and package installs all fail. | | Filesystem | Root is read-only. `/tmp` is writable (64 MB) and destroyed when the run ends. | | Memory | 256 MB | | CPU | 0.5 cores | | Time limit | 10 seconds | | Isolation | gVisor (`runsc`), all capabilities dropped, no-new-privileges, non-root user, 64-process cap | The tool description tells the model all of this up front, so it writes stdlib-only code instead of reaching for `numpy` and failing on the first call. ## Configuration | Variable | Required | Default | Description | |---|---|---|---| | `CINCH_API_KEY` | yes | — | Your Cinch API key. | | `CINCH_TIMEOUT_MS` | no | `20000` | Client-side timeout in ms. The API caps execution at 10s regardless. | | `CINCH_BASE_URL` | no | `https://api.cinch.codes` | Override the API endpoint. | ## Troubleshooting **Windows: "Failed to connect" in `claude mcp list`** — you're missing the `cmd /c` wrapper. Windows resolves `npx` to a batch script that can't be spawned directly; re-add the server using the Windows command above. **Windows: `npm error ENOENT ... AppData\Roaming\npm`** — some Node installs never create npm's global folder, and `npx` refuses to run without it. Create it once and retry: ```cmd mkdir %APPDATA%\npm ``` **Server exits immediately with "CINCH_API_KEY is not set"** — the env var didn't reach the server. In Claude Code, put `-e CINCH_API_KEY=...` *before* the server name in `claude mcp add`. In config files, check the `env` block is inside the `cinch` entry. **Debugging any connection failure** — run the server directly to see the real error instead of a generic status: ```bash CINCH_API_KEY=cinch_live_... npx -y @cinch-codes/mcp # macOS/Linux ``` ```cmd set CINCH_API_KEY=cinch_live_... && cmd /c npx -y @cinch-codes/mcp # Windows ``` Correct behavior is `cinch-mcp ... ready` followed by silence — an MCP server waits for a client. Anything else printed is the actual failure. ## Why sandboxed execution Code written by a model is untrusted code — nothing reviewed it before it ran. Executing it directly on your machine means handing it your filesystem, your network, and your credentials. Cinch runs it somewhere else entirely, in a disposable container with kernel-level isolation, and sends back only the output. ## Notes - Requires Node 18 or newer. - Output is capped at 20,000 characters per stream to protect your context window; anything beyond that is truncated with a marker. - Runs that time out or exit non-zero are returned as tool errors, so the assistant knows the code failed and can correct it. - Out-of-credit responses are surfaced clearly and instruct the assistant not to retry, so a drained balance does not turn into a retry loop. ## Links - [cinch.codes](https://cinch.codes) - JS/TS SDK: [`@cinch-codes/pangolin`](https://www.npmjs.com/package/@cinch-codes/pangolin) - Python SDK: [`pangolin-sdk`](https://pypi.org/project/pangolin-sdk/) MIT