hooksSource-backedReview first Safety ✓ Privacy ✓
MCP Server URL Allowlist - Claude Code Hook
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.
by JSONbored·added 2026-06-05·
Claude Code
HarnessClaude Code
Trigger:PreToolUse
Review first — review before installing
Open the source and read safety notes before installing.
Safety notes
- 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.
Prerequisites
- Claude Code CLI with hooks enabled.
- bash, jq, grep, awk, and sed available locally.
- ALLOWED_MCP_HOSTS set to a comma-separated list of reviewed remote MCP hosts.
Schema details
- Install type
- cli
- Troubleshooting
- No
Runtime and command metadata
- Trigger
- PreToolUse
- Script language
- bash
Script body
#!/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 '[.tool_input.content, .tool_input.new_string, (.tool_input.edits[]?.new_string)] | map(select(. != null)) | join(" ")')
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 0Full copyable content
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/mcp-server-url-allowlist.sh"
}
]
}
]
}
}About this resource
Features
- Watches Write, Edit, and MultiEdit calls before MCP-related config reaches disk.
- Extracts HTTP and HTTPS hosts from 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.
References
- Claude Code hooks - https://code.claude.com/docs/en/hooks
- MCP authorization specification - https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization
#mcp#hooks#allowlist#security#remote-mcp
Source citations
Signals
Loading live community signals…
More like this, weekly
A short, calm digest of reviewed Claude resources. Unsubscribe any time.