P
PreToolUse (mcp__cockroachdb-toolbox__cockroachdb-execute-sql)
HookFires on
PreToolUsematchingmcp__cockroachdb-toolbox__cockroachdb-execute-sqlImmediately before a tool runs — this is where an action can be denied.
Where this sits in a session
- Session start→
- Prompt submitted→
- Prompt expansion→
- Before tool use→
- After tool use→
- Notification→
- Before compaction→
- Subagent finished→
- Turn finished→
- Session end
Can block — This hook is able to deny the action or send Claude back to work.
What it runs
Executed automatically when the event fires — no prompt, no confirmation.
command· timeout 10s
python3 -c 'import sys, os, runpy; p = os.path.normpath(r"${CLAUDE_PLUGIN_ROOT}/scripts/validate-sql.py"); p = ("\\?\\" + p) if os.name == "nt" else p; runpy.run_path(p, run_name="__main__")'; exit 0Install it yourself
Paste into .claude/settings.json to run this hook without installing the whole plugin. Adjust the paths to point at your own copy of the scripts.
settings.json
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 -c 'import sys, os, runpy; p = os.path.normpath(r\"${CLAUDE_PLUGIN_ROOT}/scripts/validate-sql.py\"); p = (\"\\\\?\\\\\" + p) if os.name == \"nt\" else p; runpy.run_path(p, run_name=\"__main__\")'; exit 0",
"timeout": 10
}
],
"matcher": "mcp__cockroachdb-toolbox__cockroachdb-execute-sql"
}
]
}
}Source
Read this before installing — it runs on your machine with your permissions.
#!/usr/bin/env python3
"""Pre-execution SQL validation for CockroachDB.
Blocks dangerous patterns before they reach the database.
Receives JSON on stdin from Claude Code PreToolUse hook.
Exit 0 = allow, exit 2 = block.
"""
import json
import re
import sys
def main():
try:
data = json.load(sys.stdin)
except (json.JSONDecodeError, EOFError):
sys.exit(0)
tool_input = data.get("tool_input", {})
sql = tool_input.get("sql", "") or tool_input.get("statement", "")
if not sql:
sys.exit(0)
sql_upper = sql.upper()
# Block DROP DATABASE
if re.search(r"DROP\s+DATABASE", sql_upper):
json.dump({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason":
"DROP DATABASE is blocked by CockroachDB plugin safety hook. "
"Use DROP TABLE for individual tables instead."
}
}, sys.stdout)
sys.exit(0)
# Block TRUNCATE (data loss risk)
if re.search(r"^\s*TRUNCATE\s", sql_upper, re.MULTILINE):
json.dump({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason":
"TRUNCATE is blocked by CockroachDB plugin safety hook. "
"Use DELETE with a WHERE clause for targeted row removal."
}
}, sys.stdout)
sys.exit(0)
# Warn about SERIAL (anti-pattern — causes hotspots)
if re.search(r"\b(SERIAL|BIGSERIAL)\b", sql_upper):
json.dump({
"systemMessage":
"WARNING: SERIAL/BIGSERIAL creates sequential IDs that cause write "
"hotspots in CockroachDB. Use UUID with gen_random_uuid() instead: "
"id UUID PRIMARY KEY DEFAULT gen_random_uuid()"
}, sys.stdout)
sys.exit(0)
# Warn about multiple DDL in one transaction
ddl_count = len(re.findall(
r"(CREATE|ALTER|DROP)\s+(TABLE|INDEX|VIEW|SEQUENCE|TYPE|SCHEMA)",
sql_upper
))
if ddl_count > 1:
json.dump({
"systemMessage":
"WARNING: Multiple DDL statements detected. CockroachDB supports "
"only one DDL per transaction. Split into separate statements or "
"use SET autocommit_before_ddl = true."
}, sys.stdout)
sys.exit(0)
sys.exit(0)
if __name__ == "__main__":
main()
Shipped by 1 plugin
Installing any of these installs this hook.
Reviews
Log in to leave a review.
No reviews yet — be the first.
Explore related
Other things in this space — across every part of the ecosystem, not just hooks.