fix(core): resolve MCP capture policy per operation - #23437
Merged
Conversation
Contributor
size-limit report 📦
|
betegon
marked this pull request as ready for review
August 14, 2026 19:37
Contributor
|
👋 @JPeer264 — Please review this PR when you get a chance! |
2 similar comments
Contributor
|
👋 @JPeer264 — Please review this PR when you get a chance! |
Contributor
|
👋 @JPeer264 — Please review this PR when you get a chance! |
MCP servers can be wrapped before a Sentry client exists, causing inherited data collection settings to be fixed to their fallback values. Resolve inherited policy when an operation begins and retain request policy through response correlation. Co-Authored-By: OpenAI Codex <[email protected]>
Node module evaluation and Cloudflare Durable Object initialization can wrap MCP servers before Sentry binds a client. Exercise both runtimes with marker content so capture-policy regressions are observable. Co-Authored-By: OpenAI Codex <[email protected]>
Keep the public input and output capture defaults protected when an MCP operation has no active client or explicit overrides. Co-Authored-By: OpenAI Codex <[email protected]>
JPeer264
force-pushed
the
bt/fix-mcp-capture-policy
branch
from
August 31, 2026 12:27
7d7937d to
3af48f3
Compare
JPeer264
force-pushed
the
bt/fix-mcp-capture-policy
branch
from
August 31, 2026 15:30
9ab7892 to
5e8c79c
Compare
JPeer264
added a commit
that referenced
this pull request
Sep 2, 2026
Backport of: #23437 ## Differences to the original PR - `packages/core/src/integrations/mcp-server/transport.ts`: the no-client fallback in `resolveMcpOptions` is `false` for `recordInputs`/`recordOutputs`, not `true`. On v10 `resolveDataCollectionOptions` still routes through the `sendDefaultPii` bridge when `dataCollection` is absent, so the old `wrapMcpServerWithSentry` code fell back to `false` when no client existed. Keeping `true` here would start capturing MCP inputs and outputs on a maintenance branch. - `packages/core/src/integrations/mcp-server/transport.ts`: `startInactiveSpan` is imported from `../../tracing` together with `withActiveSpan`; v10 has no separate `../../tracing/trace` import in this file. - `packages/core/test/lib/integrations/mcp-server/capturePolicy.test.ts`: the span-config helpers use `sentry.source` instead of `sentry.segment.name.source`, and the tool config carries a top-level `op: 'mcp.server'`, matching v10's `buildMcpServerSpanConfig`. The no-client case asserts that inputs and outputs are omitted, following the fallback above. - `dev-packages/e2e-tests/test-applications/node-express/src/app.ts`: the `dataCollection.genAI` block is not added. On v10 the presence of any `dataCollection` key switches the resolution base from the `sendDefaultPii` bridge to the permissive spec defaults, which would have flipped `userInfo`, `cookies`, `httpHeaders`, `httpBodies` and `databaseQueryData` on for every other test in this app. Without the block, `genAI` already resolves to `{ inputs: false, outputs: false }`, so the new MCP e2e assertions hold unchanged. - `dev-packages/e2e-tests/test-applications/cloudflare-mcp-agent/src/index.ts`: the `genAI` settings are merged into the existing `dataCollection: { userInfo: true }` object. v10 already sets `dataCollection` in both `Sentry.init` calls, so the original patch would have produced a duplicate key and silently dropped `userInfo: true`. Co-authored-by: Miguel Betegón <[email protected]>
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.
MCP server instrumentation now honors the active Sentry client's GenAI input
and output collection settings even when the server was wrapped before that
client became available. Explicit wrapper overrides still win independently,
and the existing default remains unchanged when no policy is configured.
The capture decision belongs to the operation that starts the span.
Request/response pairs therefore retain one policy for their full lifetime
instead of allowing response timing or a different active scope to change what
gets recorded. Notifications resolve against the client active when their
operation begins. Explicit options are also snapshotted on the first wrap,
preserving the wrapper's idempotent behavior.
This is shared transport behavior, so it applies to sessionful MCP SDK v1 and
stable MCP SDK v2 without changing the public API. Packaged SDK coverage uses
the Node and Cloudflare MCP fixtures. A disposable Cloudflare Worker running
the packaged SDK also verified the policy matrix against Sentry for both modern
and legacy-compatible requests.
Root cause
wrapMcpServerWithSentryreaddataCollection.genAIonce, while the wrapperwas being constructed. Common Node import ordering and Cloudflare Durable
Object initialization can run that code before Sentry binds a client, causing
the
truefallback to become the permanent capture policy for every operationhandled by that server.
Fixes #23436