Skip to content

fix(mcp): don't report stateless StreamableHTTP servers as stdio - #7224

Merged
ericapisani merged 3 commits into
getsentry:masterfrom
Snaylaker:fix/mcp-stateless-http-transport
Aug 24, 2026
Merged

fix(mcp): don't report stateless StreamableHTTP servers as stdio#7224
ericapisani merged 3 commits into
getsentry:masterfrom
Snaylaker:fix/mcp-stateless-http-transport

Conversation

@Snaylaker

@Snaylaker Snaylaker commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Description

MCPIntegration reports mcp.transport: "stdio" and network.transport: "pipe" for a StreamableHTTP server running stateless. _get_request_context_data only sets "http" when the request carries an mcp-session-id header, and a stateless server issues no session id, so no client sends that header back and the "stdio" default stands.

The header is a session signal, not a transport signal: per the spec a server "MAY assign a session ID at initialization time", so its presence is a deployment choice. This drops it from the transport check and leaves it supplying mcp.session.id when the server is stateful. stdio is unaffected: it attaches no request object, so the outer guard stops it before this branch.

server before after
stdio stdio unchanged
SSE sse + session id from ?session_id= unchanged
StreamableHTTP, stateful http + session id from header unchanged
StreamableHTTP, stateless stdio http, no session id

test_tool_handler_stateless_streamable_http drives a real stateless StreamableHTTPSessionManager app and fails on master with assert 'stdio' == 'http'. Green on mcp 1.x and 2.x.

Issues

@Snaylaker
Snaylaker force-pushed the fix/mcp-stateless-http-transport branch 3 times, most recently from 9dc7537 to fc475f6 Compare August 20, 2026 12:39
@Snaylaker Snaylaker changed the title fix(mcp): don't report stateless StreamableHTTP servers as stdio fix(mcp): record the transport where the transport is known Aug 20, 2026
`mcp.transport` was only set to "http" when the request carried an
`mcp-session-id` header. A StreamableHTTP server running stateless issues no
session id, so no client ever sends that header back and the span kept the
"stdio" default, reporting a plainly HTTP server as a local pipe.

Drop the header requirement from the transport check. The header still supplies
`mcp.session.id` when the server is stateful, and is simply absent otherwise:
per the spec a server MAY assign a session id, so its absence says nothing
about the transport.
@Snaylaker
Snaylaker force-pushed the fix/mcp-stateless-http-transport branch from fc475f6 to d6dca91 Compare August 20, 2026 12:50
@Snaylaker Snaylaker changed the title fix(mcp): record the transport where the transport is known fix(mcp): don't report stateless StreamableHTTP servers as stdio Aug 20, 2026
@ericapisani

Copy link
Copy Markdown
Member

Thanks for opening a PR with us @Snaylaker !

I've read the conversation so far with @alexander-alderman-webb in the issue that you originally opened and the changes you have here LGTM.

I've looked into the failing tests and it looks due to an assumption on our test fixture/helper, not your changes specifically (they just uncovered the assumption). I'm opening a PR shortly to address this and once that's merged, we'll look to get your changes in.

ericapisani added a commit that referenced this pull request Aug 24, 2026
`select_transactions_with_mcp_spans` assumes that all events provided to
the helper are transactions and contain a `type` key.

However, not all events contain 'type's and so passing events that may
contain a log would raise a KeyError.

Relates to #7224
@Snaylaker
Snaylaker marked this pull request as ready for review August 24, 2026 13:08
@Snaylaker
Snaylaker requested a review from a team as a code owner August 24, 2026 13:08

@ericapisani ericapisani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@ericapisani
ericapisani merged commit 0a1762b into getsentry:master Aug 24, 2026
264 of 267 checks passed
sentrivana pushed a commit that referenced this pull request Aug 25, 2026
`select_transactions_with_mcp_spans` assumes that all events provided to
the helper are transactions and contain a `type` key.

However, not all events contain 'type's and so passing events that may
contain a log would raise a KeyError.

Relates to #7224
sentrivana pushed a commit that referenced this pull request Aug 25, 2026
`MCPIntegration` reports `mcp.transport: "stdio"` and
`network.transport: "pipe"` for a StreamableHTTP server running
stateless. `_get_request_context_data` only sets `"http"` when the
request carries an `mcp-session-id` header, and a stateless server
issues no session id, so no client sends that header back and the
`"stdio"` default stands.

The header is a session signal, not a transport signal: per the spec a
server *"MAY assign a session ID at initialization time"*, so its
presence is a deployment choice. This drops it from the transport check
and leaves it supplying `mcp.session.id` when the server is stateful.
stdio is unaffected: it attaches no request object, so the outer guard
stops it before this branch.

| server | before | after |
| --- | --- | --- |
| stdio | `stdio` | unchanged |
| SSE | `sse` + session id from `?session_id=` | unchanged |
| StreamableHTTP, stateful | `http` + session id from header | unchanged
|
| StreamableHTTP, stateless | `stdio` | `http`, no session id |

`test_tool_handler_stateless_streamable_http` drives a real stateless
`StreamableHTTPSessionManager` app and fails on `master` with `assert
'stdio' == 'http'`. Green on mcp 1.x and 2.x.


#### Issues

* resolves: #7225
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCPIntegration reports stateless StreamableHTTP servers as mcp.transport "stdio"

2 participants