Hooks: block tools on the parent Agent and run them only in subagents (keep main context clean)

Feature request for product/service

Cursor IDE

Describe the request

Goal
Keep the main Agent conversation as a thin coordinator. I do not want
Read / Shell / Write / MCP to run (or dump output) in the parent context.
The parent should only plan and delegate. Actual tool use should happen
inside Task subagents (explore, shell, generalPurpose, custom), which
return a short summary.

Desired flow

  1. User talks to the main Agent.
  2. Main Agent decides work is needed and would normally call a tool.
  3. A hook on the PARENT session denies that tool (or never lets it run).
  4. The same hook (or a follow-up) routes the work to the right subagent:
    • codebase search / file reads → explore
    • terminal / git / scripts → shell
    • multi-file implementation → generalPurpose or a custom agent
  5. Subagent runs tools in its own context window.
  6. Parent only receives the subagent final message.

Why today’s hooks are not enough

  • I can deny tools in preToolUse / beforeShellExecution, but those events
    do not say whether the caller is the parent or an already-running
    subagent. If I block Shell globally, I also block the shell subagent.
  • subagentStart / subagentStop fire on the parent and do not tag later
    tool/shell payloads with subagent_id / parent_conversation_id.
    Staff have confirmed this: conversation_id linkage is broken
    (forum 163054, 166533).
  • Hooks cannot spawn or resume a subagent. The only workaround is deny +
    agent_message (“use the Task tool”), which still burns parent turns and
    does not keep tool I/O out of the parent if the model ignores it.

Ask

  1. Identity on every tool/shell/MCP/file hook (required)

    • is_subagent: boolean
    • subagent_id: string | null
    • subagent_type: string | null
    • parent_conversation_id: string | null (must differ from the child’s
      conversation_id)

    Then a hook can: allow Task only on the parent; allow Shell/Read/Write
    only when is_subagent === true.

  2. Optional: route from the hook (nice to have)
    On preToolUse / beforeShellExecution when is_subagent is false,
    allow the hook to return something like:

    {
    “permission”: “deny”,
    “delegate”: {
    “subagent_type”: “shell”,
    “task”: “”,
    “resume_subagent_id”: null
    },
    “agent_message”: “Delegated to the shell subagent.”
    }

    Cursor would start/resume that subagent and feed only the summary back
    to the parent. Without (2), (1) still lets us enforce “parent may only
    call Task” and “tools only inside subagents.”

Policy I want to encode

  • Parent: Task allowed; Shell, Read, Write, MCP, file edits denied.
  • explore: Read / grep-style tools allowed; writes denied.
  • shell: Shell allowed (with our command matchers).
  • generalPurpose: full tools.

Until (1) ships, this policy is unsafe: a deny-all-tools hook would
disable the subagents that are supposed to do the work.

Related

https://cursor.com/docs/hooks.md
https://cursor.com/docs/subagents.md

This is the policy we want on Cursor hooks, already working on the Claude-style side via agent_id

https://raw.githubusercontent.com/knucklehead96/mrn-marketplace/master/mrn-agents-workflow/hooks/enforce-subagent-first.sh

Discriminator: hook JSON includes agent_id only when the tool ran inside a subagent. Empty agent_id → main thread → deny Read/Grep/Glob/Edit/Write/Bash and MCP; non-empty → allow.

INPUT=$(cat)
AGENT_ID=$(echo “$INPUT” | jq -r ‘.agent_id // empty’)
[ -n “$AGENT_ID” ] && exit 0 # inside a subagent — allow

Main thread then gets a deny that tells the model to delegate (Explore / analyst / developer / builder / tester / general-purpose) instead of running tools in the parent.

Cursor preToolUse / beforeShellExecution do not expose agent_id (or is_subagent) today, so this exact gate cannot be implemented here without also blocking tools inside subagents.

Ask: add the same field on Cursor tool/shell hooks (agent_id or is_subagent + subagent_type) so parent can stay chat/Task-only and subagents keep full tools.