Onumia

Command Runtime

View as Markdown

The execute MCP tool runs a single command inside an Onumia sandbox. There is no host shell behind it. Every command is parsed by a pure-PHP bash runtime, classified as read, write, or eval, and checked against your effective capabilities before a single byte of work happens.

This page explains how that runtime works, what it can run, and where the boundaries sit. Once you understand the classification model, the rest of the surface follows naturally: read commands are always available, writes and eval are opt-in, and the sandbox is the only place anything happens.

How A Command Is Run

When you call execute, Onumia runs the command with its own bash runtime rather than handing it to an operating system shell. Words, quoting, pipelines, redirection, variables, and globbing are all supported, but there is no fork, no subprocess, and no path to arbitrary host binaries. Everything the runtime can do is something Onumia has implemented and chosen to expose.

A minimal call looks like this:

execute({
  "sandbox_id": "ow_...",
  "command": "on help"
})

Three things must be true for any execution to proceed. The command must be non-empty, the sandbox_id must point to an active sandbox you can access, and you must hold at least execute_read. From there, the specific capability that gets checked depends on what the command actually does, which is decided by classification.

Working Directory

Commands run against a virtual filesystem rooted at the sandbox. The optional cwd field selects a starting directory inside that filesystem and defaults to /. Relative paths in your command are resolved against the resolved cwd, and the runtime normalizes path traversal so that .. segments can never climb above the sandbox root. A command cannot reach production directories, other sandboxes, or the host because those paths simply do not exist in the virtual filesystem it sees.

Command Classification

Before anything runs, Onumia classifies the command and uses that classification to decide which capability is required. Classification is deliberately conservative: a command is treated as a write or an eval whenever it might be one, never the other way around.

The classifier looks for three things. It first checks whether the command invokes wp eval or wp eval-file, which is always treated as eval. It then checks for shell writes, which include the mutating file commands (cp, mv, rm, rmdir, mkdir, touch, tee, chmod, ln), any output redirection (> or >>), and in-place sed -i. Finally, it inspects any wp subcommand against an allowlist of known read-only WordPress commands; anything not on that list is assumed to write. If none of those apply, the command is read-only.

Classification Meaning Required capabilities
read_only Inspects the sandbox without changing it. execute_read
sandbox_write Writes sandbox files or sandbox database rows. execute_read and execute_write
eval Runs wp eval or wp eval-file. execute_read and execute_eval

Because the model errs toward caution, a command that Onumia cannot confidently prove is read-only is classified as a write and will require execute_write. This is intentional. It is safer to ask for a capability you already have than to let an ambiguous command run with too little oversight.

Built-In Shell Utilities

The runtime ships a substantial set of process-free utilities that behave like their Unix counterparts but are implemented entirely in PHP. They cover most of what you need to navigate and analyze a WordPress codebase.

For inspecting the filesystem you have cat, ls, find, head, tail, stat, wc, du, tree, diff, basename, dirname, and readlink. For working with text there is grep, sed, awk, sort, uniq, cut, tr, nl, rev, tac, xargs, strings, split, fold, expand, and unexpand. Data helpers include jq, base64, md5sum, sha1sum, and sha256sum, and environment helpers include env (also available as printenv), date, whoami, hostname, seq, expr, sleep, and which. The interpreter itself provides the usual shell built-ins such as cd, echo, printf, export, set, test, true, and false, along with pipelines, command substitution, and globbing.

All of these are read-only by default, so they run under execute_read. The commands that change the filesystem are the exception. Writable file operations such as cp, mv, rm, rmdir, mkdir, touch, tee, chmod, and ln, together with any redirection or in-place editing, are classified as writes and require execute_write.

The on Command

The on namespace holds Onumia’s own commands. It is the place where Onumia adds capabilities that are aware of WordPress structure and the sandbox layout, rather than reimplementing generic Unix tools.

You can discover what is available without leaving the runtime. Running on help lists the registered Onumia commands and reminds you that wp is also available, and on help <command> prints command-specific usage:

on help
on help rg

on rg

The first on command is on rg, a fast code and content search built for WordPress-shaped roots. It understands the conventional layout of a WordPress install, so instead of pointing it at directories you point it at scopes.

on rg "register_post_type"
on rg --plugins "woocommerce"
on rg --themes "wp_footer"
on rg --files --content
on rg --all -i "onumia"

Scope flags decide where the search runs. --core targets WordPress core files, --plugins and --themes target their respective directories under wp-content, --content covers both plugins and themes, and --all combines core and content. You can also name a scope explicitly with --scope <name> or search a specific directory with --path <path>. When you pass neither a scope nor a path, on rg defaults to --content, which is the most common search target.

The matching options mirror the familiar ripgrep flags. Use -F for fixed strings, -i to ignore case, -w to match whole words, -n for line numbers, and -H or -I to force filenames on or off. To shape the result set, -l lists only files with matches and -c prints match counts, while --files lists files without searching their contents at all. You can narrow or widen the file set with --glob <pattern>, --hidden, and --no-ignore.

Git metadata is deliberately out of reach: .git paths are not available to on rg, so the command cannot read repository internals even when they exist on disk.

The wp Command

WP-CLI is available through wp, running in the context of the selected sandbox. Onumia injects the sandbox site URL and environment automatically, so you operate on the sandbox’s WordPress state without ever specifying a site:

wp help
wp core version
wp option get siteurl
wp post list --post_type=page

Site Selection Is Locked

To keep a command from quietly switching away from the sandbox it was issued against, Onumia rejects any flag that would override site selection. The flags --url, --blog, --network, and --network-wide are all blocked. This guarantees that every wp command stays inside the sandbox context Onumia set up for it.

Capabilities Follow The Command

WP-CLI commands are classified the same way everything else is. Read commands, the ones on Onumia’s known read-only allowlist such as wp option get, wp post list, or wp core version, run under execute_read. Any wp command that mutates state requires execute_write. The wp eval and wp eval-file commands are special: they always require execute_eval and are routed through Onumia’s safe eval path described below.

Safe Eval

Running arbitrary PHP is the most powerful thing an agent can do, so wp eval and wp eval-file are gated behind execute_eval and additionally constrained by a static safety policy. Before any PHP runs, Onumia checks it against that policy and rejects the submission outright if it finds a disallowed construct.

The policy blocks the building blocks of sandbox escape and host interaction. It refuses PHP’s own eval(), shell execution, file includes, and any call that would terminate the request. It blocks process and shell functions, dynamic and deferred dispatch where the target cannot be resolved statically, and multisite lifecycle calls so eval cannot reach across sites. Direct instantiation of filesystem, archive, database, XML, SOAP, image, and FFI classes is also refused.

Filesystem access is not removed, only confined. The eval runtime rewrites filesystem calls through a guard that resolves every path against the active sandbox data root and rejects anything that would resolve outside it or touch .git metadata. Code can read and write files where the sandbox allows it, but it cannot reach the host or another sandbox.

Within those limits, ordinary WordPress APIs work as expected. Calling update_option(...), querying posts, or using the rest of the WordPress API is perfectly acceptable inside a sandbox, because the sandbox database prefix is active and those writes land in the sandbox’s isolated state rather than on the live site.

Output

Every execution returns a structured result rather than a bare string. Alongside stdout, stderr, and the integer exit_code, the response includes the sandbox_id, the command classification, the resolved cwd, and the effective capabilities that were in force. This gives an agent everything it needs to reason about what ran and under what permissions.

Treat stderr and non-zero exit codes as signal, not noise. When a command fails or warns, surface the relevant output to the user instead of hiding it; the runtime reports these faithfully so that the agent can do the same.