[FEATURE] `tool_result` OTel event: emit classification metadata (`mcp_server_name`, `mcp_tool_name`, `skill_name`, `subagent_type`) unconditionally
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 running Claude Code with OTel enabled for observability, I want to classify tool calls in my telemetry backend by MCP server name, MCP tool name, skill name, and sub-agent type, so I can build per-server latency, per-skill usage frequency, and per-sub-agent duration dashboards.
Today these fields are only emitted in the tool_result OTel event when I set OTEL_LOG_TOOL_DETAILS=1. But that same flag also exports tool_input and tool_parameters.full_command (full Bash command string) to the OTel backend and those routinely carry sensitive data: .env file contents passed to Write, API keys in curl arguments, credentials passed as MCP tool args, etc.
So for every observability deployment I have to choose between "no classification metadata" and "full payload leak". Classification metadata is not sensitive, it's just labels, and shouldn't be coupled to the payload flag.
Proposed Solution
Emit these fields in the tool_result OTel event unconditionally, independent of OTEL_LOG_TOOL_DETAILS:
mcp_server_namemcp_tool_nameskill_namesubagent_type(not emitted at all today)
Keep tool_input, tool_parameters.bash_command, and tool_parameters.full_command gated by OTEL_LOG_TOOL_DETAILS=1 as they are now (they do carry sensitive content).
Alternative Solutions
- Parsing the full
mcp__<server>__<tool>string fromtool_name— works for MCP only, fragile, doesn't apply to skills or sub-agents. - Enabling
OTEL_LOG_TOOL_DETAILS=1and stripping sensitive fields downstream — data has already been exported, and the stripping is opt-in work per-deployment. - Not collecting this telemetry at all — loses material observability value.
Priority
High - Significant impact on productivity
Feature Category
Developer tools/SDK
Use Case Example
- Running Claude Code with OTel exporter pointed at our internal Grafana / Loki.
- We want a "tool usage by MCP server" dashboard — e.g., how often each MCP server is called, p95 latency per server, error rate per server.
- Skill-level analytics: which skills are invoked most, average duration per skill.
- Sub-agent analytics: when the agent spawns a sub-agent (Agent / Task tool), group metrics by
subagent_type. - All of this needs only the labels; we do not want
tool_inputor raw Bash commands in our observability pipeline. - Today we can't get (2)–(4) without also ingesting sensitive content, so we skip the dashboards entirely.
Additional Context
- Symmetric to the
duration_msonPostToolUse/PostToolUseFailurehooks that shipped recently (thanks!) — this is the equivalent split on the OTel side. mcp_server_scopeintool_resultis the precedent for what "emit unconditionally" looks like.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗