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.
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.
npm install @modelcontextprotocol/server # expose tools, resources, prompts
npm install @modelcontextprotocol/client # connect to servers and call themThose two are the starting point for almost everything; a process that plays both roles installs both. The full published set is nine packages:
@modelcontextprotocol/serverand@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-legacyand@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.
// 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.
npm install @modelcontextprotocol/express expressFour 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/serverand@modelcontextprotocol/clientare the two packages you install, one per side of the protocol.- Package root entries are runtime-neutral; code that spawns processes lives at the
./stdiosubpath and only enters your bundle when you import it. - The HTTP adapters —
node,express,hono,fastify— are optional thin layers overcreateMcpHandler; install at most one. @modelcontextprotocol/coreexports only Zod schema constants, for code that validates raw wire JSON itself.@modelcontextprotocol/server-legacyand@modelcontextprotocol/codemodexist for migration from v1, not for new projects.