modelcontextprotocol / modelcontextprotocol/ext-apps

@modelcontextprotocol/ext-apps consumers ship ~140K of unused zod v4 locale files in browser bundles

Open
#665 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.9k
Forks
387
Avg merge
3h 21m
Merged PRs (30d)
6

Description

I discovered while developing an mcp-app using the sdk (client side only) that the bundle contained all of zod's locales because of a start import that prevented vite's / rolldown's tree-shaking from working.

I was able to work around this by developing (with the help of AI) a little vite plugin to strip it:

// Zod v4 re-exports every locale via `export * as locales` from its classic
// entrypoint, which defeats tree-shaking when the MCP SDK imports `* as z from
// 'zod/v4'`. Replace the locales index with an `en`-only stub so the namespace
// still exists but the other ~50 locale files never enter the graph.
const zodLocalesEnOnly = {
  name: "zod-locales-en-only",
  enforce: "pre",
  load(id) {
    if (/[\\/]zod[\\/](?:v4[\\/])?locales[\\/]index\.js$/.test(id)) {
      return 'export { default as en } from "./en.js";';
    }
    return null;
  },
};

See https://github.com/les2/mcp-ext-apps-zod-locale-bloat for a minimal demonstration of the issue.

Below is an AI issue description:

@modelcontextprotocol/ext-apps consumers ship ~140K of unused zod v4 locale files in browser bundles

Summary

Any browser app that depends on @modelcontextprotocol/ext-apps (and therefore on @modelcontextprotocol/sdk) bundles all ~50 zod v4 locale files — Spanish, French, German, Japanese, Chinese, Korean, Russian, etc. — because of a tree-shaking dead-end in the transitive zod chain. On our widget (Ember + Vite + Rollup) this was ~140K of dead weight, ~20% of the final bundle.

The end result is that every browser bundle currently ships translated error strings like 数値過大:期望, Trop court, demasiado corto, zu kurz — none of which are ever displayed, since the SDK only uses zod's English error messages at runtime.

A minimal reproduction is available at https://github.com/les2/mcp-ext-apps-zod-locale-bloatnpm install && npm run compare builds twice (without and with the workaround) and prints the size delta.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal reproduction at les2/mcp-ext-apps-zod-locale-bloat and run npm install && npm run compare to observe the bundle difference. Trace the SDK's zod import path and how Vite or Rollup handles the locale re-export. Done means browser consumers no longer include unused zod locale files without requiring a consumer-side workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
rollup, typescript, vite
Domain
build-system, frontend, performance
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.