Cinch documentation

Cinch runs untrusted code in secure, disposable sandboxes — one API call, and you get back the result. Your infrastructure is never touched.

Every run executes inside a hardened, gVisor-isolated container with no network access, a read-only filesystem, and strict time and memory limits. Call it from Python or JavaScript/TypeScript.

Built for AI: Cinch is the safe place to run code your model writes. If you're building an agent that generates and executes code, jump to Using with AI agents. If you just want Claude or Cursor to run code safely, see the MCP server.

Quickstart

Install the SDK, grab an API key from your dashboard, and run code in four lines.

1. Install

shell
pip install pangolin-sdk

2. Run code

python
from pangolin import Sandbox

box = Sandbox(api_key="cinch_live_...")
result = box.run("print(2 + 2)")

print(result.stdout)      # "4\n"
print(result.exit_code)   # 0
print(result.duration_ms) # 247

Verify your email and your account starts with $1.00 in free credits — about 20 hours of compute, enough to start experimenting immediately.

Authentication

Cinch authenticates with an API key that looks like cinch_live_…. Create keys in your dashboard — you can have as many as you like (name them per project or environment), and each one's exact usage and spend is tracked separately. A key is shown in full only once at creation, so store it somewhere safe. You can revoke or delete any key at any time.

python
from pangolin import Sandbox

# Your key authenticates every request
box = Sandbox(api_key="cinch_live_yourkey")

Keep your key server-side. Never ship it in frontend code or commit it to a repo.

Running code

Call run() with a string of source code. It spins up a fresh sandbox, executes the code, captures output, and tears the sandbox down — all in one call.

python
result = box.run("""
import math
print(math.sqrt(144))
""")

print(result.stdout)  # "12.0\n"

Languages

Cinch runs both Python 3 and JavaScript (Node 20). The language option defaults to python; set it to javascript to run JS.

python
# Python (default)
box.run("print(2 + 2)")

# JavaScript — pass language="javascript"
box.run("console.log(2 + 2)", language="javascript")

The same hardening — gVisor isolation, no network, read-only filesystem, time and memory limits — applies to every language.

The result object

Every run returns a result with the captured output and metadata about the execution.

python
result = box.run("print('hello')")

result.stdout       # str  — standard output
result.stderr       # str  — standard error
result.exit_code    # int  — process exit code (0 = success)
result.timed_out    # bool — True if it hit the time limit
result.duration_ms  # int  — execution time in milliseconds

Using with AI agents

The most common reason to reach for Cinch: your model writes code, and you need to actually run it without trusting it on your own machine. The pattern is always the same — generate code, run it in a sandbox, feed the real output back to the model.

Why it matters: LLM-generated code is untrusted by definition — you can't read every line before it runs. Cinch executes it with no network, a read-only filesystem, and hard time and memory limits, so a bad generation can't touch anything it shouldn't.

Generate, then execute

A complete loop with the OpenAI SDK. The model returns code; Cinch runs it; you get structured output back.

python
from openai import OpenAI
from pangolin import Sandbox

client = OpenAI()
box = Sandbox(api_key="cinch_live_yourkey")

# 1. Ask the model to write code
completion = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "Reply with ONLY runnable Python. No markdown, no explanation."},
        {"role": "user", "content": "Compute the 20th Fibonacci number and print it."},
    ],
)
generated_code = completion.choices[0].message.content

# 2. Run that untrusted, model-written code safely in Cinch
result = box.run(generated_code)

# 3. Feed the real output back to your agent
print(result.stdout)      # "6765\n"
print(result.exit_code)   # 0

Let the model self-correct

Because every run returns stderr and an exit_code, you can hand execution errors straight back to the model and let it fix its own code — a tight generate → run → repair loop.

python
def run_with_retry(prompt, attempts=3):
    """Let the model self-correct using real execution feedback."""
    messages = [
        {"role": "system", "content": "Reply with ONLY runnable Python."},
        {"role": "user", "content": prompt},
    ]

    for _ in range(attempts):
        code = client.chat.completions.create(
            model="gpt-4o", messages=messages
        ).choices[0].message.content

        result = box.run(code)

        if result.exit_code == 0:
            return result.stdout  # success

        # Hand the error back so the model can fix its own code
        messages.append({"role": "assistant", "content": code})
        messages.append({
            "role": "user",
            "content": f"That errored:\n{result.stderr}\nFix it.",
        })

    return None

Works with any framework that produces code as text — OpenAI, Anthropic, LangChain tool calls, or your own agent loop. Cinch only cares about the code string.

MCP server

No code at all: connect Cinch to Claude Desktop, Claude Code, or Cursor, and the model gets an execute_code tool. It writes code, runs it in a Cinch sandbox instead of on your machine, and reads the real output — one config block and you're done.

Nothing to install: the config uses npx -y @cinch-codes/mcp, which fetches the server automatically on first launch. You just need Node 18+ and an API key.

Claude Desktop (macOS / Linux)

Add to claude_desktop_config.json, then restart the app.

json
{
  "mcpServers": {
    "cinch": {
      "command": "npx",
      "args": ["-y", "@cinch-codes/mcp"],
      "env": { "CINCH_API_KEY": "cinch_live_..." }
    }
  }
}

Claude Desktop (Windows)

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

shell (macOS / Linux)
claude mcp add --scope user cinch -e CINCH_API_KEY=cinch_live_... -- npx -y @cinch-codes/mcp
cmd (Windows)
claude mcp add --scope user cinch -e CINCH_API_KEY=cinch_live_... -- cmd /c npx -y @cinch-codes/mcp

Cursor

Same JSON as Claude Desktop, in .cursor/mcp.json (use the Windows variant on Windows).

The tool calls the same /run endpoint as the SDKs, with your key — identical sandbox limits and per-millisecond billing. Every call is a fresh, stdlib-only sandbox with no network; the tool description tells the model that up front, so it writes self-contained standard-library code.

Windows troubleshooting: if claude mcp list shows Failed to connect, you're missing the cmd /c wrapper. If npx errors with ENOENT ... AppData\Roaming\npm, that folder doesn't exist yet — run mkdir %APPDATA%\npm once and retry.

Package details: @cinch-codes/mcp on npm.

Recipes

Common patterns, ready to copy. Since sandboxes have no network and no shared state, you pass data in through the code string and get results out through stdout.

Pass data into a run

Embed your data directly in the code you send.

python
# Pass data in by embedding it in the code string
rows = [{"name": "Ada", "score": 91}, {"name": "Linus", "score": 88}]

code = f"""
data = {rows!r}
avg = sum(r["score"] for r in data) / len(data)
print(f"average: {{avg}}")
"""

result = box.run(code)
print(result.stdout)  # "average: 89.5\n"

Get structured data back

Print JSON from inside the sandbox, then parse it on your side.

python
# Return structured data: print JSON, then parse it back out
import json

code = """
import json
result = {"ok": True, "values": [1, 4, 9, 16]}
print(json.dumps(result))
"""

run = box.run(code)
data = json.loads(run.stdout)
print(data["values"])  # [1, 4, 9, 16]

Handle failures and timeouts

Check the result instead of trusting the run — errors land in stderr, and timeouts flip timed_out.

python
run = box.run("raise ValueError('nope')")

if run.exit_code != 0:
    print("failed:", run.stderr)   # traceback is in stderr
elif run.timed_out:
    print("hit the 10s time limit")
else:
    print(run.stdout)

Raw HTTP API

Not using an SDK? Hit the endpoint directly. Send a POST to https://api.cinch.codes/run with your key as a Bearer token.

shell
curl https://api.cinch.codes/run \
  -H "Authorization: Bearer cinch_live_yourkey" \
  -H "Content-Type: application/json" \
  -d '{"code":"print(2 + 2)"}'

Response:

json
{
  "stdout": "4\n",
  "stderr": "",
  "exitCode": 0,
  "timedOut": false,
  "durationMs": 247
}

Errors

Failed requests return a JSON body with an error field and the matching HTTP status.

StatusMeaning
400Bad request — the body must be JSON like { "code": "..." }
401Invalid or missing API key
402Out of credits — top up in your dashboard
429Concurrency limit reached — max 10 simultaneous runs
503Temporarily unavailable — retry after a moment

Limits

Each sandbox runs under strict limits for security and fairness.

RuntimePython 3 & JavaScript (Node 20)
Time limit~10 seconds per run
Memory256 MB
Concurrency10 simultaneous runs per account
NetworkNone — sandboxes have no internet access
FilesystemRead-only, with a small writable /tmp
OutputUp to 1 MB per run
IsolationgVisor, non-root, all Linux capabilities dropped

Pricing

Cinch is pay-as-you-go — no subscription, no monthly minimum. You add funds to your balance and spend them only on the compute you actually use.

  • $0.10 per compute-hour, billed by the millisecond with a 100 ms minimum per run — you pay for the exact time your code runs.
  • Each run costs its durationMs of execution. A typical sub-second run is a tiny fraction of a cent.
  • Verify your email and get $1.00 free — about 20 hours of compute, enough for tens of thousands of runs.
  • Top up any time from your dashboard — pay what you want, starting at $5. No monthly wall.

When your balance hits zero, runs are rejected with a 402 until you top up.

Ready to run some code?

Grab a free key and make your first call in under a minute.

Get started free

Comments, questions, concerns? Email us at hello@cinch.codes