A .mcpb is an ordinary zip. Unzip one and the top level holds
manifest.json and a server/ directory containing the built server and its
entire node_modules tree. Nothing is resolved at install time, which is the whole point:
the user needs no runtime, no package manager and no PATH.
$ unzip -l barcode.mcpb | head
3464 manifest.json
28942 server/index.js
761 server/lib.js
80732 server/node_modules/.package-lock.json
...
{
"manifest_version": "0.2",
"name": "mcp-barcode",
"display_name": "Barcode",
"version": "0.21.0",
"description": "...",
"author": { "name": "theluckystrike", "url": "https://github.com/theluckystrike" },
"repository": { "type": "git", "url": "https://github.com/theluckystrike/mcp-servers" },
"homepage": "https://mcp.zovo.one",
"license": "MIT",
"server": {
"type": "node",
"entry_point": "server/index.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/server/index.js"],
"env": { "MCP_LICENSE_KEY": "${user_config.license_key}" }
}
},
"user_config": {
"license_key": {
"type": "string",
"title": "License key",
"description": "Optional Pro license key. Leave blank to use the free tier.",
"sensitive": true,
"required": false
}
},
"tools": [ { "name": "qr_create", "description": "..." } ],
"keywords": ["mcp", "model-context-protocol", "qr", "barcode"]
}
That is a real manifest from this repository's v0.21.0 release, trimmed only in the tools array.
${__dirname} expands to wherever the client unpacked the bundle. This is what makes
the absolute-path problem disappear. Every other client config format needs the user to write an
absolute path themselves, and getting it wrong is the second most common install failure after a
missing runtime.
${user_config.<key>} pulls a value the user typed into the install dialog into
the server's environment. Each key in user_config declares a type, a title, a description,
whether it is required, and whether it is sensitive, which is what keeps a
licence key or an API token out of a plain text file and out of your logs.
The tools array is declarative. It lets the install dialog show what the server will be
able to do before anything runs, which is the only chance a non-developer gets to refuse.
The 32 bundles in the v0.21.0 release of this repository total 222,294,768 bytes, a mean of 6.6 MB.
The largest inspected here, barcode.mcpb, is 14 MB; invoice.mcpb is 7,023,082
bytes. The variance is dependencies, not code: the server entry point in that barcode bundle is 28,942
bytes and everything else is node_modules.
In a paginated sample of the official MCP registry on 2026-09-08, covering 2,211 distinct servers,
9 declared an mcpb package. npm had 259, PyPI 41, OCI 15 and NuGet 1,
while 1,985 servers skipped packaging entirely and published a URL. So the one distribution format
aimed at people without a terminal is used by roughly one server in 250.
npx -y @anthropic-ai/mcpb pack <dir>
The directory needs a manifest.json and the built server beside it. The part that takes
the time is vendoring: anything your server imports has to be inside the zip, including workspace
packages that are not published anywhere. In this repository that meant resolving the whole internal
package closure into server/node_modules/ and merging their runtime dependencies into one
temporary package.json so a single install covers everything.
Claude Desktop's documentation describes opening a bundle to get an installation dialog, and a
bundle you built yourself goes in through Settings, Extensions, Advanced settings, the Extension
Developer section, Install Extension. The format was previously named .dxt; that rename is
recorded with its source URL in billing/src/setup.js, read off the vendor documentation on
2026-09-02.
A bundle downloaded from a public GitHub release, opened with no terminal involved, was verified
working from a stranger's position on 2026-09-08 in docs/NEW_USER_E2E_R1.md.
Nothing in the manifest carries a signature, so trust comes from where you downloaded it. Publishing bundles as release assets on the repository that contains the source is what lets someone check that the two match.
The manifest names one entry point, so a bundle is one server. A server that spawns siblings as child processes is still one entry point from the client's side, which is how a suite ships as a single install.
Because the dependency tree is inside it. A bundle trades bytes for the two failures it removes: no runtime resolution and no absolute path for the user to get wrong.
It goes into the server's environment through the ${user_config.key} substitution in mcp_config.env. Marking a field sensitive is what keeps it out of plain text, which matters for licence keys and API tokens.
All MCP servers and prices · All guides · Buy the bundle $39