PreToolUse hooks need a way to detect subagent vs main session context
Problem
There's no way within a PreToolUse hook to determine whether the tool call is happening in the main conversation or inside a subagent (spawned via the Task tool).
I want to block certain expensive MCP tools (datadog, snowflake, atlassian, etc.) from being called directly in the main conversation — they should only be callable from subagents to avoid context bloat. A PreToolUse hook is the natural enforcement mechanism, but the hook input is identical in both contexts:
session_id— same in main and subagenttranscript_path— same in main and subagent (no/subagents/path segment)- Process tree (PPID) — same parent process
- Environment variables — identical, no
CLAUDE_SUBAGENTor similar
I verified all of this with debug logging in the hook script.
Proposed Solutions (either would work)
Option A: Add field to hook input
Add an is_subagent boolean or agent_depth integer to the PreToolUse (and PostToolUse) hook input JSON:
{
"session_id": "abc123",
"hook_event_name": "PreToolUse",
"is_subagent": true,
"tool_name": "mcp__datadog__search_logs",
...
}
Option B: Hook configuration option
Add a context field to hook definitions in settings.json:
{
"matcher": "mcp__datadog__.*",
"context": "main-only",
"hooks": [{ "type": "command", "command": "./block-direct-mcp.sh" }]
}
Values could be "main-only", "subagent-only", or "all" (default).
Use Case
Expensive/slow MCP servers (datadog, snowflake, atlassian, slack, etc.) should always be delegated to subagents. CLAUDE.md instructions asking for this are unreliable — the model frequently ignores them and calls MCPs directly, bloating the main conversation context. A hard enforcement mechanism via hooks is needed.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗