Skip to content

feat!: keep the posthog-python identity when instrumenting MCP - #1034

Open
eli-r-ph wants to merge 2 commits into
v1-capture-migration-docsfrom
v1-sdk-identity
Open

eli-r-ph wants to merge 2 commits into
v1-capture-migration-docsfrom
v1-sdk-identity

Conversation

@eli-r-ph

@eli-r-ph eli-r-ph commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

Stacked on #1030. Part of the 8.0 series (checklist in #1016).

Capture v1 sets $lib and $lib_version from the per-request PostHog-Sdk-Info header and overwrites any value in the event. One request carries events from every caller of a client, so one client can have only one identity. 8.0 fixes that identity at posthog-python/<version>.

In 7.x, posthog.mcp.instrument() and PostHogMCP relabeled the client as posthog-python-mcp: the header, $lib, and the User-Agent of feature flag requests. instrument() with no client uses the default client, the same one behind posthog.capture(). So after instrumenting, every event and flag request from the app reported posthog-python-mcp, not only the MCP events. That happened on both the legacy and the v1 paths.

Changes:

  • Breaking: MCP instrumentation no longer relabels the client. Removes _lib_identity.py, POSTHOG_MCP_LIB_NAME, Client._set_library_identity, and the request plumbing that existed only to send the relabeled User-Agent on flag, flag definition and remote config requests.
  • The MCP README and the migration guide say how identity works in 8.0. A $lib or $lib_version set in a call, in super_properties or in before_send does not reach PostHog. To find MCP traffic, filter on $mcp_* events and properties.
  • Changeset (major).

Go makes the same call in PostHog/posthog-go#361 (removes Capture.Library). posthog-rs always sends posthog-rs.

Note for reviewers: SDK Health and flag analytics list posthog-python-mcp as its own SDK. After 8.0, MCP servers count as posthog-python there. A per-event way for MCP SDKs to identify themselves is tracked as a follow-up.

💚 How did you test it?

  • test_instrument_keeps_the_host_client_identity (was test_instrument_relabels_the_host_client) now checks that a client passed to instrument() keeps $lib: posthog-python. Bringing back the relabel fails it.
  • test_mcp_client_keeps_the_sdk_identity checks that a PostHogMCP client sends PostHog-Sdk-Info: posthog-python/<version>.
  • The four tests that pinned the posthog-python-mcp identity on events, flags, flag definitions and remote config are removed, together with the code they covered.
  • ruff, mypy (baseline filter), make public_api_check, python -W error -c "import posthog", and the full pytest suite pass locally.

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran sampo add to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Cursor agent (Claude). The author decided that an SDK has one identity on capture v1, and that integrations must not relabel it. The alternative, splitting batches per library so each request can carry its own header, was rejected.

MCP instrumentation relabeled the whole client, so the app's own events and flag requests reported posthog-python-mcp. Capture v1 takes $lib from the per-request PostHog-Sdk-Info header, which is now always posthog-python.

This branch has not been deployed

No deployments
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.

1 participant