OTLP mcp_server_connection event missing server_name attribute
Summary
The claude_code.mcp_server_connection event emitted via OTLP/HTTP does not
carry the MCP server's name in its attributes. Without the name, downstream
consumers can't tell which server connected, which makes the event close to
useless for audit, governance, or supply-chain risk classification — the
primary reasons an organization would turn OTLP on in the first place.
Repro
- Configure Claude Code with
OTEL_EXPORTER_OTLP_ENDPOINTand a logs receiver. - Start a session with any MCP server configured (e.g.
context7). - Capture the
claude_code.mcp_server_connectionlog record.
Observed attributes include the standard correlation set
(session.id, user.account_uuid, organization.id, prompt.id, etc.) but
no field identifying the server.
Expected
A server_name (or equivalently named) attribute on the event, matching the
identifier the user configured. For plugin-sourced servers, the namespaced
form already used in JSONL transcripts (plugin:<plugin_id>:<server_id>,
e.g. plugin:context7:context7) would let consumers apply per-source trust
policies without further parsing.
A lifecycle indicator (mcp_action = "added" | "removed" | "connected"
| "disconnected") would also be valuable, since the current event name
implies connection but the semantics aren't documented.
Reference: https://docs.anthropic.com/en/docs/claude-code/monitoring-usage
Why this matters
The documented purpose of the OTLP feed is monitoring and governance.
Three of the four MCP-related audit questions can't be answered without the
server name:
- Did an unapproved server attach to a session?
- Did a plugin-installed server bypass the org allowlist?
- Which session activated server X (forensics / IR)?
Today the only answerable question is "did some MCP server connect," which
is not a useful audit signal on its own.
Workaround we're using
In sextant (https://github.com/a2z-tech-innovations/code-sextant) we derive
server names by parsing the JSONL transcript at~/.claude/projects/**/*.jsonl — specifically attachment records withattachment.type == "mcp_instructions_delta", reading addedNames. We
emit a synthetic claude_code.mcp_server_connection event withserver_name and source="jsonl" and feed it through the same persistence
path as real OTLP events.
This works for local-first deployments where both signals are present, but
it isn't a substitute for the OTLP event carrying the name directly:
- Organizations using OTLP to a remote collector don't ship JSONL alongside.
- The JSONL fallback can't distinguish auto-approved vs user-approved
activations (only OTLP records that), so OTLP-derived risk signals stay
capped at ~0.70 of the JSONL+OTLP combined surface.
Adding server_name to the OTLP event closes that gap and brings OTLP-only
deployments to parity with the local-first ones.
Environment
- Claude Code: latest stable as of 2026-05
- OTLP: HTTP/protobuf logs to a local receiver
- Observed against both bare
claudeand plugin-sourced servers
(plugin:context7:context7)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗