agentvisor exec
Start an interactive terminal session inside an AgentVisor sandbox.
Synopsis
agentvisor exec [flags] <source-dir>
Description
The exec command provides a shell-like experience inside the sandbox environment, useful for running interactive tools (Claude Code, Cursor, Aider), debugging, or executing one-off commands.
agentvisor exec requires a valid Manetu license key. On a TTY the CLI prompts interactively on first run; set AGENTVISOR_LICENSE_KEY for automated or headless environments. See the Licensing guide and https://manetu.com/agentvisor to obtain a key.
Unlike serve, this command:
- Does not start Temporal workflows or the HTTP API
- Bridges
stdin/stdoutdirectly to the sandbox - Returns the exit code from the executed command
All policy enforcement remains active: the HTTP proxy intercepts outbound traffic, and MCP, A2A, and Store downcalls are available to the running process.
By default, exec is silent — no logs appear on the terminal so they don't pollute the interactive session. Use --log-file or --verbose to see runtime logs.
Arguments
| Argument | Description |
|---|---|
<source-dir> | Path to the agent source directory |
Options
| Option | Default | Description | Env Var |
|---|---|---|---|
--bundle-mcp-tools | false | Bundle MCP tools rootfs into a temporary directory for local-launch (gvisor/docker only) | - |
--command | - | Command to execute in the sandbox (default: shell) | - |
--env-files | - | Comma-separated paths to .env files; later files override earlier (auto-discovers .env in source-dir if not specified) | AGENTVISOR_GUEST_ENVIRONMENT_FILES |
--guest-image | - | Guest base image (default: ghcr.io/manetu/agentvisor/agentvisor-guest:<version>-<type>) | - |
--image | - | Pre-built guest OCI image reference (alternative to source directory) | - |
--interpreter | - | Override detected interpreter (e.g., python3.12) | - |
--log-file | - | Redirect all logs to file (default: silent) | - |
--mcp-tools-image | - | MCP tools OCI image for bundling (default: ghcr.io/manetu/agentvisor/agentvisor-mcp-tools:<version>) | - |
--mount | - | Mount host path into sandbox. Format: HOST[:GUEST][:ro | rw][:cwd]. Repeatable. |
--mount-home | - | Mount host path into the agent HOME (/home/agent). Format: HOST[:RELATIVE][:ro | rw][:cwd]. RELATIVE is resolved relative to /home/agent; if omitted, basename(HOST) is used; use HOST::opts (empty RELATIVE) to mount HOST directly as HOME. Repeatable. |
--policy | - | Path to policy domain YAML file(s), comma-separated | - |
--registry-ca-data | - | Base64-encoded PEM CA certificate to trust when pulling guest/mcp-tools images (alternative to --registry-ca-file) | - |
--registry-ca-file | - | Path to a PEM CA certificate to trust when pulling guest/mcp-tools images from a private registry | - |
--registry-insecure | false | Skip TLS certificate verification for registry pulls; requires AGENTVISOR_TLS_ALLOW_INSECURE=true | - |
--sandbox | - | Sandbox mode: docker, none, gvisor (default: docker) | AGENTVISOR_GUEST_SANDBOX |
--verbose | false | Keep stderr logging on through the full session (default: silent once agent is interactive) | - |
--workdir | - | Working directory inside the sandbox | - |
Mounting Host Paths
Use --mount to bind-mount a directory from the host into the sandbox. Mounts are configured
by the operator and subject to MPE authorization before the sandbox starts.
Syntax
--mount HOST[:GUEST][:ro|rw][:cwd]
| Token | Default | Description |
|---|---|---|
HOST | (required) | Absolute or relative path on the host (resolved to absolute) |
GUEST | same as HOST | Mount point inside the sandbox |
ro|rw | ro | Mount mode: read-only or read-write |
cwd | (unset) | Set as the working directory when the command starts |
The flag is repeatable. At most one mount may have :cwd.
Windows host paths (e.g., C:\path\to\dir) are not supported; HOST must be a Unix-style path.
Working Directory Resolution
The initial working directory inside the sandbox is determined in this priority order:
--workdir— explicit override (must be a subpath of the:cwd-marked mount if one exists):cwdmount — theGUESTpath of the mount marked with:cwd- Sandbox default — whatever the container image specifies
If --workdir is set but does not fall under the :cwd mount, a warning is logged and --workdir wins.
Sandbox Caveats
| Sandbox | Support | Notes |
|---|---|---|
gvisor | Full | In rootless mode, UID mapping is applied — files appear owned by the sandbox UID. Performance over the 9P gofer may be lower than native I/O. |
docker (Linux) | Full | Standard bind mount via Docker engine. |
docker (macOS/Windows) | Full | The HOST path must be within a folder shared with Docker Desktop (Preferences → Resources → File Sharing). |
none | Not supported | Error at startup — none mode already has full host filesystem access; use it directly. |
Examples
# Mount a project read-write, starting inside it
agentvisor exec . --mount ~/myproject:/work:rw:cwd
# Read-only reference data alongside a read-write workspace
agentvisor exec . \\
--mount ~/myproject:/work:rw:cwd \\
--mount ~/datasets:/data:ro
# Image-based exec with a mounted project
agentvisor exec . --image my-custom-guest:latest --mount ~/myproject:/work:rw:cwd
# Override the starting directory to a subdirectory of the mount
agentvisor exec . --mount ~/myproject:/work:rw:cwd --workdir /work/src
Mounts can also be declared in mav-agent-config.yaml under a mounts: key. CLI --mount flags
override config-file mounts that share the same guest path.
Mounting Into Agent HOME (--mount-home)
The --mount-home flag is sugar over --mount for paths relative to the agent's
stable HOME directory (/home/agent). Use it to give coding agents like Claude Code
a persistent home without having to know the internal path.
Syntax
--mount-home HOST[:RELATIVE][:ro|rw][:cwd]
| Token | Default | Description |
|---|---|---|
HOST | (required) | Absolute or ~-expanded path on the host |
RELATIVE | basename(HOST) | Subdirectory under /home/agent to mount at. Omit (no colon) for basename. Empty (double colon HOST::) to mount HOST directly as /home/agent. |
ro|rw | ro | Mount mode |
cwd | (unset) | Set as the working directory when the command starts |
The flag is repeatable. At most one mount may have :cwd.
Use HOST::rw (empty RELATIVE, double colon) when a coding agent writes state to
$HOME root (e.g. ~/.claude.json). Use HOST:.claude:rw when the agent only
needs a subdirectory (~/.claude/).
--sandbox=none does not support --mount-home (the sandbox already has full host filesystem access).
Examples
# Persist the entire Claude Code HOME across sessions (writes ~/.claude.json at root)
agentvisor exec . --mount-home ~/.claude-home::rw
# Persist only the .claude config subdirectory
agentvisor exec . --mount-home ~/.config/claude-code:.claude:rw
# Persist .claude config AND mount a project read-write
agentvisor exec . \
--mount-home ~/.claude-home::rw \
--mount ~/myproject:/work:rw:cwd
# Read-only reference data from home dir
agentvisor exec . --mount-home ~/shared-prompts:.prompts:ro
Customizing the Sandbox Environment
Three layers of environment customization are available, from least to most invasive:
1. Environment Variables
Add per-session variables in mav-agent-config.yaml:
framework:
command: ["bash"]
env:
TERM: xterm-256color
MY_TOOL_CONFIG: /app/agent/config.json
See Project Anatomy — Framework Configuration for full precedence rules.
2. .env Files
Pass secrets and per-environment values without embedding them in config:
agentvisor exec . --env-files .env.local
A .env file in the source directory is auto-discovered if --env-files is not specified.
3. Custom Dockerfile
To install packages or layer additional tools into the guest image, place a Dockerfile in the agent source directory (next to mav-agent-config.yaml). It overrides the embedded minimal template and is processed through the same build pipeline:
FROM {{.Image}}
# The agentvisor-guest base image is built on ubi9/ubi-minimal — use microdnf, not apt-get.
RUN microdnf install -y wget git && microdnf clean all
COPY agent /app/agent
The file is processed as a Go text/template. These variables are available:
| Variable | Example | Description |
|---|---|---|
{{.Image}} | ghcr.io/manetu/agentvisor/agentvisor-guest:v1.2.3-minimal | Full base image reference (use in FROM) |
{{.ImageRepo}} | ghcr.io/manetu/agentvisor/agentvisor-guest | Repository portion without tag |
{{.ImageVersion}} | v1.2.3 | Version portion of the tag (before variant suffix) |
{{.ImageVariant}} | minimal | Image variant — minimal for exec mode, python for LangGraph agents |
{{.HasRequirements}} | true | Whether requirements.txt exists in the source directory |
The same Dockerfile override mechanism applies to agentvisor build — the same file is used when building production images. See agentvisor build for details.
4. Pre-built Image
Skip the build step entirely with a fully custom guest image:
agentvisor exec ./my-agent --image my-custom-guest:latest
This is useful for airgapped environments or when the image is built in a separate pipeline.
Sandboxing stdio MCP Servers
When mav-agent-config.yaml configures stdio MCP servers and --sandbox is gvisor or docker, each server runs in its own mcp-tools sandbox. Use --bundle-mcp-tools to pre-extract the rootfs before the session, and mcp.prepull in mav-agent-config.yaml to pre-install packages. See the agentvisor serve docs for the full explanation.
Examples
Basic Interactive Shell
agentvisor exec ./my-agent
Run a Specific Command
agentvisor exec ./my-agent --command "bash"
agentvisor exec ./my-agent --command "python3 -c 'print(1+1)'"
Run Claude Code Inside the Sandbox
agentvisor exec ./my-agent --command "claude --dangerously-skip-permissions"
Run Claude Code with Persistent HOME
# Persist Claude Code config and session data across exec runs
agentvisor exec ./my-claude-agent --mount-home ~/.claude-home::rw
With a Specific Sandbox Mode
# Docker (default on macOS/Windows)
agentvisor exec ./my-agent --sandbox=docker
# No isolation (fastest, for local debugging)
agentvisor exec ./my-agent --sandbox=none
# gVisor (Linux only, strongest isolation)
agentvisor exec ./my-agent --sandbox=gvisor
With Policy Files
agentvisor exec ./my-agent --policy ./policies/domain.yml
Redirect Logs to File (Keep Terminal Clean)
agentvisor exec ./my-agent --log-file /tmp/agentvisor.log
Enable Verbose Logging to Stderr
agentvisor exec ./my-agent --verbose
Logging Behavior
| Mode | Behavior |
|---|---|
| Default | Silent — error-only, nothing printed to terminal |
--verbose | Info-level logs to stderr |
--log-file <path> | Info-level logs written to file (terminal stays clean) |
The silent default ensures that interactive tools (shells, Claude Code) receive a clean TTY without spurious log output mixed in.
Available Downcalls
| Feature | Available in exec mode |
|---|---|
| HTTP proxy (with credential substitution) | Yes |
| MCP gateway | Yes |
| A2A gateway | Yes |
| Key-value store | Yes |
| Log forwarding | Yes |
| Checkpointing | No (no Temporal workflow) |
| SSE streaming | No (no HTTP API) |
Exit Codes
The exec command propagates the exit code of the command running inside the sandbox:
| Code | Description |
|---|---|
| 0 | Command completed successfully |
| N | Exit code from the sandboxed command |
Signals (SIGINT, SIGTERM) are forwarded into the sandbox and cancel the session cleanly.
Build Integration
For production use or stronger isolation, build a self-contained OCI image with agentvisor build and run it interactively with docker run -it. The image's entrypoint (agentvisor-host-runtime) takes no command-line arguments — trailing docker run args like exec ... --command ... are silently ignored. Whether the container runs in exec mode (and which command it runs) is decided at build time, not run time, via framework.provider: interactive and framework.command in mav-agent-config.yaml:
# mav-agent-config.yaml
framework:
provider: interactive
command: ["claude", "--dangerously-skip-permissions"]
# Build the image (embeds host and guest runtimes; bakes in exec mode
# because framework.provider is "interactive")
agentvisor build . -t my-agent:latest
# Run interactively with gVisor isolation
docker run -it --rm \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-v $(pwd)/policies:/etc/agentvisor/policies:ro \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/etc/agentvisor/policies/domain.yml \
-e MY_API_KEY \
my-agent:latest
At startup, the runtime dispatches on the AGENTVISOR_EXEC_MODE environment variable — agentvisor build sets it automatically when framework.provider: interactive is configured (or the guest image otherwise carries the exec-mode label). Images built from other providers (e.g. LangGraph) run in serve mode by default when started this way.
Troubleshooting
Terminal appears corrupted after exit
If the sandbox process exits abnormally, your terminal's raw mode may not be restored. Run reset to restore terminal settings:
reset
Policy denied errors inside the sandbox
Check that the policy file allows the HTTP endpoints your tool needs to reach:
AGENTVISOR_LOG_LEVEL=debug agentvisor exec ./my-agent --verbose
For development only, bypass authorization:
AGENTVISOR_AUTHZ_TYPE=allowall agentvisor exec ./my-agent
Never use AGENTVISOR_AUTHZ_TYPE=allowall in production.
Debugging built images (agentvisor build + docker run -it)
This section assumes an image built with framework.provider: interactive (see Build Integration above), so AGENTVISOR_EXEC_MODE=1 was baked in at build time. In exec mode, startup errors are suppressed to keep the terminal clean — only ERROR-level messages reach stderr, and INFO/DEBUG logs are silenced entirely.
If the container exits immediately or behaves unexpectedly, redirect all logs to stderr using AGENTVISOR_EXEC_LOG_FILE:
docker run -it --rm \
-e AGENTVISOR_EXEC_LOG_FILE=/dev/stderr \
-e AGENTVISOR_AUTHZ_TYPE=allowall \
my-agent:latest
This reveals startup errors that would otherwise be invisible, such as missing required environment variables:
level=ERROR msg="failed to create runtime" error="authz type is required..."
Once you've identified the issue, set the required variables and remove AGENTVISOR_EXEC_LOG_FILE for normal operation:
docker run -it --rm \
-v $(pwd)/policies:/etc/agentvisor/policies:ro \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/etc/agentvisor/policies/domain.yml \
-e MY_API_KEY \
my-agent:latest
See Also
- agentvisor serve - Long-running server mode with Temporal and HTTP API
- agentvisor run - Single agent execution (non-interactive)
- Sandbox Modes - Isolation levels and when to use each