# How to run Cline in a cloud sandbox Install the `cline` CLI with npm in a Linux microVM, authenticate it with a secret's placeholder, and run `cline --json ""`. **Runtime lets the Cline CLI keep its default auto-approve on without trusting it with your key.** Cline's CLI approves every tool by default when given a prompt, which is what a scripted run needs and what a laptop should not allow. On Runtime the run happens in a Firecracker microVM with its own kernel, Ubuntu 24.04 and Node.js 24, well past Cline's Node.js 20 minimum. The provider key is a Runtime secret: what Cline saves in its `providers.json` is a placeholder, and the host's proxy adds the real key on requests to the provider's API. A 2 vCPU, 4 GiB sandbox is $0.03125 an hour while Cline waits on the model. The `cline` npm package was at 3.0.65 on 25 September 2026. Cline comes in two forms, and each pairs with Runtime differently: | Cline | Pairing | | --------------------- | ----------------------------------------------------------------- | | The CLI (`cline`) | Runs inside a sandbox on a checkout, driven by the SDK | | The VS Code extension | Stays in your editor and calls Runtime's MCP server for sandboxes | ## Put the key in as a placeholder Cline stores provider credentials with `cline auth`. Store the real key as a Runtime secret first: ```bash no-run printf %s "$ANTHROPIC_API_KEY" | npx withruntime secrets set ANTHROPIC_API_KEY --host api.anthropic.com ``` Inside every sandbox of your account `ANTHROPIC_API_KEY` now holds a placeholder. Passing that variable to `cline auth --apikey` stores the placeholder in `~/.cline/data/settings/providers.json`, which is worthless to anyone who copies the file. The proxy swaps in the real key on HTTPS requests to `api.anthropic.com`, and only there ([secrets sandboxes never see](/docs/security#secrets-sandboxes-never-see)). ## Run the CLI on a repo ```ts check import { writeFile } from "node:fs/promises"; import { Sandbox } from "withruntime"; const repo = "https://github.com/your-org/your-repo"; const task = "Make the settings page load without layout shift and run the unit tests."; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600 }); const step = { check: true, timeoutMs: 600_000 } as const; await sbx.exec("npm install -g --prefix /workspace/.local cline", step); await sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], step); await sbx.exec( 'cline auth --provider anthropic --apikey "$ANTHROPIC_API_KEY" --modelid claude-opus-4-5-20251101', step, ); await sbx.network.set({ internet: true, allow: ["api.anthropic.com", "registry.npmjs.org"] }); const run = await sbx.exec(["cline", "--json", "-t", "1500", "-c", "/workspace/app", task], { timeoutMs: 1_800_000, onStderr: (text) => process.stderr.write(text), }); const lines = run.stdout .split("\n") .filter(Boolean) .map((line) => JSON.parse(line)); const said = lines.filter((m) => m.type === "say" && m.say === "text" && !m.partial); console.log(run.exitCode, said.at(-1)?.text); await sbx.exec("git add -A && git diff --cached > /workspace/cline.patch", { cwd: "/workspace/app", check: true, }); await writeFile("cline.patch", await sbx.files.readText("/workspace/cline.patch")); ``` ```python check import sys, json from withruntime import Sandbox repo = "https://github.com/your-org/your-repo" task = "Make the settings page load without layout shift and run the unit tests." with Sandbox.create(disk_mib=8192, timeout_seconds=3600) as sbx: sbx.exec("npm install -g --prefix /workspace/.local cline", check=True, timeout_ms=600_000) sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], check=True, timeout_ms=600_000) sbx.exec('cline auth --provider anthropic --apikey "$ANTHROPIC_API_KEY"' " --modelid claude-opus-4-5-20251101", check=True, timeout_ms=600_000) sbx.network.set(internet=True, allow=["api.anthropic.com", "registry.npmjs.org"]) run = sbx.exec(["cline", "--json", "-t", "1500", "-c", "/workspace/app", task], timeout_ms=1_800_000, on_stderr=sys.stderr.write) lines = [json.loads(line) for line in run.stdout.splitlines() if line] said = [m for m in lines if m.get("type") == "say" and m.get("say") == "text" and not m.get("partial")] print(run.exit_code, said[-1]["text"] if said else None) sbx.exec("git add -A && git diff --cached > /workspace/cline.patch", cwd="/workspace/app", check=True) with open("cline.patch", "w") as file: file.write(sbx.files.read_text("/workspace/cline.patch")) ``` Why each line is there: - **The install** uses `--prefix /workspace/.local`, so `cline` lands in the first directory on the sandbox's `PATH` with no `sudo`. - **`cline auth`** runs through a shell on purpose: the shell expands `$ANTHROPIC_API_KEY` to the placeholder inside the sandbox. The command line your code sends contains no key at all. The flags match Cline's own GitHub Actions sample. - **`--json`** switches on headless output, one JSON message per line with `type`, `text`, `ts` and a `say` or `ask` subtype. The sample keeps the last complete `text` message as Cline's answer. - **`-t 1500`** is Cline's own timeout in seconds, set under the SDK's 30-minute limit so Cline stops first and still prints its messages. - **`-c`** sets the working directory; the task is the last argument and is passed as one array element, untouched by any shell. - **Auto-approve** needs no flag: `--auto-approve` defaults to `true` for a CLI prompt. Pass `--auto-approve false` to have tool calls wait instead. Cline saves each session under `~/.cline/data/sessions`, and `--id ` resumes one. To come back to a run later, keep its sandbox: [pausing it](/how-to/pause-and-resume-a-sandbox) holds the checkout and the session data while compute billing stops. ## CLI options for scripts From Cline's CLI reference, 25 September 2026: | Option | Effect | | --------------------------- | ------------------------------------------------- | | `cline ""` | Starts in act mode with auto-approve on | | `--json` | Newline-delimited JSON messages | | `-p`, `--plan` | Plan mode | | `-t`, `--timeout ` | Stops the run after that long; `0` means no limit | | `-m`, `--model ` | Model for this run | | `-P`, `--provider ` | Provider for this run | | `-c`, `--cwd ` | Working directory | | `--retries ` | Consecutive mistakes allowed before halting | | `--id ` | Resume a saved session | ## Give the Cline extension Runtime sandboxes The VS Code extension, and the CLI on your own machine, read MCP servers from `~/.cline/data/settings/cline_mcp_settings.json`. In the extension, open the **MCP Servers** icon, then **Configure**, then **Configure MCP Servers**, and add: ```json no-run { "mcpServers": { "runtime": { "command": "npx", "args": ["-y", "withruntime", "mcp"], "disabled": false, "autoApprove": [] } } } ``` From a terminal, `cline mcp` opens a wizard that writes the same entry. The first Runtime call returns a link and a code; approve **Connect agent** in the browser and the tools appear, with no key in the settings file ([MCP](/docs/mcp#add-it-to-your-agent)). For the remote server, Cline's **Remote Servers** tab takes `https://api.withruntime.com/mcp` as Streamable HTTP. `autoApprove` lists tools Cline may call without asking. Read-only tools such as `runtime_sandbox_list` and `runtime_sandbox_files_read` are safe to add there; leave `runtime_sandbox_create` out if you want to confirm each new machine. | Tool | Use from the editor | | --------------------------------- | -------------------------------------------------- | | `runtime_sandbox_create` | A clean Linux machine for code Cline wrote | | `runtime_sandbox_exec` | Run it and see the real exit code | | `runtime_sandbox_previews_create` | Open the app it started at a private HTTPS address | | `runtime_sandbox_files_read` | Read logs and results back into the chat | ## Cost On Runtime, CPU is billed as used at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU, and memory at $0.0075 per reserved GiB-hour. So 2 vCPUs and 4 GiB cost $0.03125 an hour while Cline waits on the model and $0.08 an hour with both cores busy ([pricing](/docs/pricing)). Your provider bills the tokens. Start on the trial, 50 sandbox hours with no card: ```bash no-run npx withruntime sandbox run --trial -- node --version ``` To serve what the agent builds, see [preview agent-built apps](/use-cases/preview-agent-built-apps). Other agents with the same setup: [Claude Code](/integrations/claude-code) and [OpenCode](/integrations/opencode). ## Sources Checked 25 September 2026. - [Installing Cline](https://docs.cline.bot/getting-started/installing-cline): `npm install -g cline`, Node.js 20 or later - [CLI reference](https://docs.cline.bot/cli/cli-reference): options, `--auto-approve` default, `--json`, `-t`, `-c`, `--id` - [CLI overview](https://docs.cline.bot/usage/cli-overview): headless triggers and the JSON message fields - [GitHub PR review sample](https://docs.cline.bot/cli/samples/github-pr-review): `cline auth --provider anthropic --apikey ... --modelid ...` - [Config](https://docs.cline.bot/getting-started/config): `providers.json`, `cline_mcp_settings.json` and `sessions/` under `~/.cline/data` - [MCP overview](https://docs.cline.bot/mcp/mcp-overview): server shape, `autoApprove`, Streamable HTTP, `cline mcp` - [cline on npm](https://www.npmjs.com/package/cline): version 3.0.65 Facts on this page were checked on 25 September 2026.