Skip to content

chore: declare the MCP SDK packages only at the repo root, so every client resolves one copy #1970

Description

@cliffhall

Summary

The four v2 SDK packages — @modelcontextprotocol/client, core, server, server-legacy — are declared both in the repo-root package.json and again in clients/web, clients/cli, and (two of them) clients/tui. Each declaration installs its own copy into that client's node_modules. They should be declared once, at the root, and resolved from there by every client.

Why it matters

v2 is deliberately not an npm workspace, so each client has its own node_modules — but Node resolution walks up, and the root install is on every client's chain. The root manifest is already the source of truth for what ships: per the README, "Runtime dependencies are declared on the root package.json; client builds bundle @inspector/core and externalize npm packages resolved from the root install." The per-client copies are therefore duplicates of a decision made at the root, and duplicates can drift.

That drift is not hypothetical here. The same pins in five places have to be bumped in lockstep or a client silently builds against a different SDK copy than the one the tarball will resolve — and a second copy of @modelcontextprotocol/client/core is exactly the failure the vitest config already carries a dedupe + server.deps.inline workaround for (a vi.mock that misses because the mock and the import resolved to different copies).

yaml in vitest.shared.mts is the existing precedent: it is aliased to the repo-root node_modules while every other pinned package points at the client's own.

Scope

Remove the four packages from clients/web, clients/cli, and clients/tui package.json, leaving the root declaration as the single source. clients/launcher declares none of them today and stays as-is.

@modelcontextprotocol/ext-apps rides along

ext-apps is declared twice (root + clients/web) and is the only reason the v1 SDK is installed at all: it declares @modelcontextprotocol/sdk: ^1.29.0 as a peer, which npm auto-installs. Nothing in this repo imports @modelcontextprotocol/sdk — it appears in no package.json of ours, only as "peer": true in the lock files — so there is nothing to "remove", but there are currently two copies at two versions: 1.29.0 at the root and 1.30.0 under clients/web. Consolidating ext-apps to the root collapses that to one copy at one version, which is the only lever we have over a transitive peer.

Acceptance

  • The four packages (plus ext-apps) appear in exactly one package.json: the root.
  • npm install at the root still produces a working tree for every client; npm run ci passes.
  • No second copy of the v1 @modelcontextprotocol/sdk in any client node_modules after a clean install.

Metadata

Metadata

Assignees

Labels

choreMaintenance: deps, build tooling, CI, cleanup — no user-facing behavior changev2Issues and PRs for v2

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions