重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
build-mcpb by anthropics/claude-plugins-official
npx skills add https://github.com/anthropics/claude-plugins-official --skill build-mcpbMCPB 是一个与其运行时环境打包在一起的本地 MCP 服务器。用户只需安装一个文件;它无需 Node、Python 或其机器上的任何工具链即可运行。这是分发本地 MCP 服务器的官方方式。
当服务器必须在用户机器上运行时,请使用 MCPB——例如读取本地文件、驱动桌面应用程序、与 localhost 服务通信、使用操作系统级 API。如果你的服务器仅调用云 API,那么你几乎肯定需要一个远程 HTTP 服务器(参见 build-mcp-server)。不要为那些可以是一个 URL 的东西支付 MCPB 的打包成本。
my-server.mcpb (zip 压缩包)
├── manifest.json ← 身份标识、入口点、配置模式、兼容性
├── server/ ← 你的 MCP 服务器代码
│ ├── index.js
│ └── node_modules/ ← 捆绑的依赖项(或供应商化)
└── icon.png
主机读取 manifest.json,将 server.mcp_config.command 作为 stdio MCP 服务器启动,并传递消息。从你的代码角度来看,它与本地 stdio 服务器完全相同——唯一的区别在于打包方式。
{
"$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
"manifest_version": "0.4",
"name": "local-files",
"version": "0.1.0",
"description": "读取、搜索和监视本地文件系统上的文件。",
"author": { "name": "你的名字" },
"server": {
"type": "node",
"entry_point": "server/index.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/server/index.js"],
"env": {
"ROOT_DIR": "${user_config.rootDir}"
}
}
},
"user_config": {
"rootDir": {
"type": "directory",
"title": "根目录",
"description": "要暴露的目录。默认为 ~/Documents。",
"default": "${HOME}/Documents",
"required": true
}
},
"compatibility": {
"claude_desktop": ">=1.0.0",
"platforms": ["darwin", "win32", "linux"]
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
server.type — node、python 或 binary。信息性字段;实际的启动命令来自 mcp_config。
server.mcp_config — 启动进程的确切命令/参数/环境变量。使用 ${__dirname} 表示相对于捆绑包的路径,使用 ${user_config.<key>} 来替换安装时的配置。没有自动前缀——你的服务器读取的环境变量名称就是你放在 env 中的名称。
user_config — 在主机 UI 中显示的安装时设置。type: "directory" 会渲染一个原生的文件夹选择器。sensitive: true 会将设置存储在操作系统密钥链中。所有字段请参见 references/manifest-schema.md。
服务器本身是一个标准的 stdio MCP 服务器。工具逻辑中没有任何 MCPB 特有的内容。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readFile, readdir } from "node:fs/promises";
import { join } from "node:path";
import { homedir } from "node:os";
// ROOT_DIR 来自你在清单的 server.mcp_config.env 中设置的内容——没有自动前缀
const ROOT = (process.env.ROOT_DIR ?? join(homedir(), "Documents"));
const server = new McpServer({ name: "local-files", version: "0.1.0" });
server.registerTool(
"list_files",
{
description: "列出配置根目录下某个目录中的文件。",
inputSchema: { path: z.string().default(".") },
annotations: { readOnlyHint: true },
},
async ({ path }) => {
const entries = await readdir(join(ROOT, path), { withFileTypes: true });
const list = entries.map(e => ({ name: e.name, dir: e.isDirectory() }));
return { content: [{ type: "text", text: JSON.stringify(list, null, 2) }] };
},
);
server.registerTool(
"read_file",
{
description: "读取文件内容。路径相对于配置的根目录。",
inputSchema: { path: z.string() },
annotations: { readOnlyHint: true },
},
async ({ path }) => {
const text = await readFile(join(ROOT, path), "utf8");
return { content: [{ type: "text", text }] };
},
);
const transport = new StdioServerTransport();
await server.connect(transport);
沙箱化完全是你自己的责任。 清单级别没有沙箱——进程以完整的用户权限运行。验证路径、拒绝逃逸 ROOT、允许列表中的进程启动。参见 references/local-security.md。
在从配置环境变量硬编码 ROOT 之前,请检查主机是否支持 roots/list——这是获取用户批准目录的规范原生方式。该模式请参见 references/local-security.md。
npm install
npx esbuild src/index.ts --bundle --platform=node --outfile=server/index.js
# 或者:如果原生依赖项难以捆绑,则完整复制 node_modules
npx @anthropic-ai/mcpb pack
mcpb pack 会压缩目录并根据模式验证 manifest.json。
pip install -t server/vendor -r requirements.txt
npx @anthropic-ai/mcpb pack
将依赖项供应商化到一个子目录中,并在你的入口脚本中将其前置到 sys.path。原生扩展(如 numpy 等)必须为每个目标平台构建——如果可能,请避免使用原生依赖项。
与移动应用商店不同,MCPB 不强制执行权限。清单中没有 permissions 块——服务器以完整的用户权限运行。references/local-security.md 是必读内容,而非可选。每个路径都必须验证,每个进程启动都必须经过允许列表,因为在平台层面没有任何东西会阻止你。
如果你来这里期望清单提供文件系统/网络作用域:它不存在。请在工具处理程序中自行构建。
如果你的服务器唯一的工作就是调用云 API,请停止——那是一个穿着 MCPB 外衣的远程服务器。用户从本地运行它得不到任何好处,而你却在无缘无故地承担本地安全负担。
MCPB 服务器可以像远程 MCP 应用一样提供 UI 资源——组件机制与传输方式无关。例如,浏览实际磁盘的本地文件选择器、控制原生应用程序的对话框等。
组件创作在 build-mcp-app 技能中介绍;在这里工作方式相同。唯一的区别是服务器运行的位置。
# 交互式清单创建(首次)
npx @anthropic-ai/mcpb init
# 直接通过 stdio 运行服务器,使用检查器探查它
npx @modelcontextprotocol/inspector node server/index.js
# 根据模式验证清单,然后打包
npx @anthropic-ai/mcpb validate
npx @anthropic-ai/mcpb pack
# 为分发签名
npx @anthropic-ai/mcpb sign dist/local-files.mcpb
# 安装:将 .mcpb 文件拖放到 Claude Desktop 上
在发布前,请在没有你的开发工具链的机器上进行测试。MCPB 中的“在我机器上能运行”故障几乎总是可以追溯到某个实际上没有被打包的依赖项。
references/manifest-schema.md — 完整的 manifest.json 字段参考references/local-security.md — 路径遍历、沙箱化、最小权限每周安装次数
64
代码仓库
GitHub 星标数
14.2K
首次出现
4 天前
安全审计
安装于
claude-code60
opencode54
github-copilot53
gemini-cli53
kimi-cli53
cursor53
MCPB is a local MCP server packaged with its runtime. The user installs one file; it runs without needing Node, Python, or any toolchain on their machine. It's the sanctioned way to distribute local MCP servers.
Use MCPB when the server must run on the user's machine — reading local files, driving a desktop app, talking to localhost services, OS-level APIs. If your server only hits cloud APIs, you almost certainly want a remote HTTP server instead (see build-mcp-server). Don't pay the MCPB packaging tax for something that could be a URL.
my-server.mcpb (zip archive)
├── manifest.json ← identity, entry point, config schema, compatibility
├── server/ ← your MCP server code
│ ├── index.js
│ └── node_modules/ ← bundled dependencies (or vendored)
└── icon.png
The host reads manifest.json, launches server.mcp_config.command as a stdio MCP server, and pipes messages. From your code's perspective it's identical to a local stdio server — the only difference is packaging.
{
"$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
"manifest_version": "0.4",
"name": "local-files",
"version": "0.1.0",
"description": "Read, search, and watch files on the local filesystem.",
"author": { "name": "Your Name" },
"server": {
"type": "node",
"entry_point": "server/index.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/server/index.js"],
"env": {
"ROOT_DIR": "${user_config.rootDir}"
}
}
},
"user_config": {
"rootDir": {
"type": "directory",
"title": "Root directory",
"description": "Directory to expose. Defaults to ~/Documents.",
"default": "${HOME}/Documents",
"required": true
}
},
"compatibility": {
"claude_desktop": ">=1.0.0",
"platforms": ["darwin", "win32", "linux"]
}
}
server.type — node, python, or binary. Informational; the actual launch comes from mcp_config.
server.mcp_config — the literal command/args/env to spawn. Use ${__dirname} for bundle-relative paths and ${user_config.<key>} to substitute install-time config. There's no auto-prefix — the env var names your server reads are exactly what you put in env.
user_config — install-time settings surfaced in the host's UI. type: "directory" renders a native folder picker. sensitive: true stores in OS keychain. See references/manifest-schema.md for all fields.
The server itself is a standard stdio MCP server. Nothing MCPB-specific in the tool logic.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readFile, readdir } from "node:fs/promises";
import { join } from "node:path";
import { homedir } from "node:os";
// ROOT_DIR comes from what you put in manifest's server.mcp_config.env — no auto-prefix
const ROOT = (process.env.ROOT_DIR ?? join(homedir(), "Documents"));
const server = new McpServer({ name: "local-files", version: "0.1.0" });
server.registerTool(
"list_files",
{
description: "List files in a directory under the configured root.",
inputSchema: { path: z.string().default(".") },
annotations: { readOnlyHint: true },
},
async ({ path }) => {
const entries = await readdir(join(ROOT, path), { withFileTypes: true });
const list = entries.map(e => ({ name: e.name, dir: e.isDirectory() }));
return { content: [{ type: "text", text: JSON.stringify(list, null, 2) }] };
},
);
server.registerTool(
"read_file",
{
description: "Read a file's contents. Path is relative to the configured root.",
inputSchema: { path: z.string() },
annotations: { readOnlyHint: true },
},
async ({ path }) => {
const text = await readFile(join(ROOT, path), "utf8");
return { content: [{ type: "text", text }] };
},
);
const transport = new StdioServerTransport();
await server.connect(transport);
Sandboxing is entirely your job. There is no manifest-level sandbox — the process runs with full user privileges. Validate paths, refuse to escape ROOT, allowlist spawns. See references/local-security.md.
Before hardcoding ROOT from a config env var, check if the host supports roots/list — the spec-native way to get user-approved directories. See references/local-security.md for the pattern.
npm install
npx esbuild src/index.ts --bundle --platform=node --outfile=server/index.js
# or: copy node_modules wholesale if native deps resist bundling
npx @anthropic-ai/mcpb pack
mcpb pack zips the directory and validates manifest.json against the schema.
pip install -t server/vendor -r requirements.txt
npx @anthropic-ai/mcpb pack
Vendor dependencies into a subdirectory and prepend it to sys.path in your entry script. Native extensions (numpy, etc.) must be built for each target platform — avoid native deps if you can.
Unlike mobile app stores, MCPB does NOT enforce permissions. The manifest has no permissions block — the server runs with full user privileges. references/local-security.md is mandatory reading, not optional. Every path must be validated, every spawn must be allowlisted, because nothing stops you at the platform level.
If you came here expecting filesystem/network scoping from the manifest: it doesn't exist. Build it yourself in tool handlers.
If your server's only job is hitting a cloud API, stop — that's a remote server wearing an MCPB costume. The user gains nothing from running it locally, and you're taking on local-security burden for no reason.
MCPB servers can serve UI resources exactly like remote MCP apps — the widget mechanism is transport-agnostic. A local file picker that browses the actual disk, a dialog that controls a native app, etc.
Widget authoring is covered in the build-mcp-app skill; it works the same here. The only difference is where the server runs.
# Interactive manifest creation (first time)
npx @anthropic-ai/mcpb init
# Run the server directly over stdio, poke it with the inspector
npx @modelcontextprotocol/inspector node server/index.js
# Validate manifest against schema, then pack
npx @anthropic-ai/mcpb validate
npx @anthropic-ai/mcpb pack
# Sign for distribution
npx @anthropic-ai/mcpb sign dist/local-files.mcpb
# Install: drag the .mcpb file onto Claude Desktop
Test on a machine without your dev toolchain before shipping. "Works on my machine" failures in MCPB almost always trace to a dependency that wasn't actually bundled.
references/manifest-schema.md — full manifest.json field referencereferences/local-security.md — path traversal, sandboxing, least privilegeWeekly Installs
64
Repository
GitHub Stars
14.2K
First Seen
4 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code60
opencode54
github-copilot53
gemini-cli53
kimi-cli53
cursor53
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
52,700 周安装