Sandbox Shell Tool#
SandboxShellTool lets an agent run shell commands inside an environment you choose — a local subprocess, a Docker container, a Daytona or Tenki sandbox, or any custom backend. Unlike the provider-hosted ShellTool (which runs server-side, and only on OpenAI), it executes client-side, so it works with any model provider.
The design has two orthogonal pieces:
- The environment decides where commands run and carries all backend config (image, env vars, network, timeout, …).
- The tool decides the agent-facing policy (
allowed/blocked/ignore/readonly).
The same environment can back both a SandboxShellTool and a SandboxCodeTool.
Quick Start#
With no arguments, SandboxShellTool uses a LocalEnvironment with a temporary working directory that is cleaned up when the process exits.
Choosing an Environment#
The first argument is the environment. Pass a LocalEnvironment, DockerEnvironment, DaytonaEnvironment, or TenkiEnvironment:
A LocalEnvironment directory is created automatically if it does not exist, and is not deleted on exit when an explicit path is given.
Command Filtering#
Filtering policy lives on the tool, not the environment:
Tool Parameters#
| Parameter | Default | Description |
|---|---|---|
environment | None | Backend: LocalEnvironment / DockerEnvironment / DaytonaEnvironment / TenkiEnvironment. None → LocalEnvironment() |
allowed | None | Whitelist of command prefixes, matched word by word. Setting it switches on restricted mode. None → all commands allowed |
blocked | None | Blacklist of command prefixes. None → nothing blocked |
ignore | None | Gitignore-style path patterns. Commands referencing matching paths return "Access denied: <path>" |
readonly | False | When True and allowed is not set, restricts to a built-in list of commands that cannot write files or run programs (cat, ls, grep, …) in restricted mode |
LocalEnvironment Parameters#
| Parameter | Default | Description |
|---|---|---|
path | None | Working directory. None → temporary dir prefixed ag2_sandbox_, deleted on exit |
cleanup | None | None → auto (True when path=None, False otherwise) |
timeout | 60 | Per-command timeout in seconds. Returns an exit code 124 result on expiry |
max_output | 100_000 | Maximum characters in the returned output; truncated output gets a [truncated: …] suffix |
env_vars | None | Environment variables merged into every command |
Filter Order#
Filtering is applied in this order on every run_shell_command(command) call:
allowed— if set, the command must match at least one prefix and use no shell syntax (pipes, redirects, chaining). Otherwise:"Command not allowed: <cmd>".blocked— if set, the command must not match any prefix. Otherwise:"Command not allowed: <cmd>".ignore— literal file paths parsed from the command string are resolved and checked against the patterns. On match:"Access denied: <path>".- Execute — the command runs in the environment: through
sh -c, or as a plain argv in restricted mode.
Note
ignore checks only literal path tokens in the command string. Paths computed dynamically inside the shell (variable substitution, command substitution, glob expansion) are not inspected.
Read-Only Mode#
Use readonly=True to let the agent inspect files without modifying anything:
This restricts commands to cat, head, tail, ls, grep, wc, diff, stat, and a few others: only commands that have no option to write a file or run another program.
find, file and git are not in the list, because each can write or run programs through its arguments (find -exec, file -C, git diff --output, and programs named in .git/config). To give a read-only agent git log or find, list them in allowed. An explicit allowed replaces the built-in set, and what its commands can do is then your call:
For real isolation, use a DockerEnvironment, DaytonaEnvironment, or TenkiEnvironment.
Restricted Mode#
Setting allowed or readonly=True switches on restricted mode. The command is split into words once, the same way a POSIX shell quotes them, and that exact argv is checked and then run without a shell. Nothing can expand after the check, so none of these work:
- pipes, redirects and chaining (
|,>,<,;,&,&&,||, newlines), rejected with a clear error; - globs:
ls *.pypasses*.pytolsliterally, so usegrep -r --include='*.py'orlsinstead; - variables,
~, brace expansion and command substitution; - shell builtins:
echoandpwdrun the programs found onPATH.
Without allowed and readonly, commands run through sh -c with full shell syntax.
Accessing the Working Directory#
SandboxShellTool exposes the resolved working directory via the workdir property:
Stateful Multi-Turn Conversations#
Because files persist in workdir across ask() calls, the agent can build on prior work in a chained conversation:
Warning
A LocalEnvironment gives the agent direct access to your filesystem and the ability to run arbitrary commands. Always set allowed, blocked, or readonly when exposing it to untrusted prompts, or use a DockerEnvironment, DaytonaEnvironment, or TenkiEnvironment for real isolation.
SandboxShellTool vs ShellTool vs AnthropicBashTool#
SandboxShellTool | ShellTool | AnthropicBashTool | |
|---|---|---|---|
| Execution | Client-side, in your environment | Provider-side, in OpenAI's container | Client-side, in your environment |
| Provider support | Any provider | OpenAI only | Anthropic only |
| Tool definition | AG2's run_shell_command function | OpenAI's hosted shell | Anthropic's bash_20250124 |
| Environment control | Full (allowed, blocked, ignore, backend choice) | Limited (provider-dependent) | Full — same options as SandboxShellTool |
| Import | ag2.tools.SandboxShellTool | ag2.tools.ShellTool | ag2.tools.AnthropicBashTool |
AnthropicBashTool exists because Anthropic ships its own bash tool definition but does not run it. It reuses everything on this page for execution, so reach for it when you want Claude to use the tool it was trained on; reach for SandboxShellTool when the same agent code has to run against several providers. See Anthropic Bash.