Atlas survey

Shipping Your MCP Server: Deployment & Distribution in 2026

How you actually ship and share the MCP server you built: transport choice, packaging channels, the official registry, and client config.

16 sources ~4 min read mcp · deployment · distribution · registry · mcpb · claude-code

Decision. Ship a local stdio server when one user runs it on their own machine — publish it as an npm/PyPI package (npx/uvx) or wrap it in a .mcpb bundle for one-click Claude Desktop install [1][7]. Go remote Streamable-HTTP the moment many users share one instance or you need auth, audit, and horizontal scale — host it on Cloudflare Workers, a container, or a serverless platform [1][2]. For discovery, publish server.json to the official MCP Registry [4] — but it only stores metadata pointing at npm/PyPI/NuGet/Docker; your code still lives in a package registry.

Transport: where the server runs

Transport is the first deployment decision because it dictates everything downstream (hosting, auth, packaging).

Axis stdio (local) Streamable HTTP (remote)
Where it runs Subprocess on the client’s machine A web service reachable over the network
Process model One process per user — 50 devs × 8 servers ≈ 400 processes [1] One process serves many clients concurrently [1]
Single-call latency ~0.3–1 ms warm (p95 ~2–3 ms) [1] ~5–10 ms same-DC (p95 ~15–25 ms) [1]
Auth None at transport layer (env vars only) [1] Authorization header, OAuth 2.1 + PKCE [1][2]
Best for Local dev, single-user desktop tools [3] Team sharing, SaaS, identity/audit/RBAC/scale [1]

Streamable HTTP (MCP spec 2025-03-26) is JSON-RPC 2.0 over a single HTTP endpoint supporting POST and GET, with optional Server-Sent Events for streaming — it replaces the deprecated HTTP+SSE transport [3]. The migration from stdio is mechanical: with the TypeScript SDK you swap the stdio adapter for the HTTP server adapter; tools and handlers are unchanged [2][1]. The 5–10 ms HTTP overhead is rarely the dominant cost against an LLM call, so don’t pick stdio for latency alone [1].

Hosting a remote server

Option Notes
Cloudflare Workers ⭐ 3.8k Official template; ~0ms cold start, global edge, free tier 100K req/day; OAuth built-in [2][5]
Vercel / serverless functions Free tier; good fit if you already deploy there [5]
FastMCP Cloud / mcphosting.io Managed MCP-specific hosting, free personal tiers [5]
Your own container (Docker) Run the HTTP server behind a load balancer; full control, you own auth/scale [6]

For public servers you can skip auth entirely; for private ones add an X-API-Key header or implement OAuth 2.1 with PKCE (the MCP spec standard) [2][5].

Packaging & distribution channels

A local server gets distributed as a runnable package; a remote server gets distributed as a URL. The channels:

Channel How users run it Best for One-click?
npm (npx) npx -y your-mcp-server Node/TypeScript SDK servers [10] ✗ (config)
PyPI (uvx) uvx your-mcp-server Python servers [10] ✗ (config)
Docker / OCI docker run your/mcp-image Pinned deps, isolation, CI/CD [4] ✗ (config)
.mcpb bundle Double-click → Install [7] End users on Claude Desktop, no runtime needed
Remote URL Paste https://…/mcp into client SaaS, zero-install, shared instance [2] ~ (deeplink)

npx -y and uvx are the default distribution for SDK-built servers: ship the package to npm/PyPI and the client’s config just references the command. The registry’s supported package types map directly to npm, PyPI, NuGet, and Docker Hub [4].

DXT / .mcpb — one-click desktop install

Desktop Extensions ⭐ 1.9k bundle an entire local MCP server — including all dependencies — into a single installable package, “spiritually similar to Chrome extensions (.crx) or VS Code extensions (.vsix)” [7]. Note the rename: the format moved from .dxt to .mcpb (MCP Bundle); existing .dxt files still work but use .mcpb for new extensions [8].

A .mcpb is a zip archive containing the server plus a manifest.json — the only required file — declaring name, tools/prompts, user configuration, and runtime requirements [8]. It eliminates the usual friction: Claude Desktop bundles Node.js, so users need no developer tools, and sensitive config like API keys is stored in the OS keychain [8]. Build it with the CLI [9]:

npm install -g @anthropic-ai/mcpb
mcpb init    # scaffold manifest.json
mcpb pack    # produce the .mcpb file

Publishing to the official MCP Registry

The official MCP Registry ⭐ 6.9k is the official centralized metadata repository for publicly accessible servers, backed by Anthropic, GitHub, PulseMCP, and Microsoft [4]. It is an “app store for MCP servers” but hosts metadata only, not code [12] — package registries (npm, PyPI, Docker Hub) host the binaries; the registry maps a server name + version to e.g. npm:weather-mcp [4]. It is still in preview (API freeze v0.1, GA pending) and is designed to be consumed by downstream aggregators/marketplaces — not directly by host apps [4].

Server names use reverse-DNS namespaces tied to verified GitHub accounts or domains, so only the legitimate owner can publish under io.github.<username>/* [4]. The publish flow [11]:

  1. Write a server.json (name, version, packages[] with registryType + transport, repository).
  2. Reference the name in your package README as <!-- mcp-name: io.github.you/server --> so the registry can verify ownership.
  3. Publish the package to npm/PyPI/NuGet/Docker.
  4. Authenticate and publish the metadata:
./mcp-publisher login github          # browser code flow → unlocks io.github.<you>/*
./mcp-publisher publish .mcp/server.json

The registry does not support private servers (private networks or private package registries) — self-host your own registry implementing the OpenAPI spec for those [4]. The GitHub MCP Registry will soon source its listings from the official registry [11].

Installing into clients

Every client speaks the same protocol, so a package is interchangeable — but each has its own config file and command [13].

Client Config file / command stdio example remote example
Claude Desktop .mcpb install, or claude_desktop_config.json [8] manifest-driven, no JSON edit — (use .mcpb / connectors)
Claude Code claude mcp add.mcp.json / ~/.claude.json [14] claude mcp add --transport stdio fs -- npx -y @some/mcp claude mcp add --transport http notion https://mcp.notion.com/mcp
VS Code .vscode/mcp.json or code --add-mcp [10] {"command":"npx","args":["-y","@.../server"]} {"type":"http","url":"https://…/mcp"}
Cursor .cursor/mcp.json or “Add to Cursor” deeplink [15][16] mcpServers block with command/args base64 deeplink: cursor://anysphere.cursor-deeplink/mcp/install?name=…&config=…

Notes for distributors:

  • Scope = sharing. In Claude Code, --scope project writes .mcp.json at the repo root; commit it and every teammate’s machine gets the same config [14]. VS Code’s .vscode/mcp.json and Cursor’s .cursor/mcp.json work the same way [10][15].
  • Deeplinks are the closest thing to one-click for editors: ship an “Add to Cursor”/”Install in VS Code” button that encodes the server config so users skip JSON editing [16].
  • SSE is deprecated as of early 2026 — emit HTTP config, not SSE, for new servers [14].
  • Never hardcode secrets in shared config; use input variables / env files [10].

Practical recommendation

Build once with the TypeScript SDK (repo ⭐ 12.6k), then pick channels by audience: publish the npm package (works in every editor via npx), wrap a .mcpb for non-technical Claude Desktop users, and — when you outgrow per-user processes — stand up a Streamable-HTTP instance and hand out a URL plus an “Add to Cursor” deeplink. List server.json in the official registry so aggregators surface you [4].

Citations · 16 sources

Click the Citations tab to load…