fix(mcp): warn when stateless session middleware never attached - #856
Draft
posthog[bot] wants to merge 1 commit into
Draft
fix(mcp): warn when stateless session middleware never attached#856posthog[bot] wants to merge 1 commit into
posthog[bot] wants to merge 1 commit into
Conversation
The stateless-session mint (PostHogMcpStatelessSessionMiddleware) is zero-config only when the ASGI app is built after instrument() runs. An app built or mounted earlier (the common FastAPI case) silently gets no middleware, so every session falls back to a fragmented per-process id with nothing in the SDK saying so. Make the failure loud with two independent signals: - instrument() warns when streamable_http_app() was already called before it ran (FastMCP's cached _session_manager is the tell). - A one-time runtime warning fires when a tool call arrives over HTTP with no session id and resolution falls back to a generated session. Both point to the manual fix, app.add_middleware(...), now documented in posthog/mcp/README.md. No behavior change on correctly-wired servers or on stdio. Generated-By: PostHog Code Task-Id: 9efb38cb-2672-4236-8da6-208e4f83f686
Contributor
posthog-python Compliance ReportDate: 2026-08-07 13:25:20 UTC ✅ All Tests Passed!111/111 tests passed Capture_V1 Tests✅ 94/94 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
PostHogMcpStatelessSessionMiddlewaresilently never attached — and nothing in the SDK said so. It cost two support round trips and a full SDK release that didn't fix their issue.instrument()runs.autowire_stateless_mintmonkey-patches the app factories on the server, so an app built or mounted beforeinstrument()(the common FastAPI-mounts-at-import case) gets no middleware at all.resolve_session_idto the per-processgeneratedbranch. Classic works-in-dev (mcp.run()calls the patched factory), dark-in-prod (FastAPI mounts its own app).asgi.py(which feat(mcp): support the MCP 2026-07-28 spec and mcp 2.x SDK #830 does not); the only shared file issession.py, which this PR deliberately leaves untouched to avoid conflict.💚 How did you test it?
Added unit + end-to-end tests, and reproduced the customer's ordering trap against a real stateless FastMCP streamable-HTTP transport.
Mcp-Session-Id→generatedsession fires exactly one warning; repeat requests stay quiet.streamable_http_app()beforeinstrument()triggers the warning.instrument(), atools/callwith no session header fires both warnings; the correctly-ordered path fires neither.147 passed, 1 skipped.ruff check/ruff formatclean.Two independent signals now surface the failure (either would have ended the ticket on day one):
instrument()warningstreamable_http_app()was already called beforeinstrument()ranadd_middleware+posthog/mcp/README.mdDocs: the manual
app.add_middleware(PostHogMcpStatelessSessionMiddleware)path now lives in a findableposthog/mcp/README.md, plus a sharpened note inexamples/mcp_stateless.py.📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Fully autonomous
instrument(). Chose two complementary detectors: an instrument-time probe of FastMCP's lazily-created_session_manager(set oncestreamable_http_app()has run) and a runtime warn-once gated onhttp_request AND no token AND no mcp_session_id AND session_source == "generated"— the precise fingerprint that can't fire for stdio or correctly-wired servers.posthog/mcp/session.pyso this stays conflict-free with draft feat(mcp): support the MCP 2026-07-28 spec and mcp 2.x SDK #830; plumbed a newhttp_requestflag throughprepare_requestand the adapters instead.Created with PostHog Desktop from this inbox report.