safe-webfetch
v0.1.8
Published
Claude Code permission prompt controller - auto allow/deny via pattern matching hooks
Readme
safe-webfetch
Rule-based auto-control for Claude Code permission prompts via pattern matching.
Why
Claude Code shows a permission prompt every time it accesses an external resource (URLs, etc.). Manually approving the same domains over and over interrupts your flow.
safe-webfetch uses Claude Code's Hooks to automatically allow or deny based on predefined rules, eliminating repetitive prompts.
It also features template learning — once you approve a URL, the tool extracts the domain or package name and auto-generates rules so future requests to the same pattern are allowed automatically.
How it works
PreToolUse hook → match rules → allow / pass (no match)
PostToolUse hook → template learning → append new rules to permission.json- PreToolUse: Evaluates rules from
config.json5(manual) thenpermission.json(auto-generated). If a rule matches, the request is allowed. If no rule matches, Claude Code shows its normal permission prompt. - PostToolUse: Extracts placeholders from approved URLs using template definitions and generates new allow rules.
Installation
mise (recommended)
mise use ubi:shoppingjaws/safe-webfetchDownloads a precompiled binary from GitHub Releases. No runtime dependencies required.
npm (requires Bun runtime)
npm install -g safe-webfetchRequires Bun to be installed, as the package uses Bun-specific APIs.
Build from source
git clone https://github.com/shoppingjaws/safe-webfetch.git
cd safe-webfetch
bun install
bun run build # → dist/safe-webfetch
cp dist/safe-webfetch ~/.local/bin/Setup
safe-webfetch initThis will:
- Create
$XDG_CONFIG_HOME/safe-webfetch/config.json5with default templates - Register PreToolUse / PostToolUse hooks in
~/.claude/settings.json
Configuration
Config files live in $XDG_CONFIG_HOME/safe-webfetch/ (defaults to ~/.config/safe-webfetch/).
config.json5 — Manual rules and templates
{
// Manual rules: glob pattern matching (matched URLs are auto-allowed)
rules: [
"https://docs.example.com/**",
],
// Templates: used for auto-learning in PostToolUse
templates: [
{
match: "https://github.com/{org}/**",
generate: [
"https://github.com/{org}/**",
"https://raw.githubusercontent.com/{org}/**",
],
},
],
}permission.json — Auto-generated rules
Generated automatically by the PostToolUse hook based on templates. No manual editing required.
{
"rules": [
"https://github.com/anthropics/**",
"https://raw.githubusercontent.com/anthropics/**"
]
}Pattern syntax
Rule patterns use glob syntax:
| Pattern | Meaning |
|---------|---------|
| * | Matches any string except / |
| ** | Matches any string including / (crosses directories) |
| ? | Matches any single character except / |
Template {placeholder} captures a single path segment (no /) and expands it into generate patterns.
Rule evaluation order
config.json5rules(manual)permission.jsonrules(auto-generated)
If a rule matches, the request is allowed. If no rule matches, Claude Code shows its normal permission prompt.
Default templates
safe-webfetch init generates templates for:
- GitHub —
github.com/{org}/**+raw.githubusercontent.com/{org}/** - docs.* sites —
docs.{domain}/**(AWS, Datadog, GCP, etc.) - npm —
www.npmjs.com/package/{pkg}/**+registry.npmjs.org/{pkg}/** - npm (scoped) —
www.npmjs.com/package/@{scope}/{pkg}/**+registry.npmjs.org/@{scope}/{pkg}/** - PyPI —
pypi.org/project/{pkg}/** - crates.io —
crates.io/crates/{crate}/**+docs.rs/{crate}/** - pkg.go.dev —
pkg.go.dev/{module}/**
Commands
| Command | Description |
|---------|-------------|
| safe-webfetch init | Create config + register hooks |
| safe-webfetch hook | PreToolUse hook (reads tool input from stdin) |
| safe-webfetch post-hook | PostToolUse hook (template learning) |
| safe-webfetch log show [-n N] | Show recent log entries |
Development
bun test # Run tests
bun run typecheck # Type check
bun run lint:check # Lint
bun run format:check # Format check
bun run format # Apply formatting
bun run build # CompileLicense
MIT
