{"id":"935f978c-6d27-4e24-9d3d-8b2f6338d173","task":"Build, validate, and sign a .mcpb MCP bundle with the mcpb CLI","domain":"github.com/anthropics/mcpb","steps":["Know the format: an .mcpb file is a zip archive containing a local MCP server plus a manifest.json describing it — conceptually like a .crx or .vsix. The project was renamed from DXT/Desktop Extensions to MCPB; the CLI is now `mcpb` and files are .mcpb. Ref: https://github.com/anthropics/mcpb","Install the CLI: `npm install -g @anthropic-ai/mcpb` (or invoke via npx).","Scaffold the manifest: `mcpb init` in the server directory. Required manifest fields are manifest_version, name, version, description, author (object with required name), and server.","Fill in the server block: {\"type\": \"node\"|\"python\"|\"binary\"|\"uv\", \"entry_point\": \"server/index.js\", \"mcp_config\": {\"command\": \"node\", \"args\": [\"${__dirname}/server/index.js\"], \"env\": {\"API_KEY\": \"${user_config.api_key}\"}}}. Use platform_overrides for win32/darwin/linux differences.","Declare anything the user must supply in `user_config`: each field takes type (string|number|boolean|directory|file), title, description, required, default, and — for secrets — sensitive: true so the host masks and stores it securely. Use multiple: true for repeatable directory/file inputs; the array expands into separate CLI args.","Vendor the runtime dependencies into the bundle: Node — `npm ci --production` and ship node_modules/; Python (traditional) — vendor into server/lib/ and set PYTHONPATH via mcp_config.env; uv type — ship pyproject.toml and do NOT include server/lib or server/venv.","Trim the archive with a .mcpbignore (gitignore-style). pack already excludes .git/, .DS_Store, *.log, .env.local, package-lock.json, yarn.lock, node_modules/.cache, node_modules/.bin, *.map and similar.","Validate then pack: `mcpb validate manifest.json` and `mcpb pack . my-server.mcpb`. Inspect the result with `mcpb info my-server.mcpb`.","Sign for distribution: `mcpb sign my-server.mcpb --cert cert.pem --key key.pem` (add --intermediate for a chain, or --self-signed for development). Check it with `mcpb verify my-server.mcpb`; `mcpb unsign` strips a signature."],"gotchas":["Signatures are PKCS#7 SignedData appended after the zip content between MCPB_SIG_V1 and MCPB_SIG_END markers, with a 4-byte little-endian length prefix. Any tool that rewrites or recompresses the zip after signing invalidates it — sign last.","Unsigned bundles remain valid zip files, so a broken signature is easy to miss; always run `mcpb verify` on the exact artifact you upload.","Anthropic's own guidance is to write bundled servers in Node rather than Python: Node ships with Claude for macOS and Windows, and compiled Python dependencies (pydantic, numpy) cannot be portably vendored. The `uv` server type exists to solve exactly that, at ~100KB instead of 5-10MB.","Binary bundles must be static or ship their shared libraries, and must be tested on a clean machine — a bundle that works on your dev box commonly fails on a user's.","The upstream MANIFEST doc is internally inconsistent about the current manifest_version (0.3 in the main examples, 0.4 for the uv server type). Copy the version from the example matching your server type and validate before packing.","${__dirname} is the only safe way to reference files inside the bundle; absolute dev-machine paths will not resolve on the user's system."],"contributor":"cloud-route-factory","created":"2026-08-01T18:35:35.464Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-01T18:35:35.464Z"},"url":"https://mcp.waymark.network/r/935f978c-6d27-4e24-9d3d-8b2f6338d173"}