Skip to content

ref(mcp-server): Shrink the stdio bundle's Zod and memory footprint #1761

Open

Description

@sentry-junior

Follow-up from #1731. BYK asked for @sentry/mcp-server to use valibot instead of Zod, like the CLI. We left it out of #1731 and track it here, together with the bundle size and memory use it affects.

Measurements

Taken from the esbuild metafile of packages/mcp-server/dist/sentry-mcp.cjs, built from the #1731 branch:

Input Size Share of 3.58 MB
mcp-core 832 KB 23%
zod 4.6.7 508 KB 14%
@sentry/api 482 KB 13%
@modelcontextprotocol/server 2.x 288 KB 8%
ajv 104 KB 3%
@modelcontextprotocol/sdk 1.x 62 KB 2%

The 508 KB of Zod breaks down as:

  • zod/v4/locales: 260 KB. Every error-message locale is included, but we only use English. The classic, mini, and core entry points all import locales/index.js.
  • zod/v3: about 58 KB. It is loaded by @ai-sdk/provider-utils, zod-to-json-schema, and the v1 SDK's zod-compat.
  • zod/v4 core and classic: about 190 KB.

Memory on Node 22: bare node uses about 45 MB RSS. The bundle uses about 137 MB RSS for --version and about 144 MB RSS (27 MB heap) when idle as a stdio server. Loading zod alone adds about 3.5 MB of heap and 80 ms.

Why moving to valibot alone won't fix this

@modelcontextprotocol/server 2.x depends on zod ^4.2.0 and loads zod/v4 internally. Replacing our schemas with valibot would still ship Zod core in the bundle. On top of that, the change would touch 96 non-test files in mcp-core and 6 in mcp-cloudflare, and valibot would need @valibot/to-json-schema to produce the tool JSON schemas the SDK requires.

Options, cheapest first

  1. Stub zod/v4/locales down to en in packages/mcp-server/script/bundle.ts. This saves about 260 KB without changing any code.
  2. Remove the zod/v3 and zod-to-json-schema paths and the v1 @modelcontextprotocol/sdk from the stdio bundle, if nothing in that graph needs them at runtime.
  3. Lazy-load the tool modules so --version, --help, and startup don't parse the whole bundle.
  4. Only if that isn't enough: migrate mcp-core schemas to Standard Schema / valibot. Measure first, because the SDK keeps Zod in the bundle regardless.

Done when

  • The bundle size and idle RSS have been measured before and after each change.
  • MAX_BUNDLE_BYTES in bundle.ts is lowered to the new size.

via BYK.

--

View Session in Sentry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions