[FEATURE] Forward the calling agent's id to MCP servers in tools/call _meta (subagents and Workflow agents share one connection)
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
Subagents (Agent tool) and Workflow agents reuse the parent session's MCP connection. That is the documented behavior, and it is usually what you want. But a stateful MCP server then has no way to tell callers apart: every tools/call from the main agent, from a subagent and from each parallel Workflow agent arrives on the same connection, with nothing in the request that says who made it.
For a browser server this breaks parallel work. Playwright MCP keeps one "current tab" per connection, so when two subagents browse at the same time, one browser_tabs new moves the other's current tab, snapshots come from the wrong page, and a browser_close from one subagent closes every tab of the session, the parent's included. The same applies to any MCP server that keeps per-caller state (a shell, a REPL, a database transaction, a cursor).
The per-agent alternative doesn't work either. An inline mcpServers entry in the agent definition doesn't isolate concurrent instances: byte-identical configs share one process (#84638), and in my test the first instance to finish took the process down while its sibling's call was still in flight (Connection closed).
Proposed Solution
Forward the caller's identity to MCP servers in params._meta of tools/call, for example:
"_meta": {
"claudecode/agentId": "a7395ab0743b383a6",
"claudecode/agentType": "general-purpose",
"claudecode/sessionId": "…"
}
Absent for the main agent, same values hooks already receive as agent_id / agent_type / session_id. It could be opt-in per server (e.g. "forwardAgentContext": true in the server config) if there is a privacy concern. A server that cares can then key its state per agent (one browser context, tab group or shell per agent) while still sharing one process and one connection.
Alternative Solutions
What works today: a PreToolUse hook (matcher mcp__<server>__.*) reads agent_id and returns updatedInput with an extra _meta argument. Measured on 2.1.288 with an echo MCP server: the stamped value reaches the server for the main agent, an Agent-tool subagent and Workflow agents (agent_type: workflow-subagent), each with a distinct id, and updatedInput isn't validated against the tool's schema.
It works, but it is fragile:
- it relies on
updatedInputkeeping extra keys the schema doesn't declare (a server with strict validation rejects them); - every user has to install a hook, and every MCP call pays a process spawn;
agent_idin hook payloads is occasionally inconsistent (#90662), so a server can't fully trust it.
Priority
Medium - Would be very helpful
Feature Category
MCP server integration
Use Case Example
- A session runs a Workflow with 3 agents that each research a different site in the browser.
- With the agent id in
_meta, the Playwright server gives each agent its own tab group and current tab, all in the user's single logged-in Chrome profile. - When a subagent finishes or calls
browser_close, only its own tabs close; the parent's browsing is untouched.
Additional Context
Related: #84638 (inline servers shared across concurrent subagents), #90662 (agent_id inconsistencies in hook payloads). I'm implementing the hook-based workaround in a Playwright MCP fork; with the id in _meta, the hook would go away.