Tool System Architecture

Tools are what make the agent agentic. The agent_tools.py module defines a modular execution framework where each tool is an AgentTool dataclass with a name, description, JSON schema parameters, and a handler function.

Tool Execution Flow

Model requests tool call
  → Look up tool by name in registry
    → Preflight checks (plugin hooks, policy validation)
      → Permission enforcement (read/write/shell gates)
        → Execute handler with arguments and context
          → Post-execution hooks (result injection, metadata)
            → Return ToolExecutionResult to session

The ToolExecutionContext (frozen dataclass) provides each handler with: root workspace path, command timeouts, permission flags, and references to all runtime systems (search, accounts, MCP, etc.).

Tool Registry

Claw Code Agent ships 60+ built-in tools organized into categories:

File Operations

ToolPurpose
list_dirDirectory listing with pagination
read_fileFile reading with line range support
write_fileFile creation with SHA256 tracking
edit_fileText replacement with occurrence counting
notebook_editJupyter notebook cell manipulation

Search and Retrieval

ToolPurpose
glob_searchFile pattern matching
grep_searchRegex/literal text search across files
web_fetchHTTP/HTTPS resource retrieval
web_searchMulti-provider web search
tool_searchTool registry discovery

Execution

ToolPurpose
bashShell command execution with timeout and security validation
sleepBounded wait (0–5 seconds max)

Account and Configuration

ToolPurpose
account_statusProfile status display
account_login / account_logoutIdentity activation/clearing
config_list / config_get / config_setConfiguration management via dotted paths

MCP Integration

ToolPurpose
mcp_list_resourcesResource discovery
mcp_read_resourceURI-based resource retrieval
mcp_list_toolsExposed tool enumeration
mcp_call_toolTool invocation over transport

Task and Planning

ToolPurpose
task_list / task_get / task_create / task_updateFull task lifecycle
task_start / task_complete / task_block / task_cancelStatus transitions
plan_get / update_plan / plan_clearMulti-step plan management
todo_writeBulk todo list replacement

Collaboration

ToolPurpose
team_list / team_create / team_deleteTeam management
send_message / team_messagesMessage persistence and history
delegate_agentNested agent delegation
ask_user_questionInteractive user prompts

Infrastructure

ToolPurpose
worktree_enter / worktree_exit / worktree_statusGit worktree management
workflow_list / workflow_runManifest-backed workflow execution
remote_connect / remote_disconnect / remote_statusRemote profile management
search_activate_provider / search_list_providersSearch backend switching

Output Management

Large tool outputs are handled by _truncate_output(), which splits content into head and tail sections. _snapshot_text() normalizes whitespace and clips at 240 characters for previews. All output respects the max_output_chars context limit.

Permission Model

Permissions are enforced at the tool level through a tiered system:

TierFlagAllows
Read-only(default)list_dir, read_file, glob_search, grep_search
Write--allow-writeFile creation, editing, and deletion
Shell--allow-shellShell command execution
Unsafe--unsafeDestructive operations (force push, rm -rf, etc.)

Permission checks are enforced by two gate functions:

  • _ensure_write_allowed() — Verifies allow_file_write before any file modification
  • _ensure_shell_allowed() — Validates command safety and checks allow_shell_commands

Three exception types enforce safety boundaries:

ExceptionTrigger
ToolPermissionErrorPermission tier violation
ToolExecutionErrorInvalid input or state
OSError / SubprocessErrorSystem-level failures

All exceptions return structured ToolExecutionResult with metadata for the agent to reason about.

Bash Security System

The bash_security.py module is one of the most sophisticated components, implementing 18 validators with 163 tests. Every shell command passes through this system before execution.

Validation Architecture

The bash_command_is_safe() entry point constructs a ValidationContext:

ValidationContext
├── original_command        # Raw input
├── base_command            # First token
├── unquoted_content        # Text outside single quotes
├── fully_unquoted_content  # Text outside all quotes, redirections stripped
└── unquoted_keep_quote_chars  # Preserves quote chars for analysis

Security Outcomes

OutcomeMeaning
ALLOWSafe command, auto-approve
ASKRequires user confirmation
DENYBlocked outright
PASSTHROUGHCheck passed, continue to next validator

Injection and Obfuscation Detection

The system blocks multiple attack vectors:

  • Command substitution — Backticks, $(), ${}, and process substitution <()
  • ANSI-C quoting$'...' patterns that can hide characters
  • Zsh-specific expansions — Format-specific shell escapes
  • IFS manipulation — Internal Field Separator attacks
  • Process environment access/proc/*/environ reads

Parser-Differential Detection

Validators detect scenarios where different shells would interpret commands differently:

  • Control characters (0x00–0x08, 0x0E–0x1F, 0x7F)
  • Carriage returns outside quoted strings
  • Unicode whitespace characters
  • Backslash-escaped operators/whitespace
  • Mid-word hash characters in unquoted context

Misparsing concerns take higher priority than other issues and are blocked even when marked for user confirmation.

Destructive Command Detection

The get_destructive_command_warning() function matches against 20+ patterns:

CategoryExamples
Gitreset --hard, push --force, clean -f, stash drop
FilesRecursive rm -rf
DatabaseDROP TABLE, DELETE FROM
Infrastructurekubectl delete, terraform destroy

Special Command Handling

Certain commands receive bespoke validation:

CommandSafe WhenDangerous When
git commitSimple -m 'message'Complex flags
jqNormal filtersContains system()
sedStream modeIn-place editing (-i)
findBasic search-exec, -delete flags
python / node--version, --help, -cArbitrary scripts

Validation Flow

  1. Early validators check for empty commands, incomplete fragments, and known-safe patterns
  2. Main validators run sequentially, deferring non-misparsing concerns
  3. Misparsing validators return immediately with higher priority
  4. Deferred results are evaluated only if no misparsing issues were detected

The final gate, check_shell_security(), enforces shell enablement flags and returns an (allowed: bool, message: str) tuple to the tool execution layer.

Hook Policy System

The hook_policy.py module provides manifest-based security policies that layer on top of the permission model.

Policy Manifests

HookPolicyManifest dataclasses store configuration across multiple domains:

FieldPurpose
managed_settingsKey-value pairs for configuration control
safe_env_namesEnvironment variables permitted for access
budget_overridesToken and cost limit adjustments
deny_toolsExact-match tool blocking
deny_tool_prefixesPrefix-based tool blocking
Hook messagesInjected guidance at various execution phases

Trust Determination

The is_trusted() method evaluates all loaded manifests, returning the last explicit trust value. If no manifest sets trust explicitly, the system defaults to trusted.

Tool Denial

denied_tool_message() checks two mechanisms:

  1. Exact match — Lowercased tool name against deny_tools tuple
  2. Prefix match — Tool name against deny_tool_prefixes entries

When blocked, the system returns a message identifying the tool and responsible policy file.

Hook Execution Points

PhaseMethodPurpose
Before toolbefore_tool_messages()Preflight guidance injection
After toolafter_tool_messages()Postflight result augmentation
Wildcard'*' key routingDefault messages for all tools

Messages concatenate across all applicable manifests, enabling layered policy composition.

References