[FEATURE] Add agent identities to tool event payloads

Resolved 💬 3 comments Opened Mar 17, 2026 by mathnathan Closed Mar 17, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

When Claude Code runs subagents, the PreToolUse and PostToolUse hooks fire for tool calls made inside the subagent but the payload contains no information about which agent invoked the tool. This makes it impossible to write hook logic that is conditional on the calling agent.

Today, SubagentStart and SubagentStop correctly include agent_id and agent_type in their payloads. But the tool-level hooks (PreToolUse, PostToolUse) that fire between those boundaries are anonymous. There is no way to determine at hook-execution time whether the tool call originated from the parent session or from a specific subagent, let alone which subagent.

This is a significant gap for any hook that needs to enforce per-agent policy:

  • Security and permission boundaries: a hook cannot block a specific tool for a specific subagent type while allowing it for others. For example, you may want to allow a web-researcher subagent to use WebSearch freely but require approval before any code-writer subagent calls Write or Edit. Without agent_id in the hook payload, a blanket block or blanket allow is the only option.
  • Audit logging and observability: hooks used for compliance logging cannot attribute tool calls to the agent that made them. Log entries are missing a critical dimension: who (which agent) performed the action.
  • Rate limiting and resource control: hooks that enforce budget or rate limits (e.g., max API calls, max files written) cannot maintain per-agent counters. All agents share an undifferentiated pool.
  • Conditional tool interception: a hook cannot safely modify or enrich PreToolUse inputs differently depending on the agent context (e.g., injecting different working directories or prefixes for different subagent roles).

Proposed Solution

Add agent_id and agent_type fields to the PreToolUse, PostToolUse, and PostToolUseFailure hook payloads whenever the tool call originates inside a subagent. When the call originates from the parent (main) session, both fields should be null or omitted.

The proposed payload addition:

{
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": { ... },
  "tool_use_id": "toolu_abc123",
  "agent_id": "a2e586e02eeb9c9a4",
  "agent_type": "file-summarizer"
}
  • agent_id: the same opaque identifier already present in SubagentStart/SubagentStop payloads, so hooks can correlate tool calls to a specific subagent lifecycle
  • agent_type: the subagent's name field from its definition (e.g., "file-summarizer"), enabling policy decisions based on agent role without needing to track agent_id state across hook invocations
  • Both fields should be null (or absent) when the tool call originates from the parent session, preserving backwards compatibility

No changes to hook registration or the settings.json schema seem necessary.

Alternative Solutions

_No response_

Priority

Medium - Would be very helpful

Feature Category

Developer tools/SDK

Use Case Example

Consider a multi-agent code review pipeline with scoped tool permissions

A team uses Claude Code with two subagents defined in .claude/agents/:

  • code-analyzer: reads files and produces a review report (should only use Read, Glob, Grep)
  • code-fixer: applies the suggested fixes (uses Edit, Write, Bash)

They want a PreToolUse hook that enforces this separation. They want to block code-analyzer from ever writing files, even if the model decides to try.

Step 1: User runs: "_Analyze the auth module for bugs and fix any you find._"

Step 2: Claude spawns both subagents. code-analyzer starts reading files. Its PreToolUse hooks fire with tool_name: "Read" and the hook sees agent_type: "code-analyzer", allows it through.

Step 3: The model inside code-analyzer attempts to call Write directly (hallucination or prompt drift). The PreToolUse hook fires. With agent_type in the payload, the hook script checks: if agent_type == "code-analyzer" and tool_name in ("Write", "Edit", "Bash"): block. The write is denied before it executes.

Step 4: code-fixer calls Edit. The hook sees agent_type: "code-fixer", allows it.

Without this feature, the hook at Step 3 cannot distinguish whether the Write came from code-analyzer (block it) or code-fixer (allow it). The only option is to block Write for all agents which breaks code-fixer, or allow it for all agents which defeats the security boundary entirely.

Additional Context

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗