NAME

Claude::Agent::DryRun - Dry-run mode support for Claude Agent SDK

SYNOPSIS

use Claude::Agent::DryRun qw(create_dry_run_hooks);
use Claude::Agent::Options;

# Simple dry-run with default output
my $options = Claude::Agent::Options->new(
    dry_run => 1,
);

# Dry-run with custom callback
my $changes = [];
my $options = Claude::Agent::Options->new(
    dry_run => 1,
    on_dry_run => sub {
        my ($tool_name, $tool_input, $preview) = @_;
        push @$changes, { tool => $tool_name, input => $tool_input };
        print "[DRY-RUN] $preview\n";
    },
);

# After query completes, review changes
for my $change (@$changes) {
    print "Would have used: $change->{tool}\n";
}

DESCRIPTION

This module provides dry-run functionality for the Claude Agent SDK. In dry-run mode, file-modifying tools are intercepted and their effects are previewed without executing them.

============================================================================

SECURITY WARNING: DRY-RUN MODE IS FOR PREVIEW ONLY - NOT A SECURITY BOUNDARY

============================================================================

Dry-run mode provides preview functionality only, NOT security guarantees. Do NOT rely on dry-run mode to prevent malicious or unintended command execution.

By default, CLAUDE_AGENT_DRY_RUN_STRICT=1 is enabled, which uses a whitelist approach for Bash commands. If you disable strict mode (CLAUDE_AGENT_DRY_RUN_STRICT=0), the Bash command detection falls back to regex-based heuristics that can be easily bypassed through shell obfuscation techniques including:

  • Command substitution: $(echo rm) -rf

  • Variable expansion: $cmd where cmd=rm

  • Hex/octal encoding in certain shells

  • Aliases that expand to destructive commands

  • Custom scripts or less common destructive tools

For security-critical applications, use:

  • Explicit tool whitelisting via allowed_tools

  • Containerization (Docker, etc.)

  • Sandboxed/isolated environments

  • Custom PreToolUse hooks with strict validation

IMPORTANT: For any production use, ensure CLAUDE_AGENT_DRY_RUN_STRICT=1 (the default) is always enabled. The heuristic fallback mode (CLAUDE_AGENT_DRY_RUN_STRICT=0) is deprecated and may be removed in a future version.

Do NOT rely on dry-run mode as a security mechanism.

WRITE TOOLS

The following tools are considered "write" tools and will be blocked in dry-run mode:

  • Write - File creation/overwrite

  • Edit - File modification

  • Bash - Commands that may modify files (detected by heuristics)

  • NotebookEdit - Jupyter notebook modifications

Read-only tools execute normally:

  • Read - File reading

  • Glob - File pattern matching

  • Grep - Content searching

  • WebFetch - Web content fetching

  • WebSearch - Web searching

MCP TOOLS AND DRY-RUN MODE

Custom MCP tools (tools with names starting with mcp__) are allowed by default in dry-run mode because the system cannot automatically determine whether they perform write operations.

To block specific MCP tools in dry-run mode, you have the following options:

  • Set the CLAUDE_AGENT_MCP_WRITE_TOOLS environment variable to a comma-separated list of MCP tool names that should be blocked (e.g., mcp__myserver__write_file,mcp__myserver__delete_record)

  • Implement dry-run logic within the MCP tool itself

  • Create custom PreToolUse hooks to explicitly block specific MCP tools

FUNCTIONS

create_dry_run_hooks

my $hooks = create_dry_run_hooks($on_dry_run_callback);

Creates hook matchers for dry-run mode. Returns a hashref suitable for the hooks option.

is_write_tool

my $is_write = is_write_tool($tool_name, $tool_input);

Returns true if the tool is considered a write operation.

format_preview

my $preview = format_preview($tool_name, $tool_input);

Formats a human-readable preview of what the tool would do.

AUTHOR

LNATION, <email at lnation.org>

LICENSE

This software is Copyright (c) 2026 by LNATION.

This is free software, licensed under The Artistic License 2.0 (GPL Compatible).