This is the documentation for the v2 beta — looking for the v1 documentation?
Skip to content

Packages and subpath exports

The SDK is published as nine npm packages. Most projects install exactly one of them.

Start from one package

Everything in Build your first server came from a single install, @modelcontextprotocol/server — through two import paths.

ts
import { McpServer } from '@modelcontextprotocol/server';
import { serveStdio } from '@modelcontextprotocol/server/stdio';

The first path is the package's root entry. The second is a subpath export — a separate entry point inside the same package, declared in its exports map.

Pick the package for your side of the protocol

Install the package for the side of the protocol you are building.

sh
npm install @modelcontextprotocol/server   # expose tools, resources, prompts
npm install @modelcontextprotocol/client   # connect to servers and call them

Those two are the starting point for almost everything; a process that plays both roles installs both. The full published set is nine packages:

  • @modelcontextprotocol/server and @modelcontextprotocol/client — the two starting points, one per side.
  • @modelcontextprotocol/node, @modelcontextprotocol/express, @modelcontextprotocol/hono, @modelcontextprotocol/fastify — optional adapters for serving over HTTP.
  • @modelcontextprotocol/core — the raw Zod wire schemas.
  • @modelcontextprotocol/server-legacy and @modelcontextprotocol/codemod — migration surfaces for v1 code.

A tenth package in the repository, @modelcontextprotocol/core-internal, is private: server and client bundle it at build time, so it never appears in your dependency tree.

Keep Node-only code behind the ./stdio subpath

StdioClientTransport spawns the server as a child process, so it is exported from ./stdio, never from the root entry.

ts
// Runs anywhere: browsers, Workers, Node.
import { Client } from '@modelcontextprotocol/client';
// Spawns a child process — Node-only, so it lives behind the subpath.
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';

The root entry of every package is runtime-neutral: its module graph never reaches node:child_process or any other Node builtin a browser or Cloudflare Workers bundler cannot resolve. Importing ./stdio is the explicit opt-in to a process runtime. @modelcontextprotocol/server/stdio is the server-side counterpart and exports serveStdio and StdioServerTransport.

Coming from v1?

v1's single @modelcontextprotocol/sdk package exposed deep file paths such as @modelcontextprotocol/sdk/server/mcp.js. The v2 packages declare an exports map, so only the subpaths each package names resolve — the codemod rewrites the imports for you.

Add a framework adapter when you serve over HTTP

createMcpHandler from @modelcontextprotocol/server already serves MCP over web-standard Request and Response objects. An adapter package wires that handler into a specific runtime or framework; install the adapter next to the framework it adapts.

sh
npm install @modelcontextprotocol/express express

Four adapters exist: @modelcontextprotocol/node for Node's built-in http server, and one each for Express, Hono, and Fastify. They are thin layers over createMcpHandler and add no MCP behavior of their own.

Serve over HTTP covers the handler itself; Express, Hono, and Fastify each have a recipe.

Reach for core only to validate raw wire JSON

@modelcontextprotocol/core exports the Zod schema constants the SDK validates protocol payloads against, for code that handles raw JSON-RPC payloads itself — gateways, proxies, log pipelines. Neither server nor client exports a Zod schema, and the matching TypeScript types ship with both, so if you only call registerTool and callTool you never install it. Wire schemas is the how-to.

Leave server-legacy and codemod to the migration guide

@modelcontextprotocol/server-legacy is a frozen copy of v1's server-side SSE transport and OAuth Authorization Server helpers, published so a v1 deployment can move to v2 without replacing everything at once. @modelcontextprotocol/codemod is the command-line tool that rewrites v1 imports and call sites to their v2 forms. Neither belongs in a new project — the upgrade guide covers both.

Recap

  • @modelcontextprotocol/server and @modelcontextprotocol/client are the two packages you install, one per side of the protocol.
  • Package root entries are runtime-neutral; code that spawns processes lives at the ./stdio subpath and only enters your bundle when you import it.
  • The HTTP adapters — node, express, hono, fastify — are optional thin layers over createMcpHandler; install at most one.
  • @modelcontextprotocol/core exports only Zod schema constants, for code that validates raw wire JSON itself.
  • @modelcontextprotocol/server-legacy and @modelcontextprotocol/codemod exist for migration from v1, not for new projects.