Two tools, however many servers.
Loading every tool into the model’s context costs tokens on every call. Code mode loads two.
A client sees discover_tools and execute_code. It searches the catalogue only when it needs to.
Owners and admins can turn off Code Mode without turning off Direct Mode.
What each tool does.
discover_tools searches the services you have authorized. It returns matching tools, not the whole catalogue.
execute_code runs the model’s TypeScript against those typed tools. It can chain them. In the session above, 3 services are reached in 1 round trip.
Approval resumes the program. It does not repeat it.
Tool calls are not transactions. Restarting a program after an approval could repeat earlier changes. Instead, Rayrun:
- Pauses the exact QuickJS fiber and records the calls that completed.
- Resumes the same execution after approval. Earlier calls are not rerun.
- Rechecks policy, tool definition, client, and credential before dispatch.
- Ends the pause after a deploy, a restart, or its 10-minute lease. It reports the loss and never restarts code whose effects may already exist.
Clients with URL elicitation open the review page as part of the call. Browser and CLI fallbacks carry server-issued state, so a model cannot approve its own call. The exact-call approval boundary.
Safe reads can start early.
Speculative programmatic tool calling (sPTC) starts eligible read calls while the model is still writing execute_code. If the finished program makes the same call, the result is already waiting.
- Only tools approved as safe, read-only, and repeatable are eligible.
- The finished call rechecks the token, policy, definition, arguments, and credential. A mismatch runs normally.
- Rayrun Chat uses it automatically. Custom streaming harnesses get it through @rayrun/sdk. Codex and Claude Code connections do not use it.
sPTC was introduced by Alex Zhang. Rayrun adapts the MIT-licensed spec-ptc project for an MCP gateway. Integrate streamed run-ahead.
Authorization stays outside the sandbox.
The model can rewrite anything inside the runtime. It can name a tool. It cannot make a call.
- Allowlists, argument checks, budgets, and credentials never enter QuickJS.
- Every outbound call crosses the host broker and passes live policy checks.
- Model code runs in a credential-free Docker service with outbound networking off.
- Each execution gets a fresh seccomp-confined Node process and QuickJS VM with time, memory, call, and output limits. It is destroyed afterwards.
- Hosted hooks run in their own isolate, separate from model code. How hooks are bounded.
The service is a runc container on the host kernel, not a microVM. It limits ordinary failures and reduces the impact of an engine escape. Credentials stay outside it.
Every upstream call spends a workspace-wide daily budget, shared with Direct Mode. The default is 10,000 attempts per UTC day. Refused calls do not spend it.
When to use Direct Mode.
Use Direct Mode when the catalogue is small enough to load up front. The model calls the tool you see.
Point the client at /mcp/direct. The /mcp endpoint stays in Code Mode.
The same boundary from the terminal.
The Rayrun CLI describes and calls tools through the Direct Mode endpoint. If a call needs approval, the CLI opens the review page, saves the call, and prints a rayrun resume command.
- The CLI also configures supported MCP clients.
- It inspects connections, client policy, approvals, and Activity.
- People sign in with OAuth. CI uses a scoped API key.
The same pattern at scale.
Cloudflare calls this Code Mode. Anthropic calls it code execution with MCP. One call finds tools and another runs them.
Cloudflare exposes more than 2,500 API endpoints through 2 tools, in about 1,000 tokens. Rayrun applies the same pattern to your connected services.
Connect one server and watch it.
Rayrun records each discover_tools and execute_code call, plus every tool call underneath.
