# How to Use the Shell Toolkit in AISuite for Safe Command Execution

> Safely execute OS commands with the AISuite shell toolkit. Learn how to leverage whitelisting and restrictions for secure command execution.

- Repository: [Andrew Ng/aisuite](https://github.com/andrewyng/aisuite)
- Tags: how-to-guide
- Published: 2026-06-16

---

**The shell toolkit in AISuite is a built-in tool that lets agents execute OS commands in a controlled environment with whitelisting, shell syntax restrictions, and configurable timeouts.**

The shell toolkit is a core component of the [andrewyng/aisuite](https://github.com/andrewyng/aisuite) repository that enables AI agents to interact with the operating system safely. Implemented in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py), this toolkit provides a `run_shell` interface wrapped in AISuite's standard tool contract, allowing seamless integration with agents while maintaining strict security controls. When instantiated, the toolkit returns a list containing a single callable tool that executes commands through the `ShellToolkit` class.

## Basic Setup and Import

To begin using the shell toolkit, import the `shell` function from the toolkit module. This function instantiates a `ShellToolkit` bound to a specific working directory and returns a list containing the `run_shell` tool.

```python
from aisuite.toolkits.shell import shell

# Instantiate with basic configuration

tools = shell(
    cwd="/tmp",
    allowed_commands=["ls", "cat"],
    allow_all=False,
    allow_shell=False,
)

run_shell = tools[0]

```

The `shell()` function accepts several parameters that control execution behavior, including the working directory (`cwd`), command whitelisting (`allowed_commands`), and shell syntax restrictions (`allow_shell`).

## Creating a Restricted Shell Environment

For secure operations, restrict the toolkit to specific commands and disable shell interpretation. The `ShellToolkit` class validates commands against an explicit whitelist in the `_validate_command` method, raising `PermissionError` for unauthorized commands.

```python
from aisuite.toolkits.shell import shell

# Only allow 'ls' and 'cat' commands

tools = shell(
    cwd="/tmp",
    allowed_commands=["ls", "cat"],
    allow_all=False,          # enforce the whitelist

    allow_shell=False,        # disallow complex shell syntax

)

run_shell = tools[0]

# Run an allowed command

result = run_shell("ls -l")
print("stdout:", result["stdout"])

# Attempting a disallowed command raises PermissionError

# run_shell("rm -rf /")  # Raises PermissionError

```

By default, the `_validate_no_shell_syntax` method parses commands using `shlex.split` and rejects any tokens matching `UNSUPPORTED_SHELL_TOKENS`. This prevents pipes, redirections, and multi-line commands unless explicitly enabled.

## Enabling Full Shell Mode

To execute complex shell commands with pipes or redirections, set `allow_shell=True`. This configures `subprocess.run` to invoke the native shell (Bash on POSIX, PowerShell on Windows) with `shell=self.allow_shell`.

```python
from aisuite.toolkits.shell import shell

tools = shell(
    cwd="/home/user",
    allow_all=True,           # allow any command

    allow_shell=True,         # enable full shell interpretation

    default_timeout_seconds=60,
)

run_shell = tools[0]

# Complex command with pipelines works now

result = run_shell("ps aux | grep python")
print(result["stdout"])

```

Use this mode with caution, as it bypasses the shell syntax restrictions and executes commands through the system's native shell interpreter.

## Security Features and Risk Classification

According to the source code in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py), the shell toolkit is classified as high risk. The returned tool metadata includes `risk_level="high"` and `requires_approval=True`, indicating that the AISuite UI will prompt for user approval before executing commands.

The toolkit implements multiple validation layers:

- **Working directory binding**: The `cwd` parameter is validated via `Path(cwd).expanduser().resolve()` to ensure the directory exists and is accessible.
- **Command whitelisting**: Unless `allow_all=True`, the `_validate_command` method checks commands against the `allowed_commands` list.
- **Shell syntax validation**: The `_validate_no_shell_syntax` method prevents unintended shell interpretation when `allow_shell=False`.

## Timeout Handling and Output Management

The `ShellToolkit` handles execution timeouts through `subprocess.run(..., timeout=timeout)`, where the default timeout is 30 seconds. When a command exceeds this limit, the toolkit catches `TimeoutExpired` and returns a structured result with `timed_out=True`.

Output truncation occurs automatically for large results. The `_output_value` method calls `_truncate` to limit stdout and stderr to `max_output_chars` (default 20,000 characters) unless an artifact store is active.

The tool returns a standardized dictionary with the following structure:

```python
{
    "run_shell": {
        "command": "...",
        "cwd": "...",
        "exit_code": int | None,
        "stdout": str,
        "stderr": str,
        "timed_out": bool,
    }
}

```

## Integration with AISuite Agents

The shell toolkit integrates seamlessly with AISuite agents by conforming to the tool contract defined in [`aisuite/agents/__init__.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/__init__.py). Pass the toolkit output directly to any agent expecting a list of tools.

```python
from aisuite.agents import Agent
from aisuite.toolkits.shell import shell

class MyAgent(Agent):
    def __init__(self):
        super().__init__(
            tools=shell(
                cwd=".", 
                allowed_commands=["echo"], 
                allow_all=False
            )
        )

agent = MyAgent()
agent.run("echo Hello AISuite")

```

## Summary

- The shell toolkit is implemented in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py) and provides the `run_shell` tool through the `ShellToolkit` class.
- **Command whitelisting** via `allowed_commands` and **shell syntax restrictions** via `allow_shell=False` provide defense-in-depth security.
- The toolkit binds to a specific working directory using `Path(cwd).expanduser().resolve()` and validates directory existence.
- **Timeout handling** defaults to 30 seconds but is configurable via `default_timeout_seconds`, returning `timed_out=True` when limits are exceeded.
- Output automatically truncates to `max_output_chars` (20,000) via the `_truncate` method.
- The tool requires user approval in the AISuite UI due to its `risk_level="high"` classification.

## Frequently Asked Questions

### How do I restrict which commands the shell toolkit can execute?

Use the `allowed_commands` parameter to specify an explicit whitelist of permitted commands. The `_validate_command` method in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py) checks each command against this list and raises `PermissionError` if the command is not included, unless you set `allow_all=True`.

### Can I use shell pipes and redirections with the AISuite shell toolkit?

By default, no. The toolkit's `_validate_no_shell_syntax` method uses `shlex.split` to detect and reject shell operators defined in `UNSUPPORTED_SHELL_TOKENS`. To enable pipes and redirections, instantiate the toolkit with `allow_shell=True`, which passes `shell=True` to `subprocess.run` and invokes the native system shell.

### What happens when a command exceeds the timeout limit?

When a command exceeds `default_timeout_seconds` (default 30 seconds), the toolkit catches the `TimeoutExpired` exception and returns a structured result with `timed_out=True`. The process is terminated, and you receive partial output along with the timeout status in the returned dictionary.

### Why does the shell toolkit require user approval?

According to the source code in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py), the toolkit metadata includes `risk_level="high"` and `requires_approval=True`. This classification ensures that users must explicitly approve command execution in the AISuite UI, preventing agents from running potentially destructive operations without oversight.