Connect an LLM
An LLM should not execute generated code directly on the host. Route tool calls through a sandbox, validate the request, apply a timeout, and redact output before returning it to the model.
Minimal shape
Section titled “Minimal shape”model tool call -> app validates request -> mvm sandbox command -> app redacts stdout/stderr -> model receives bounded resultMinimal wrappers
Section titled “Minimal wrappers”import jsonimport subprocess
def run_code(code: str) -> dict: if len(code) > 20_000: raise ValueError("tool input too large")
proc = subprocess.run( ["mvmctl", "run", "--timeout", "10", "--", "python", "-c", code], check=False, text=True, capture_output=True, ) return { "exit_code": proc.returncode, "stdout": proc.stdout[-8000:], "stderr": proc.stderr[-8000:], }
print(json.dumps(run_code("print(2 + 2)")))import { spawnSync } from "node:child_process";
function runCode(code: string) { if (code.length > 20_000) { throw new Error("tool input too large"); }
const proc = spawnSync("mvmctl", ["run", "--timeout", "10", "--", "node", "-e", code], { encoding: "utf8", });
return { exit_code: proc.status ?? 1, stdout: proc.stdout.slice(-8000), stderr: proc.stderr.slice(-8000), };}
console.log(JSON.stringify(runCode("console.log(2 + 2)")));For repeated calls, build and boot a named sandbox instead:
mvmctl init ./llm-tool --preset pythonmvmctl build ./llm-toolmvmctl up ./llm-tool --name llm-toolmvmctl exec llm-tool -- python /work/tool.pySecurity checklist
Section titled “Security checklist”- Validate the tool schema before invoking
mvmctl. - Set a timeout.
- Default to no network access unless the tool needs a named endpoint.
- Do not pass secrets through command-line args.
- Treat stdout and stderr as untrusted model-visible data.
- Store receipts or audit identifiers with the model trace when available.