From mcp-toolkit
This skill should be used when the user asks to "build an MCPB", "create a desktop extension", "package an MCP server", "create an mcpb file", "distribute an MCP server", "bundle my MCP server", "create a local MCP extension", "make an MCP Bundle", or needs guidance on packaging a local MCP server for single-click installation in Claude Desktop. Covers the full workflow from project setup through packing, testing, and signing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mcp-toolkit:build-mcpbThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- [When to Use MCPB vs. Remote Connector](#when-to-use-mcpb-vs-remote-connector)
MCP Bundles (.mcpb) are zip archives containing a local MCP server and a manifest.json. They enable single-click installation in Claude Desktop, similar to browser extensions (.crx, .vsix).
Choose MCPB (local server) for:
Choose a remote connector for:
Claude Desktop runs on macOS (darwin) and Windows (win32). Declare supported platforms in manifest.json's compatibility section. Best practice: test on both platforms even if you develop on one.
npm install -g @anthropic-ai/mcpb
Build a standard MCP server using the MCP SDK (@modelcontextprotocol/sdk). The server communicates via stdio transport — this is the only transport used in MCPB bundles.
npm install @modelcontextprotocol/sdk
For a Node.js server (server/index.js):
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "my-extension",
version: "1.0.0",
});
server.tool("my_tool", "Description of what this tool does", {}, async () => {
return { content: [{ type: "text", text: "Hello from MCPB!" }] };
});
const transport = new StdioServerTransport();
await server.connect(transport);
For a Python server (server/main.py):
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-extension")
@mcp.tool()
def my_tool() -> str:
"""Description of what this tool does"""
return "Hello from MCPB!"
if __name__ == "__main__":
mcp.run()
Run in your project directory:
mcpb init
The interactive wizard prompts for:
This creates manifest.json. You can also create it manually — see the mcpb-manifest skill for the full spec.
# Pack current directory (outputs <name>.mcpb)
mcpb pack .
# Pack with custom output filename
mcpb pack . my-extension-v1.0.mcpb
mcpb pack automatically:
manifest.json.git, node_modules/.cache, .DS_Store, etc.).mcpb ZIP fileThree installation methods:
.mcpb file.mcpbAll methods open an installation UI where users review details, configure settings, and grant permissions.
my-extension/
├── manifest.json # Required: metadata and configuration
├── server/
│ └── index.js # Main entry point
├── node_modules/ # Bundled dependencies (run npm install first)
├── package.json
└── icon.png # Optional: 512x512 PNG
my-extension/
├── manifest.json
├── server/
│ ├── main.py
│ └── lib/ # Bundled packages (pip install --target server/lib .)
└── icon.png
my-extension/
├── manifest.json # server.type = "uv"
├── pyproject.toml # Dependencies declared here
├── src/
│ └── server.py
└── .mcpbignore # Exclude .venv, __pycache__, etc.
The uv type is experimental (v0.4+). The host manages Python installation — small bundle size (~100 KB vs 5–10 MB for bundled deps).
| Command | Description |
|---|---|
mcpb init [dir] | Interactive manifest creation wizard |
mcpb validate <path> | Validate manifest.json against schema |
mcpb pack <dir> [output] | Pack directory into .mcpb file |
mcpb sign <file> | Sign .mcpb with X.509 certificate |
mcpb verify <file> | Verify signature of signed .mcpb |
mcpb info <file> | Show file size and signature details |
mcpb unsign <file> | Remove signature (dev/testing) |
mcpb validate manifest.json
# or
mcpb validate .
# Self-signed (development/testing)
mcpb sign my-extension.mcpb --self-signed
# Production (with CA certificate)
mcpb sign my-extension.mcpb \
--cert production-cert.pem \
--key production-key.pem \
--intermediate intermediate-ca.pem
# Verify after signing
mcpb verify my-extension.mcpb
Create .mcpbignore to exclude additional files from the bundle:
# .mcpbignore
*.test.js
src/**/*.test.ts
coverage/
docs/
.env*
temp/
# 1. Develop your MCP server
mkdir my-extension && cd my-extension
# 2. Initialize
mcpb init
# 3. Implement server code
# 4. For Node.js: install and bundle dependencies
npm install
# 5. Validate
mcpb validate .
# 6. Pack
mcpb pack .
# 7. Install in Claude Desktop (double-click the .mcpb file)
# 8. Test tools via Claude Desktop
If your server needs user-provided values (API keys, directories, settings), define user_config in manifest.json. Claude Desktop auto-generates a settings UI. Reference values via ${user_config.KEY} in mcp_config.args or mcp_config.env.
See the mcpb-manifest skill for full user_config schema and examples.
To distribute via the Anthropic Connectors Directory, additional requirements apply:
npx claudepluginhub seangsisg/claude-depot --plugin mcp-toolkitPackages MCP servers into standalone .mcpb bundles with Node or Python runtime for distributing local servers that access filesystem, desktop apps, or OS without user toolchain.
Guides integration of Model Context Protocol (MCP) servers into Claude Code plugins via .mcp.json or plugin.json for external service tools, with scope management (local, project, user).
Guides building MCP (Model Context Protocol) servers in Python and TypeScript to give Claude new tools, resources, and prompts.