P
PostToolUse (mcp__(.*[Cc]arta.*|2827383e-1775-4df3-b6ff-04d5392f6d18|640916d9-5e0c-4d0b-830a-03500fa93e5e|1af3c326-9402-463c-ba5c-d62de59cf57b|8eb65db0-0cbd-4f50-833b-3057c150d41a|33b9b857-8443-4b2d-b191-2d9b6c50eb86)__execute_query)
HookFires on
PostToolUsematchingmcp__(.*[Cc]arta.*|2827383e-1775-4df3-b6ff-04d5392f6d18|640916d9-5e0c-4d0b-830a-03500fa93e5e|1af3c326-9402-463c-ba5c-d62de59cf57b|8eb65db0-0cbd-4f50-833b-3057c150d41a|33b9b857-8443-4b2d-b191-2d9b6c50eb86)__execute_queryImmediately after a tool returns, with its result available.
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 5s
node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/warn-empty-query.js"Install 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": {
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/warn-empty-query.js\"",
"timeout": 5
}
],
"matcher": "mcp__(.*[Cc]arta.*|2827383e-1775-4df3-b6ff-04d5392f6d18|640916d9-5e0c-4d0b-830a-03500fa93e5e|1af3c326-9402-463c-ba5c-d62de59cf57b|8eb65db0-0cbd-4f50-833b-3057c150d41a|33b9b857-8443-4b2d-b191-2d9b6c50eb86)__execute_query"
}
]
}
}Source
Read this before installing — it runs on your machine with your permissions.
#!/usr/bin/env node
/**
* PostToolUse Hook: Warn on empty execute_query responses
*
* When execute_query returns no rows, outputs a reminder to stderr
* (exit 2) which gets fed to Claude.
*
* Part of the official Carta AI Agent Plugin.
*/
let inputData = '';
process.stdin.on('data', chunk => (inputData += chunk));
process.stdin.on('end', () => {
try {
const input = JSON.parse(inputData);
const { tool_input, tool_response } = input;
// Extract the result string from the MCP response
let resultStr = tool_response?.result || tool_response;
if (Array.isArray(resultStr) && resultStr[0]?.type === 'text') {
resultStr = resultStr[0].text;
} else if (resultStr?.content && Array.isArray(resultStr.content)) {
resultStr = resultStr.content[0]?.text || resultStr;
}
// Parse and check for empty results
let parsed;
try {
parsed = typeof resultStr === 'string' ? JSON.parse(resultStr) : resultStr;
} catch {
process.exit(0);
return;
}
const isEmpty =
(parsed && parsed._warning) ||
(Array.isArray(parsed) && parsed.length === 0) ||
(parsed?.rows && parsed.rows.length === 0) ||
(parsed?.count === 0);
if (isEmpty) {
const sql = tool_input?.sql || 'query';
process.stderr.write(
`⚠️ EMPTY DATA: execute_query returned no results. ` +
`Tell the user what data was expected but missing and suggest next steps ` +
`(check firm context with list_contexts, verify table names with list_tables, etc.).`
);
process.exit(2);
return;
}
process.exit(0);
} catch (err) {
// Never block on hook errors
process.exit(0);
}
});
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.