# How to run Qwen Code in a cloud sandbox Install `@qwen-code/qwen-code` in a Linux microVM, point it at DashScope with a settings file, and run `qwen -p --yolo` on a checkout. **Runtime gives Qwen Code's yolo mode the isolated machine its authors ask for, and keeps the DashScope key off it.** Qwen Code's headless guide warns that `--yolo` "does not enable a sandbox" and recommends it for an isolated runner or container. A Runtime sandbox is a Firecracker microVM with its own kernel, Ubuntu 24.04 and Node.js 24, which satisfies the CLI's Node.js 22 requirement. The key lives as a Runtime secret, so the machine only ever holds a placeholder. Waiting on the model, a 2 vCPU, 4 GiB sandbox costs $0.03125 an hour. The npm release on 25 September 2026 was 0.24.5. | You want | Set it up like this | | -------------------------------------------- | ------------------------------------------------- | | Qwen Code editing a repo unattended | Install it in a sandbox and drive it from the SDK | | Qwen Code on your laptop running code safely | Register Runtime's MCP server with `qwen mcp add` | ## One secret, one settings file Qwen Code talks to any OpenAI-compatible endpoint. Its auth guide suggests a single `~/.qwen/settings.json` that names the provider, the model and the environment variable holding the key. Store the key under that variable's name, bound to the endpoint's host. This example uses Alibaba Cloud Model Studio's international endpoint: ```bash no-run printf %s "$DASHSCOPE_API_KEY" | npx withruntime secrets set DASHSCOPE_API_KEY --host dashscope-intl.aliyuncs.com ``` Every sandbox then has `DASHSCOPE_API_KEY` holding a placeholder, and the proxy fills in the true value only on HTTPS requests to that host. The settings file below carries no key at all, just the name of the variable, which is what Qwen Code's `envKey` field is for ([secrets sandboxes never see](/docs/security#secrets-sandboxes-never-see)). A key from a Coding Plan or Token Plan works the same way: bind the secret to that plan's host and set `baseUrl` to the matching address from Qwen Code's provider guide. ## Drive it from TypeScript or Python ```ts check import { writeFile } from "node:fs/promises"; import { Sandbox } from "withruntime"; const repo = "https://github.com/your-org/your-repo"; const task = "Replace the deprecated date library with the standard Intl API and keep the tests green."; const settings = { modelProviders: { openai: [ { id: "qwen3-coder-plus", name: "qwen3-coder-plus", baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", envKey: "DASHSCOPE_API_KEY", }, ], }, security: { auth: { selectedType: "openai" } }, model: { name: "qwen3-coder-plus" }, }; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600 }); await sbx.files.write("/workspace/.qwen/settings.json", JSON.stringify(settings, null, 2)); const install = { check: true, timeoutMs: 600_000 } as const; await sbx.exec("npm install -g --prefix /workspace/.local @qwen-code/qwen-code", install); await sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], install); await sbx.network.set({ internet: true, allow: ["dashscope-intl.aliyuncs.com", "registry.npmjs.org"], }); const run = await sbx.exec( [ "qwen", "-p", task, "--yolo", "--max-session-turns", "80", "--max-wall-time", "25m", "--output-format", "json", ], { cwd: "/workspace/app", env: { QWEN_CODE_SUPPRESS_YOLO_WARNING: "1" }, timeoutMs: 1_800_000, onStderr: (text) => process.stderr.write(text), }, ); const messages = JSON.parse(run.stdout); const last = messages[messages.length - 1]; console.log(run.exitCode, last.subtype, last.result); await sbx.exec("git add -A && git diff --cached > /workspace/qwen.patch", { cwd: "/workspace/app", check: true, }); await writeFile("qwen.patch", await sbx.files.readText("/workspace/qwen.patch")); ``` ```python check import sys, json from withruntime import Sandbox repo = "https://github.com/your-org/your-repo" task = "Replace the deprecated date library with the standard Intl API and keep the tests green." settings = { "modelProviders": {"openai": [{ "id": "qwen3-coder-plus", "name": "qwen3-coder-plus", "baseUrl": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", "envKey": "DASHSCOPE_API_KEY", }]}, "security": {"auth": {"selectedType": "openai"}}, "model": {"name": "qwen3-coder-plus"}, } with Sandbox.create(disk_mib=8192, timeout_seconds=3600) as sbx: sbx.files.write("/workspace/.qwen/settings.json", json.dumps(settings, indent=2)) sbx.exec("npm install -g --prefix /workspace/.local @qwen-code/qwen-code", check=True, timeout_ms=600_000) sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], check=True, timeout_ms=600_000) sbx.network.set(internet=True, allow=["dashscope-intl.aliyuncs.com", "registry.npmjs.org"]) run = sbx.exec( ["qwen", "-p", task, "--yolo", "--max-session-turns", "80", "--max-wall-time", "25m", "--output-format", "json"], cwd="/workspace/app", env={"QWEN_CODE_SUPPRESS_YOLO_WARNING": "1"}, timeout_ms=1_800_000, on_stderr=sys.stderr.write, ) last = json.loads(run.stdout)[-1] print(run.exit_code, last["subtype"], last["result"]) sbx.exec("git add -A && git diff --cached > /workspace/qwen.patch", cwd="/workspace/app", check=True) with open("qwen.patch", "w") as file: file.write(sbx.files.read_text("/workspace/qwen.patch")) ``` How the pieces fit: - **The settings file goes in first.** `security.auth.selectedType` tells Qwen Code which protocol to use on start, so it never opens the `/auth` dialog, which a headless run cannot answer. `HOME` in a sandbox is `/workspace`, so `~/.qwen` is `/workspace/.qwen`. - **`--yolo`** approves shell, write and edit calls. The suppression variable only silences the one-line stderr warning Qwen Code prints when yolo runs without its own sandbox; the microVM is the boundary instead. - **Budgets** stop a stuck agent. `--max-session-turns` ends the run with exit code 53, and `--max-wall-time` or `--max-tool-calls` with exit code 55. - **JSON output** is an array of messages. The last one has `type: "result"`, a `subtype` such as `success`, and the final answer in `result`. - **The diff** travels back as a file, so its size never runs into the 64 KiB cap on returned output. ## Flags for unattended runs As documented in Qwen Code's headless guide on 25 September 2026: | Flag | Effect | | ------------------------------------- | ------------------------------------------------- | | `-p`, `--prompt` | Headless mode for one prompt | | `--yolo`, `--approval-mode yolo` | Approve every tool call | | `--approval-mode auto-edit` | Approve edits, ask about the rest | | `--output-format json` | One JSON array at the end of the run | | `--output-format stream-json` | One message per line as the run goes | | `--max-session-turns ` | Turn cap; exit code 53 when crossed | | `--max-wall-time`, `--max-tool-calls` | Budget caps; exit code 55 when crossed | | `--continue`, `--resume ` | Carry on a session saved under `~/.qwen/projects` | Because sessions are stored in the sandbox's home, `--continue` works across tasks when the same sandbox is kept. [Pausing it](/how-to/pause-and-resume-a-sandbox) between tasks keeps the checkout, the session files and any running processes while compute billing stops. ## Give Qwen Code Runtime's tools With Qwen Code on your own machine, add Runtime's MCP server at user scope: ```bash no-run qwen mcp add --scope user runtime npx -y withruntime mcp ``` or put the same entry in `~/.qwen/settings.json`: ```json no-run { "mcpServers": { "runtime": { "command": "npx", "args": ["-y", "withruntime", "mcp"] } } } ``` On the first call the server shows a link and a code. Approving **Connect agent** in the browser loads every Runtime tool, with no key written into the settings ([MCP](/docs/mcp#add-it-to-your-agent)). In CI, `RUNTIME_API_KEY` from a secret manager takes the place of the browser step. | Tool | Use | | ------------------------------------------------ | --------------------------------------------- | | `runtime_sandbox_create`, `runtime_sandbox_exec` | Start a microVM and run commands in it | | `runtime_sandbox_files_write`, `_read` | Move source in and results out | | `runtime_sandbox_previews_create` | Share a dev server at a private HTTPS address | | `runtime_sandbox_fork` | Try several fixes from one running state | ## Cost Runtime charges $0.025 per vCPU-hour of CPU actually used, with a floor of a twentieth of a vCPU, plus $0.0075 per reserved GiB-hour. For 2 vCPUs and 4 GiB that is $0.03125 an hour idle and $0.08 an hour with both cores busy ([pricing](/docs/pricing)). Model Studio bills the tokens on your key. Try it on the free trial, 50 sandbox hours with no card: ```bash no-run npx withruntime sandbox run --trial -- node --version ``` Qwen Code shares its lineage with [Gemini CLI](/integrations/gemini-cli), whose page uses Google's API instead. For many agents at once, see [a sandbox for coding agents](/use-cases/coding-agent-sandbox), and for scoring runs, [agent evals](/use-cases/agent-evals-and-swe-bench). ## Sources Checked 25 September 2026. - [Qwen Code on GitHub](https://github.com/QwenLM/qwen-code): `npm install -g @qwen-code/qwen-code@latest`, Node.js 22 or later - [Headless mode](https://github.com/QwenLM/qwen-code/blob/main/docs/users/features/headless.md): `-p`, `--yolo`, output formats, budgets, exit codes 53 and 55, the yolo warning - [Authentication](https://github.com/QwenLM/qwen-code/blob/main/docs/users/configuration/auth.md): `modelProviders`, `envKey`, `security.auth.selectedType` - [Model providers](https://github.com/QwenLM/qwen-code/blob/main/docs/users/configuration/model-providers.md): the international DashScope endpoint and the Coding Plan addresses - [MCP](https://github.com/QwenLM/qwen-code/blob/main/docs/users/features/mcp.md): `qwen mcp add` and `mcpServers` - [@qwen-code/qwen-code on npm](https://www.npmjs.com/package/@qwen-code/qwen-code): version 0.24.5 Facts on this page were checked on 25 September 2026.