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) -rfVariable expansion:
$cmdwherecmd=rmHex/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_toolsContainerization (Docker, etc.)
Sandboxed/isolated environments
Custom
PreToolUsehooks 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_TOOLSenvironment 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
PreToolUsehooks 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).