ctx_execute
Run code in a sandboxed subprocess across 12 languages; only what you print enters context.
ctx_execute runs code in an isolated subprocess and returns only what the code
prints to stdout. The raw inputs the code reads — files, command output, parsed
structures — stay inside the sandbox and never reach the context window. This is
how you derive an answer from data: filter, count, aggregate, parse, or transform
it, then print the conclusion.
The savings are direct. A scan that would otherwise pour 56 KB of raw bytes into context returns a 299 B summary instead — a 99.5% reduction.
Write a program that processes the data and prints the answer. The data stays in
the sandbox; only your console.log output enters context. See
Think in Code.
Languages
Twelve languages run in the sandbox: javascript, typescript, python,
shell, ruby, go, rust, php, perl, r, elixir, and csharp. For
JavaScript and TypeScript, Bun is auto-detected and used when present — it runs 3
to 5 times faster — and Node.js is the fallback.
Parameters
| Parameter | Required | Description |
|---|---|---|
language | yes | One of the 12 supported languages. |
code | yes | The program to run. Print only the answer. |
timeout | no | Max execution time in milliseconds. When omitted, no server-side timer fires and the MCP host's RPC timeout governs; pass an explicit value for long-running builds. |
intent | no | What you are looking for in the output. When the run prints a lot, this is the filter: it drives which auto-indexed sections come back, not just a label. |
cwd | no | Working directory for shell commands. Non-shell languages still run from their sandbox temp directory. |
background | no | Keep a long-running process alive instead of killing it on timeout. Defaults to false. |
When a run prints more than about 5 KB, the output is auto-indexed into the
knowledge base and only the sections matching your intent come back; the rest is
retrievable later with ctx_search. This is why intent
is the lever, not a label — phrase it with the terms you expect in the output.
Set background to true for processes you want to keep running, such as a dev
server, so they are not terminated when the timeout elapses.
In a background script, do not add setTimeout or any self-close timer — the
process must stay alive until the timeout detaches it. For a server-plus-fetch
pattern, prefer putting both the server and the fetch in a single ctx_execute
call rather than reaching for background.
Example
This run reads a directory of JSON files in the sandbox and prints only a summary. None of the file contents enter context.
const fs = require("fs");
const path = require("path");
const dir = "./data";
let files = 0;
let records = 0;
let failed = 0;
try {
for (const name of fs.readdirSync(dir)) {
if (!name.endsWith(".json")) continue;
files += 1;
try {
const parsed = JSON.parse(fs.readFileSync(path.join(dir, name), "utf8"));
records += Array.isArray(parsed) ? parsed.length : 1;
} catch {
failed += 1;
}
}
} catch (e) {
console.log("scan failed:", e && e.message);
}
console.log(`files=${files} records=${records} failed=${failed}`);Only the final line returns:
files=128 records=54210 failed=2The model gets the three numbers it needs and keeps the rest of its window free.
When to use it
Reach for ctx_execute whenever the goal is to learn something from data rather
than to quote the data back. Use Bash instead for a short fixed observation where
the output is already small. Use Write or Edit for any change to a file on disk:
the sandbox filesystem is discarded after each run, so mutations made here do not
persist.