feat(client): override SDK surface to "mcp" for usage telemetry#15
Merged
Conversation
Constructs the underlying devhelm.Devhelm SDK with surface="mcp" so the API attributes traffic to the MCP server rather than to bare-SDK use. The SDK's X-DevHelm-Sdk-Name header is preserved alongside, so the API can still see which devhelm SDK version this MCP build is on for client-version skew debugging. Surface version comes from importlib.metadata; reports the installed devhelm-mcp-server release. Falls back to "unknown" for source-tree installs. Detecting the host MCP client (Cursor vs Claude Desktop vs ...) is deferred — fastmcp's Context.session.client_params.clientInfo carries that info, but threading Context through every tool would be a wide surgery against this PR's "no callsite changes" goal. The wire contract already supports X-DevHelm-Mcp-Client via surface_metadata so we can layer it in later without an API change. Depends on devhelm>=0.6.0 (which ships the surface=/surface_version=/ surface_metadata= constructor kwargs). pyproject pin bumped accordingly. Tests: 1 new test in test_client.py asserting the SDK is built with the mcp surface override. Full suite (58) green; ruff + mypy clean. Wire contract docs: https://devhelm.io/telemetry API-side handler: devhelmhq/mono#332 SDK-side change: devhelmhq/sdk-python#19 Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
Tells the API that traffic from this server is MCP traffic, not bare-SDK traffic. Surgical 10-line override at the single SDK construction site (
get_client); zero callsite changes.Wire effect
X-DevHelm-Surfacesdk-py(defaulted by SDK)mcpX-DevHelm-Surface-VersionX-DevHelm-Sdk-Namesdk-pysdk-py(preserved — lets the API debug client-version skew between MCP + SDK)Dependencies
This PR pins
devhelm>=0.6.0because thesurface=/surface_version=constructor kwargs land indevhelmhq/sdk-python#19. Order:devhelmhq/sdk-python#19(cutsdevhelm 0.6.0)devhelm-mcp-serverreleaseUntil the SDK release ships, this PR's CI will fail dependency resolution. That's expected and the failure message is the dependency itself.
Future work (deliberately not in this PR)
Detecting the host MCP client (Cursor vs Claude Desktop vs Claude Code vs Zed vs ...) so the API gets
X-DevHelm-Mcp-Client: <name>for finer-grained adoption analytics. The fastmcpContext.session.client_params.clientInfocarries that info, but threading Context through every tool would be exactly the per-callsite surgery this PR's goal forbids. The wire contract already supportsX-DevHelm-Mcp-Clientviasurface_metadataso we can layer it in as a small follow-up.Tests
test_client.pyassertsget_client()builds the SDK with surface=mcp + version + sdk-name preservedTest plan
pytest -q— 58 / 58 green (against localdevhelm0.6.0 install)ruff check + format --check + mypy --strict— cleanorg_surface_usagerow carriessurface=mcp+ themcp_server_first_callPostHog event firesWire contract: https://devhelm.io/telemetry
API-side handler:
devhelmhq/mono#332SDK-side change:
devhelmhq/sdk-python#19Made with Cursor