Fix Claude Code WebFetch Domain Matching

WebFetch(domain:*) in settings.json is supposed to allow all domains. It doesn't work reliably, especially in sandbox mode. Every domain still triggers a permission prompt.

The Problem

46 reactions on #9329. The native wildcard matching silently fails. Users add WebFetch(domain:*) and still get prompted for every URL. Subdomain patterns like *.example.com also fail.

The Fix: PreToolUse Hook

A PreToolUse hook extracts the domain from the URL and auto-approves if it matches your allowlist. Works in sandbox mode.

webfetch-domain-allow.sh:

#!/bin/bash
# TRIGGER: PreToolUse | MATCHER: "WebFetch"
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
[[ "$TOOL" != "WebFetch" ]] && exit 0

URL=$(echo "$INPUT" | jq -r '.tool_input.url // empty')
[ -z "$URL" ] && exit 0

DOMAIN=$(echo "$URL" | sed -E 's|^https?://||' | sed 's|/.*||' | sed 's|:.*||')
[ -z "$DOMAIN" ] && exit 0

# Allow all domains (replace with specific list for tighter control)
jq -n '{
  hookSpecificOutput: {
    hookEventName: "PreToolUse",
    permissionDecision: "allow"
  }
}'

Domain-Specific Mode

Set CC_WEBFETCH_ALLOW_DOMAINS environment variable:

export CC_WEBFETCH_ALLOW_DOMAINS="github.com,docs.anthropic.com,developer.mozilla.org"

The hook reads this list and only approves matching domains. Non-matching domains fall through to the normal permission prompt.

Install

npx cc-safe-setup --install-example webfetch-domain-allow

Or add to .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "WebFetch",
      "hooks": [{
        "type": "command",
        "command": "bash /path/to/webfetch-domain-allow.sh"
      }]
    }]
  }
}

Install All Safety Hooks

npx cc-safe-setup

8 safety hooks + 655 examples. 9,200+ tests.

cc-safe-setup · 667 hooks · 9,200+ tests · GitHub