Skip to content

feat(deps): make HTTP/SSE transport deps optional for stdio-only consumers#1964

Open
MukundaKatta wants to merge 1 commit intomodelcontextprotocol:v1.xfrom
MukundaKatta:fix/optional-http-deps-stdio-1924
Open

feat(deps): make HTTP/SSE transport deps optional for stdio-only consumers#1964
MukundaKatta wants to merge 1 commit intomodelcontextprotocol:v1.xfrom
MukundaKatta:fix/optional-http-deps-stdio-1924

Conversation

@MukundaKatta
Copy link
Copy Markdown

Closes #1924.

Why

The published v1 SDK ships express, cors, express-rate-limit, @hono/node-server, eventsource, eventsource-parser, raw-body, content-type, hono, and jose as direct runtime dependencies. Stdio-only consumers (the most common deployment for local MCP servers) never load any of that code, but every install still pulls in ~22 MB / 60+ transitive packages and lights up supply-chain analyzers (Socket, Snyk, Scorecard) for code paths the user never imports.

The issue author's mercury-invoicing-mcp server is a 33 KB stdio-only bundle that picks up 6 Socket alerts originating from the Express tree. A second commenter (jibbius) reports the dependency tree size is currently a blocker for adoption inside their workplace. None of those alerts are actionable for stdio-only maintainers.

This PR implements Option 2 from the issue — the lightest-touch fix that doesn't require splitting the package or introducing new conditional exports.

What

  • package.json
    • Move express, cors, express-rate-limit, @hono/node-server, raw-body, content-type, eventsource, eventsource-parser, jose from dependencies to peerDependencies with peerDependenciesMeta.<name>.optional = true. npm 7+, pnpm, and yarn skip optional peers that aren't already in the consumer's tree, so stdio-only installs no longer pull them in.
    • Drop hono from runtime deps entirely. It is only referenced by src/examples/server/honoWebStandardStreamableHttp.ts (kept available via devDependencies); nothing in src/server/** or src/client/** imports it.
    • Mirror the moved packages into devDependencies so the local repo (tests, examples, build) keeps a green install.
  • README.md — add an "Optional peer dependencies" matrix mapping each transport / OAuth helper to the package(s) it now requires the consumer to install.
  • test/stdio-only-imports.test.ts — new static-analysis test that reads src/{client,server}/stdio.ts, src/shared/*.ts, src/types.ts, and src/inMemory.ts and asserts none of them statically import / require an HTTP-only peer. Catches future regressions where someone accidentally moves an HTTP dep behind a top-level import in a stdio path.
  • .changeset/optional-http-sse-deps.mdmajor changeset (peer-dep relocation is a soft breaking change for HTTP consumers who relied on the SDK to install Express transitively).

The transport modules themselves are unchanged. Each HTTP/SSE module still imports its peer at the top of the file, so a consumer who imports @modelcontextprotocol/sdk/server/streamableHttp.js without installing @hono/node-server gets an immediate, clearly-attributed ERR_MODULE_NOT_FOUND at load time pointing at the missing package.

Tested

  • npm test — 49 files, 1586/1586 passing (no behavior changes).
  • npm test -- --run test/stdio-only-imports.test.ts — new test passes 7/7.
  • npm install --omit=dev --omit=optional --dry-run reports 290 packages removed from the production tree vs the prior dependencies set.
  • All existing HTTP / SSE / OAuth tests (test/server/streamableHttp.test.ts, test/server/sse.test.ts, test/server/auth/**, test/client/sse.test.ts, test/client/streamableHttp.test.ts) continue to pass — the peers resolve fine because they're declared in devDependencies.

Notes for reviewers

  • The major changeset bump is conservative — strictly speaking, this only breaks consumers who relied on the SDK to install Express / Hono transitively, which is a behavior change but not an API change. Happy to downgrade to minor if that matches the maintenance policy on v1.x.
  • The v2 monorepo (main) already addresses the same root cause architecturally via the @modelcontextprotocol/{client,server,node,express,hono} split; this PR is the equivalent fix for users on the published 1.x line who can't wait for v2.
  • I also looked at PR fix(node): make hono an optional peer dependency #1896 (makes hono an optional peer in the v2 /node package) — that change is scoped to v2 and doesn't address v1 consumers.

@MukundaKatta MukundaKatta requested a review from a team as a code owner April 26, 2026 21:44
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 26, 2026

🦋 Changeset detected

Latest commit: e344cbe

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

…umers

Move `express`, `cors`, `express-rate-limit`, `@hono/node-server`,
`raw-body`, `content-type`, `eventsource`, `eventsource-parser`, and
`jose` from runtime `dependencies` to optional `peerDependencies`.
Drop the unused-at-runtime `hono` package entirely (only referenced
by an example).

For stdio-only consumers (the most common deployment for local MCP
servers) this removes ~22 MB / 60+ transitive packages from the
install, eliminating supply-chain alerts for code paths the user
never loads. Apps that already depend on Express, Hono, etc. via
their own `package.json` continue to work unchanged.

Adds a static-analysis test that asserts the stdio transport source
files never grow a static import of an HTTP/SSE-only peer dep, so
the lazy boundary cannot regress silently.

Closes modelcontextprotocol#1924.
@MukundaKatta MukundaKatta force-pushed the fix/optional-http-deps-stdio-1924 branch from 02b4a63 to e344cbe Compare April 26, 2026 22:02
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 26, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@modelcontextprotocol/sdk@1964

commit: e344cbe

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