How to Block Dangerous Commands with Claude Code Hooks
Claude Code is useful because it can run tools, but that also means a project needs deterministic guardrails. Instructions in a prompt can be forgotten. A PreToolUse hook runs before the tool call and can reject it in code. What we are building This project hook inspects every Bash command. If it finds rm -rf, it writes a reason to stderr and exits with status 2. Claude Code blocks the command and receives the reason as feedback. The important detail is the exit code: Exit 0: the hook has no objection; normal permissions still apply. Exit 2: a PreToolUse action is blocked. Exit 1: this is only a non-blocking hook error for most events, so it is the wrong choice for a guardrail. 1. Add the hook configuration Create .claude/settings.json in the project: { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-dangerous.sh", "args": [] } ] } ] } } The Bash matcher keeps this hook focused on shell commands. Using args: [] selects exec form, so the project path is passed without shell quoting problems. 2. Add the guard script Create .claude/hooks/block-dangerous.sh: #!/bin/bash input=$(cat) command=$(jq -r '.tool_input.command // empty'
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to