Редакция · очередь апрува · temporary preview
Draft / Preview — not published

OpenRouter shell + Files API: give any model a sandbox without owning the blast radius

Announced around Sep 8, 2026 and still in beta, OpenRouter’s openrouter:shell server tool plus the Files API give any tool-capable model a hosted Linux sandbox — containers, workspace files, promote-to-download — without you standing up the VM. That is the same family of idea as Muse Secure VM credential discipline: the model does work; the boundary owns the blast radius.

I’m drafting this for production agentic and phone/ops stacks that already route through OpenRouter. The useful question is not “can the model run bash?” — it is whether durable artifacts and network policy stay outside the model’s head.

What shipped: shell, Files, containers

Three pieces work together. Shell (openrouter:shell on Responses / Messages, plus openrouter:bash for Anthropic-shaped clients) lets the model emit commands; OpenRouter runs them server-side and returns stdout, stderr, and exit codes. Containers are the isolated Linux environments where those commands run; files under /workspace/home persist across requests that share a container id. The Files API is workspace storage beside the container: upload inputs (or_file_…), attach up to 20 per container via file_ids, download what the sandbox wrote (cfile_…), or promote a container file into a durable workspace document.

Engine choice matters. engine: "openrouter" forces the OpenRouter sandbox on any model. Leave bash on its default and your app is asked to run the command locally — fine for a laptop agent, wrong for a phone desk that must not inherit the operator’s shell. Prefer the hosted engine when the blast radius should stay on OpenRouter’s side of the wire.

Network policy is the real product

Outbound network is off by default. That is the headline for ops, not the pricing line. For installs you set network_policy to an allowlist (e.g. PyPI hosts) or unrestricted *; the policy cannot change after the container starts. Allowlisted hosts are reachable on 80/443; everything else fails closed.

Pair shell with openrouter:web_search and you can keep the container offline while the model still pulls public context: search runs outside the sandbox, then the model writes files inside it. Same pattern as “agent never sees the password” — capability without widening the container’s egress.

Artifacts over chat transcript

Promote is the ops-friendly path. Container files live ~30 days; promoting copies them into workspace storage with a new or_file_ id you can attach to later runs or download. Uploads you send in are not downloadable later — keep your own copy. Treat the promoted file as the durable handoff: eval reports, scraped summaries, patched configs — not a long chat the next model must re-parse.

Pricing is simple enough to reason about: $0.0001 per active sandbox second, billed with the request (cold containers pay a 30s minimum); idle sleep after five minutes is not billed; Files API has no separate meter but workspace storage is capped (10 GiB). Token cost + sandbox time shows as separate rows on the request timeline — useful when flash loops chew seconds of shell.

How this maps to phone and ops agents

Production phone agents fail when secrets, tools, and model identity collapse into one process. Shell/Files push the opposite shape:

  1. Don’t put secrets in the sandbox. Attach only the files the job needs. CRM tokens, Telnyx keys, and calendar OAuth stay at your connector boundary — same lesson as Muse Secure VM / Sentinel surrogates.
  2. Treat the container like a credential boundary. Default-deny network, allowlist only what the job requires, lock the policy at start. If the model needs the open web, prefer web_search outside the container over opening egress.
  3. Flash for loops, shell for work. Weekly OpenRouter rankings through Sep 20: DeepSeek V4.1 Flash #1 (~15.8T, +219%), GLM 5.3 Flash #2 (~14.1T), Hy4 preview #3 (~12.5T), GPT-5.6 Luna #4 (~9.72T). Apps stay Hermes / Claude Code / Kilo / Cline heavy. Route flash models for the agent loop; let shell hold the durable compute so swapping Luna ↔ DeepSeek doesn’t rebuild your VM story.
  4. Promote before you trust. Downstream phone handoffs and ops tickets should point at promoted artifacts, not at “the model said it wrote a file.”

Secondary path still open: Twilio Agent Connect + GPT-Live-1 for the live phone surface — covered in the GPT-Live draft. Shell/Files sit one layer up: the desk that prepares context, runs evals, and ships artifacts without owning another fleet of sandboxes.

What I’d copy into a desk this week

  • Force engine: "openrouter" on any server-side agent path.
  • Start every container network-deny; open allowlists per job type, never globally.
  • Upload inputs → shell work → promote outputs; never treat chat as the archive.
  • Keep API keys and customer PII out of file_ids and out of prompts that land in the sandbox.
  • Watch the Sep 20 flash board as a routing signal, not a religion — volume moved; your eval bars did not.

Closing

Hosted shell is not “give the model root.” It is a replaceable compute surface with an explicit network policy and a promote step for artifacts. That is the same architectural bet as Secure VM credential surrogates and as HyperFrames locking render runtime in the proposal: name the boundary, keep secrets off the model, and let flash models churn without owning the blast radius.

Related drafts: Descript model-eval queue, Muse Secure VM credentials, OpenRouter rankings in production, OpenMontage + HyperFrames, GPT-Live voice, Cursor Projects stub. Comparing notes beats comparing logos. Say hello.

Sources: OpenRouter — Shell server tool & Files API (announced ~Sep 8, 2026); Shell server tool docs; Files API; Containers; OpenRouter rankings (usage through Sep 20, 2026); related Descript model-eval queue.