Tool

execute

When query and read together are not enough, drop into JavaScript with all the same data at hand. Compose what does not exist as a single tool; store the reusable part so the next composition is one import away.

You ask your agent “which files churn the most, and how many hands have been in them?” — this is the script it writes. Save the same script as hotspots.js and the shell form pipes it in.

Your agent calls — mcp

execute code="(async () => { const rows = await repoql.query(`SELECT uri, commits, authors FROM git_hotspots('file:///**') LIMIT 5`); return rows.map(r => ({ file: r.uri.split('/').pop(), commits: r.commits, authors: r.authors })); })()"

You call — cli

rql execute < hotspots.js

What comes back — the same on both surfaces

file commits authors ServeCommand.cs 126 3 RepoQL.Hosting.App.csproj 100 2 RepoQL.slnx 89 3 CLAUDE.md 86 2 changelog.md 69 3 [57 tok | 848 ms | ready]

Scripts run as a QuickJS–WASM module, so top-level return is a syntax error — wrap the body in an immediately-invoked function as above. Return plain values: objects and arrays render as tables, and --jsonl streams them for pipelines. The sandbox also renders — return repoql.graphviz(dot) and an SVG comes back instead of rows.

Parameters

ParameterWhat it does
coderequiredThe JavaScript to run.
intentoptionalA short line on what you are trying to accomplish. It should stand alone.
tokenBudgetoptionalRoom for the response.
timeoutoptionalExecution deadline in milliseconds.

What is in scope

In the sandboxWhat it does
repoql.query(sql)The full SQL surface, returning rows.
repoql.read(uri, opts)Any address, with its budget and representation.
repoql.write(uri, content) · repoql.delete(uri)Write results back into the sandbox for later steps.
repoql.graphviz(dot) · repoql.svgToPng(svg)Render diagrams from data you just computed.
repoql.ffmpeg({...})Probe or transform media.
mcp.servers() · mcp.tools(name) · mcp.<server>.<tool>(args)Call any approved MCP tool and get parsed results back.
import("yaml"), import("diff"), import("semver")Built-in modules, plus the others the sandbox ships.

When not to reach for it

If one SQL statement would do the job, write the statement. execute earns its place when the work is imperative — branching on intermediate values, accumulating across iterations, retrying — or when the output is not a table at all.

This page names what exists. The depth behind every name ships inside the binary at help:///: the bounds, the failure modes, how they compose. It answers to explore and read exactly like your code does. Install it, and your agent has the manual.