fix: record the MCP JSON-RPC request id as request_id, not session_id

What does this MR do and why?

The MCP tool-call analytics recorded the JSON-RPC request id under a key called session_id. The start_mcp_tool_call and finish_mcp_tool_call internal events, the AiTracking usage-event payload, and mcp.log all used this key. The call handler filled it with request[:id] || SecureRandom.uuid.

The MCP Server is stateless by design. It does not issue an Mcp-Session-Id, and it ignores one if a client sends it. So there is no session to record.

The wrong name has a real cost. On GitLab.com between 2026-08-24 and 2026-09-20, 89% of tool calls carried a session_id value that was shared by more than 100 users. The value 2 alone covers 811k calls from 23k users. Grouping by this key joins unrelated calls together. It broke the first pass of a tool-sequence analysis.

The product manager narrowed the issue to a rename of the field to request_id. Analysis will approximate sessions as user plus client plus a time gap. See #630544 (closed).

This MR renames the key to request_id in these places:

  • The call handler and the mcp.log payload (lib/api/mcp/handlers/call_tool.rb).
  • The EE event tracking (ee/lib/ee/api/mcp/handlers/call_tool.rb).
  • Both event definitions (ee/config/events/start_mcp_tool_call.yml and ee/config/events/finish_mcp_tool_call.yml). The property description now says the server is stateless and that this value is the JSON-RPC request id.
  • The AiTracking payload mapping (ee/lib/gitlab/tracking/ai_tracking.rb).

The specs are updated to match.

Data note: events that are already stored keep session_id inside their payloads. Only newly emitted events carry request_id. Queries and dashboards that read this property need to account for the switch date.

The session_id keys used by other features, such as Duo Chat tools and agent platform sessions, are real session ids. This MR does not change them.

How to verify locally

Run the three spec files. The AiTracking spec needs a running ClickHouse.

bundle exec rspec spec/lib/api/mcp/handlers/call_tool_spec.rb ee/spec/lib/ee/api/mcp/handlers/call_tool_spec.rb ee/spec/lib/gitlab/tracking/ai_tracking_spec.rb

I also checked this end to end on GDK through the real /api/v4/mcp endpoint. A tools/call with JSON-RPC id e2e-req-42 wrote an mcp.log entry with request_id: "e2e-req-42" and no session_id key. This held for both a successful and a failed tool call.

References

Closes #630544 (closed)

🤖 Generated with Claude Code

Merge request reports

Loading
Loading