Why Use Governed Runtime
Falling back to unrestricted shell access bypasses SDL-MCP’s policy layer.sdl.runtime.execute keeps command execution consistent with SDL policy:
- Executable allowlisting prevents unauthorized binaries from running
- CWD jailing confines execution to within the repo root
- Environment scrubbing passes only whitelisted environment variables to subprocesses
- Timeout enforcement prevents runaway processes
- Concurrency limits prevent resource exhaustion
- Full audit logging of every execution
runtimeExecute inside sdl.chain.
Supported Runtimes
16 runtimes are supported across Windows, Linux, and macOS.- Interpreted
- Compiled
| Runtime | Typical Executable | Common Uses |
|---|---|---|
node | node or bun | JavaScript tests, scripts, build tooling |
typescript | tsx / ts-node | TypeScript scripts without pre-compilation |
python | python3 / python | Tests, scripts, analysis, automation |
shell | bash / sh / cmd.exe / powershell | General command execution |
ruby | ruby | Ruby scripts and tests |
php | php | PHP scripts |
perl | perl | Perl scripts |
r | Rscript | R scripts and analysis |
elixir | elixir | Elixir scripts |
Code Mode vs Args Mode
sdl.runtime.execute supports two invocation styles:
- Args mode — pass the runtime and an
argsarray. SDL-MCP resolves the executable and spawns the process with those arguments. - Code mode — pass source code directly. SDL-MCP writes it to a temp file, compiles it if needed, and executes it.
The outputMode Parameter
The outputMode parameter controls how much output is returned in the response. This is the primary lever for controlling token consumption.
| Mode | Default | Est. Tokens | What You Get |
|---|---|---|---|
"minimal" | Yes | ~50 | {status, exitCode, signal, durationMs, outputLines, outputBytes, artifactHandle} — no stdout/stderr content |
"summary" | No | ~200–500 | Head + tail output excerpts (legacy behavior) |
"intent" | No | Variable | Only lines matching queryTerms — no head/tail summary |
- Use
minimal(the default) when you only need to know whether a command succeeded. Follow up withsdl.runtime.queryOutputto search the persisted artifact if the command failed. - Use
summaryto restore legacy behavior where head + tail excerpts are returned inline. Useful for short commands where you always want to see some output. - Use
intentwhen you providequeryTermsand only care about matching lines. No head/tail summary is included — only matched excerpts.
All modes enforce a 500-character per-line cap. Lines exceeding this are truncated with a
[truncated] suffix, preventing a single long line (such as minified JSON) from consuming the entire response budget.Two-Phase Pattern: Execute + Query
The recommended workflow for most runtime tasks:Execute with minimal output
Run the command and receive a lightweight status response with an Response (~50 tokens):
artifactHandle.Check the exit code
If
exitCode is 0, the command succeeded. Move on without reading any output — zero tokens spent on content you don’t need.sdl.runtime.queryOutput
Retrieves and searches stored runtime output artifacts on demand. Use this after an outputMode: "minimal" execution to inspect specific parts of the output without loading it all into context.
| Parameter | Type | Required | Description |
|---|---|---|---|
artifactHandle | string | Yes | Handle returned by sdl.runtime.execute |
queryTerms | string[] | Yes | Keywords to search for in the output |
maxExcerpts | integer | No | Maximum excerpt windows to return (default: 10) |
contextLines | integer | No | Lines of context around each match (default: 3) |
stream | string | No | "stdout", "stderr", or "both" (default: "both") |
Security Model
Every runtime request passes through SDL-MCP governance in order:- Feature gate —
runtime.enabledmust betrue - Allowed runtime check — runtime must be in
allowedRuntimes - Executable validation — executable must be compatible with the chosen runtime
- CWD jailing — working directory must be within the repo root
- Environment scrubbing — only
PATHand explicitly allowlisted env vars are passed to the subprocess - Timeout and output caps — hard limits on duration, stdout bytes, and stderr bytes
- Concurrency limits — maximum concurrent jobs enforced
Configuration
Real Examples
- Run tests
- Run a linter
- Run a Python script
- Go program
SDL-First Guidance
When SDL-MCP is configured for agent enforcement:- Prefer
runtimeExecuteinsidesdl.chainover native shell tools - Prefer the two-phase pattern:
outputMode: "minimal"thensdl.runtime.queryOutputon demand - Prefer structured query terms over dumping large output back to the model
- Use
shellonly when a shell is genuinely necessary, not as a default catch-all runtime