Skip to main content

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.

License required

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/stdout directly 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

ArgumentDescription
<source-dir>Path to the agent source directory

Options

OptionDefaultDescriptionEnv Var
--bundle-mcp-toolsfalseBundle 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][:rorw][:cwd]. Repeatable.
--mount-home-Mount host path into the agent HOME (/home/agent). Format: HOST[:RELATIVE][:rorw][: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-insecurefalseSkip TLS certificate verification for registry pulls; requires AGENTVISOR_TLS_ALLOW_INSECURE=true-
--sandbox-Sandbox mode: docker, none, gvisor (default: docker)AGENTVISOR_GUEST_SANDBOX
--verbosefalseKeep 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]
TokenDefaultDescription
HOST(required)Absolute or relative path on the host (resolved to absolute)
GUESTsame as HOSTMount point inside the sandbox
ro|rwroMount 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.

note

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:

  1. --workdir — explicit override (must be a subpath of the :cwd-marked mount if one exists)
  2. :cwd mount — the GUEST path of the mount marked with :cwd
  3. 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

SandboxSupportNotes
gvisorFullIn 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)FullStandard bind mount via Docker engine.
docker (macOS/Windows)FullThe HOST path must be within a folder shared with Docker Desktop (Preferences → Resources → File Sharing).
noneNot supportedError 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
note

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]
TokenDefaultDescription
HOST(required)Absolute or ~-expanded path on the host
RELATIVEbasename(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|rwroMount mode
cwd(unset)Set as the working directory when the command starts

The flag is repeatable. At most one mount may have :cwd.

tip

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/).

note

--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:

VariableExampleDescription
{{.Image}}ghcr.io/manetu/agentvisor/agentvisor-guest:v1.2.3-minimalFull base image reference (use in FROM)
{{.ImageRepo}}ghcr.io/manetu/agentvisor/agentvisor-guestRepository portion without tag
{{.ImageVersion}}v1.2.3Version portion of the tag (before variant suffix)
{{.ImageVariant}}minimalImage variant — minimal for exec mode, python for LangGraph agents
{{.HasRequirements}}trueWhether requirements.txt exists in the source directory
tip

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

ModeBehavior
DefaultSilent — error-only, nothing printed to terminal
--verboseInfo-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

FeatureAvailable in exec mode
HTTP proxy (with credential substitution)Yes
MCP gatewayYes
A2A gatewayYes
Key-value storeYes
Log forwardingYes
CheckpointingNo (no Temporal workflow)
SSE streamingNo (no HTTP API)

Exit Codes

The exec command propagates the exit code of the command running inside the sandbox:

CodeDescription
0Command completed successfully
NExit 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
danger

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