Skip to content

feat(server-utils): Auto-instrument MCP servers via orchestrion - #24529

Open
mydea wants to merge 3 commits into
developfrom
feat/mcp-server-auto-instrumentation
Open

mydea wants to merge 3 commits into
developfrom
feat/mcp-server-auto-instrumentation

Conversation

@mydea

@mydea mydea commented Sep 21, 2026

Copy link
Copy Markdown
Member

McpServer instances currently only produce spans when the user manually calls wrapMcpServerWithSentry. This adds an mcpServer integration (default, tracing) that wraps every McpServer at construction through an orchestrion constructor hook, so no manual call is needed.

Both SDK families are covered: @modelcontextprotocol/server (v2) — whose McpServer lives in a content-hashed tsdown chunk, so it's matched by a regex filePath with className: 'McpServer' as the real selector, the same shape mastra.ts uses — and @modelcontextprotocol/sdk (v1). The subscriber just hands the constructed instance to the existing wrapMcpServerWithSentry, reusing all of its transport/handler instrumentation rather than reimplementing anything.

wrapMcpServerWithSentry stays fully supported. Re-wrapping an already-wrapped instance never patches it twice, but capture options are tracked per server (WeakMap): a later call fills in recordInputs/recordOutputs left unset by an earlier wrap. So the auto-wrap's defaults yield to a later manual override — a user can still wrapMcpServerWithSentry(server, { recordInputs: false }) to opt out — while an explicit first wrap still wins. The transport reads these options per message.

mcpServerIntegration is re-exported from the runtime packages that surface the other tracing integrations (node, bun, deno, elysia, aws/gcp serverless, astro), alongside mastraIntegration.

🤖 Generated with Claude Code

Add an `mcpServer` integration that wraps `McpServer` instances at
construction through an orchestrion constructor hook, so users no longer
need to call `wrapMcpServerWithSentry` by hand. Covers both
`@modelcontextprotocol/server` (v2, matched in its content-hashed chunk)
and `@modelcontextprotocol/sdk` (v1). `wrapMcpServerWithSentry` stays a
supported, idempotent no-op when the instance was already auto-wrapped.

Rename the existing manual node-integration-test suite to
`mcp-server/manual-instrumentation` and add `mcp-server/v1` and
`mcp-server/v2` suites that exercise the auto-wrapping path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e0e1545. Configure here.

Comment thread packages/server-utils/src/integrations/mcp-server.ts
Comment thread packages/server-utils/src/index.ts
@github-actions

github-actions Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.09 kB - -
@sentry/browser - with treeshaking flags 27.35 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.26 kB - -
@sentry/browser (incl. Tracing) 50.56 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 50.58 kB - -
@sentry/browser (incl. Tracing, Profiling) 53.56 kB - -
@sentry/browser (incl. Tracing, Replay) 90.11 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 79.21 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 94.81 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 107.78 kB - -
@sentry/browser (incl. Feedback) 46.62 kB - -
@sentry/browser (incl. sendFeedback) 34.15 kB - -
@sentry/browser (incl. FeedbackAsync) 39.26 kB - -
@sentry/browser (incl. Metrics) 30.1 kB - -
@sentry/browser (incl. Logs) 30.35 kB - -
@sentry/browser (incl. Metrics & Logs) 31.02 kB - -
@sentry/react 30.84 kB - -
@sentry/react (incl. Tracing) 52.88 kB - -
@sentry/vue 36.34 kB - -
@sentry/vue (incl. Tracing) 52.86 kB - -
@sentry/svelte 29.11 kB - -
CDN Bundle 30.8 kB - -
CDN Bundle (incl. Tracing) 51.1 kB - -
CDN Bundle (incl. Logs, Metrics) 33.06 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 53.09 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 73.75 kB - -
CDN Bundle (incl. Tracing, Replay) 88.66 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 90.58 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 94.7 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 96.71 kB - -
CDN Bundle - uncompressed 91.16 kB - -
CDN Bundle (incl. Tracing) - uncompressed 152.53 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 97.73 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 158.49 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 227.14 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 272.1 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 278.04 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 285.81 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 291.74 kB - -
@sentry/nextjs (client) 55.21 kB - -
@sentry/sveltekit (client) 50.99 kB - -
@sentry/core/server 40.04 kB +0.11% +43 B 🔺
@sentry/core/browser 13.66 kB - -
@sentry/node 138.03 kB +3.54% +4.72 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 82.25 kB +0.11% +86 B 🔺
@sentry/node - without tracing 90.02 kB +0.13% +111 B 🔺
@sentry/node - without channel injection 116.82 kB +4.18% +4.69 kB 🔺
@sentry/aws-serverless 98.3 kB +0.13% +122 B 🔺
@sentry/cloudflare (withSentry) - minified 204.74 kB - -
@sentry/cloudflare (withSentry) 509.41 kB - -

View base workflow run

@mydea
mydea added this pull request to stack #24534 September 21, 2026 08:30
mydea and others added 2 commits September 21, 2026 10:39
Auto-instrumentation wraps each `McpServer` at construction with no explicit
capture options. The double-wrap guard previously ignored a later manual
`wrapMcpServerWithSentry(server, { recordInputs, recordOutputs })` entirely,
silently dropping the override so tool I/O could still be collected against a
server the user meant to opt out.

Track the mutable capture options per server (WeakMap) instead of a plain
WeakSet: a re-wrap now fills in options the first wrap left unset, so an
auto-wrap's defaults yield to a later manual override, while an explicit first
wrap still wins (unchanged, per `snapshots explicit overrides from the first
wrap`). The transport reads these options per message, so the update applies to
subsequent requests.

Also export `mcpServerIntegration` from the runtime packages that surface the
other tracing integrations (node, bun, deno, elysia, aws/gcp serverless,
astro), alongside `mastraIntegration`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Making `mcpServerIntegration` a default (tracing) integration pulls the
`wrapMcpServerWithSentry` instrumentation tree (~8.7 KB gzipped) into the
`init` path, which was previously tree-shaken out. Bump the two affected
`@sentry/node` scenarios to their measured sizes:
- `@sentry/node`: 135 -> 139 KB
- `@sentry/node - without channel injection`: 114 -> 117 KB

`@sentry/node - without tracing` is unchanged (the integration is
tracing-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mydea
mydea marked this pull request as ready for review September 21, 2026 09:05
@mydea
mydea requested review from a team as code owners September 21, 2026 09:05
@mydea
mydea requested review from JPeer264, betegon, isaacs, nicohrubec and s1gr1d and removed request for a team September 21, 2026 09:05
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