PreToolUse hook that blocks edits adding remote MCP server URLs unless their host appears in an explicit allowlist, reducing accidental connection to unreviewed OAuth, SSE, or Streamable HTTP MCP endpoints.
This hook blocks unreviewed remote hosts in MCP-related config edits; it does not prove an allowed host is safe., Run a separate authorization and source review before adding a new host to the allowlist., The hook fails open when jq is unavailable, so CI or pre-commit checks should cover high-assurance environments.
Privacy notes
The hook reads pending config text from Claude Code tool input but does not write files or call the network., Blocked hostnames are printed to stderr and may reveal internal MCP endpoints in the local terminal.
Author
JSONbored
Submitted by
JSONbored
Claim status
unclaimed
Last verified
2026-06-05
Decision playbook
Review trust signals before you adopt
Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.
Compare context
Selected
0
Current score
63
Baseline
—
Delta
No baseline selected
No major trust-signal divergence detected in the current selection.
Source and provenance checks
Needs review
Confirm ownership and provenance before trusting install instructions.
Source link availableRequired
Open the canonical repository and verify ownership.
Done
Source provenance statusRequired
Marked as source-backed.
Done
Metadata reviewed
No reviewed flag detected in metadata.
Pending
Safety and privacy checks
Complete
Validate risk disclosures before installation or API wiring.
Safety notes presentRequired
Review the listed safety guidance before running commands.
Done
Privacy notes presentRequired
Review data handling notes before connecting accounts or secrets.
Done
Trust level risk gateRequired
Trust level does not block evaluation.
Done
Package and install checks
Needs review
Check package metadata and artifact integrity signals.
Install payload available
Install or copy payload is available for review.
Done
Package verification flag
No package verification flag provided.
Pending
Checksum metadata
No checksum provided for downloaded artifact.
Pending
Compare-driven decision checks
Needs review
Use compare context to validate trade-offs before adoption.
Compare tray has multiple entries
Add at least one more entry to compare trust differences.
Watches Write, Edit, and MultiEdit calls before MCP-related config reaches disk.
Extracts HTTP and HTTPS hosts from raw and JSON-decoded pending text.
Blocks hosts not listed in ALLOWED_MCP_HOSTS.
Makes remote MCP additions intentional and reviewable.
Runs locally with bash and jq.
Why use it
Remote MCP servers can sit behind OAuth and expose account data or write-capable
tools. This hook adds a small local control: Claude cannot casually paste a new
remote endpoint into config unless that host has already been reviewed and added
to the local allowlist.
Show that MCP Server URL Allowlist - Claude Code Hook is listed on HeyClaude. Paste this Markdown into your README — it renders the badge and links back to this page.
[](https://heyclau.de/entry/hooks/mcp-server-url-allowlist-hook)
How it compares
MCP Server URL Allowlist - Claude Code Hook side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
1 trust signal differ across this comparison (Submitter).
PreToolUse hook that blocks edits adding remote MCP server URLs unless their host appears in an explicit allowlist, reducing accidental connection to unreviewed OAuth, SSE, or Streamable HTTP MCP endpoints.
PreToolUse hook that reviews proposed writes to MCP configuration files and blocks inline credential values, credential-bearing URLs, and broad filesystem roots before they are saved.
PreToolUse hook that scans proposed writes to prompt, agent, rule, markdown, and context files for common prompt-injection phrases before the content is saved into an AI-readable surface.
Comprehensive Docker image vulnerability scanning with layer analysis, base image recommendations, and security best practices enforcement. This PostToolUse hook automatically scans Docker images for vulnerabilities when Dockerfiles are modified, providing real-time security validation during development.
✓This hook blocks unreviewed remote hosts in MCP-related config edits; it does not prove an allowed host is safe.
Run a separate authorization and source review before adding a new host to the allowlist.
The hook fails open when jq is unavailable, so CI or pre-commit checks should cover high-assurance environments.
✓Runs before Write, Edit, and MultiEdit tool calls and reads only the pending file path plus proposed new text, including replacement fragments for partial edits.
Blocks matching MCP configuration edits with exit code 2 when it finds inline credential values, credential-bearing URLs, or broad filesystem roots for filesystem MCP servers.
Does not start MCP servers, contact remote MCP endpoints, edit files, delete files, or inspect existing config beyond the proposed tool input.
Text and JSON heuristics can miss unusual config shapes or flag reviewed local setups; use `MCP_CONFIG_PRIVACY_ALLOWLIST` only for documented exceptions.
Set `MCP_CONFIG_PRIVACY_MODE=advisory` to warn without blocking while a team tunes its MCP policy.
✓Runs before Write, Edit, and MultiEdit calls and reads only the proposed target path plus new text from Claude Code hook input.
Blocks with exit code 2 when context-like files contain common instruction-override, disclosure, role-confusion, concealment, or silent tool-execution patterns.
Does not send text to a model, call an API, read existing files, start tools, execute generated content, or modify files itself.
Pattern matching can miss obfuscated attacks and can flag legitimate security documentation; use advisory mode while tuning the file scope.
Set `PROMPT_INJECTION_SCANNER_SCOPE=all` only when the team wants every Write/Edit/MultiEdit payload scanned.
✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.
Privacy notes
✓The hook reads pending config text from Claude Code tool input but does not write files or call the network.
Blocked hostnames are printed to stderr and may reveal internal MCP endpoints in the local terminal.
✓Runs locally and makes no network calls.
Does not print credential values, URLs, or full config content; it reports only finding categories.
The target file path, finding category, allowlist pattern, and mode variable can still appear in terminal output, Claude Code transcripts, CI logs, or screenshots.
Use environment-variable expansion or a secret manager for MCP credentials so private tokens are not committed to project-scoped config files.
✓Runs locally and makes no network calls.
Does not print the matched text; it reports only finding categories and generic remediation guidance.
The target path, finding categories, mode variable, and allowlist pattern can still appear in terminal output, Claude Code transcripts, CI logs, or screenshots.
When documenting prompt-injection examples, quote or redact them so attack text does not become active instruction material in prompt or agent files.
✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.
Prerequisites
Claude Code CLI with hooks enabled.
bash, jq, grep, and awk available locally.
ALLOWED_MCP_HOSTS set to a comma-separated list of reviewed remote MCP hosts.
Claude Code CLI with hooks enabled.
bash, jq, grep, sort, and a reviewed `.claude/settings.json` or user-level hook configuration.
A team MCP policy for approved servers, credential storage, filesystem scopes, and remote transports.
Claude Code CLI with hooks enabled.
bash, jq, grep, sort, tr, and a reviewed `.claude/settings.json` or user-level hook configuration.
A team policy for which prompt, rule, agent, documentation, and context files are read as instructions by AI tools.
— none listed
Install
mkdir -p .claude/hooks
cat > .claude/hooks/mcp-server-url-allowlist.sh <<'MCP_SERVER_URL_ALLOWLIST_HOOK'
#!/usr/bin/env bash
set -u
if ! command -v jq >/dev/null 2>&1; then
exit 0
fi
input=$(cat)
file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.path // ""')
text=$(printf '%s' "$input" | jq -r '
def scalar_strings:
if type == "string" then .
elif type == "array" then .[] | scalar_strings
elif type == "object" then .[] | scalar_strings
else empty end;
def decoded_config_strings:
try (fromjson | scalar_strings) catch empty;
[.tool_input.content, .tool_input.new_string, (.tool_input.edits[]?.new_string)]
| map(select(type == "string"))
| .[]
| ., decoded_config_strings
' 2>/dev/null)
normalized_text=$(printf '%s' "$text" | sed 's#\\/#/#g')
case "$file" in
*mcp*.json|*.mcp.json|*.claude/settings.json|*/settings.json) ;;
*) exit 0 ;;
esac
hosts=$(printf '%s' "$normalized_text" | grep -Eo 'https?://[^"[:space:]]+' | awk -F/ '{print $3}' | sort -u)
[ -z "$hosts" ] && exit 0
allowlist=$(printf '%s' "${ALLOWED_MCP_HOSTS:-}" | tr ',' ' ')
for host in $hosts; do
case " $allowlist " in
*" $host "*) ;;
*)
echo "Blocked remote MCP URL: $host is not in ALLOWED_MCP_HOSTS." >&2
exit 2
;;
esac
done
exit 0
MCP_SERVER_URL_ALLOWLIST_HOOK
chmod +x .claude/hooks/mcp-server-url-allowlist.sh