Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"plugins": ["@typescript-eslint", "import", "prettier", "simple-import-sort"],
"parser": "@typescript-eslint/parser",
"ignorePatterns": ["dist/*", "node_modules/*", "*.js"],
"ignorePatterns": ["dist/**", "node_modules/**", "*.js", "*.d.ts"],
"parserOptions": {
"project": "./tsconfig.json"
},
Expand All @@ -28,7 +28,7 @@
"import/no-extraneous-dependencies": [
"error",
{
"packageDir": "./"
"packageDir": ["./", "./packages/cli", "./packages/schemas"]
}
],
// Imports must not cause cyclical dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ jobs:
run: yarn build:schema
- name: Check for schema changes
run: |
if ! git diff --exit-code schemas/; then
if ! git diff --exit-code packages/schemas/schemas/; then
echo "Error: JSON schemas in schemas/ directory are out of sync!"
echo "Please run 'yarn build:schema' and commit the changes."
echo ""
echo "Changes detected:"
git diff schemas/
git diff packages/schemas/schemas/;
exit 1
fi
echo "✓ All schemas are up to date"
2 changes: 1 addition & 1 deletion CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The MCPB CLI provides tools for building MCP Bundles.
## Installation

```bash
npm install -g @anthropic-ai/mcpb
npm install -g @modelcontextprotocol/mcpb-cli
```

```
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
>
> - `dxt` CLI is now `mcpb`
> - `.dxt` files are now `.mcpb` files
> - `@anthropic-ai/dxt` package will be moved to `@anthropic-ai/mcpb`
> - `@anthropic-ai/dxt` package will be moved to `@modelcontextprotocol/mcpb-cli`

MCP Bundles (`.mcpb`) are zip archives containing a local MCP server and a `manifest.json` that describes the server and its capabilities. The format is spiritually similar to Chrome extensions (`.crx`) or VS Code extensions (`.vsix`), enabling end users to install local MCP servers with a single click.

This repository provides three components: The bundle specification in [MANIFEST.md](MANIFEST.md), a CLI tool for creating bundles (see [CLI.md](CLI.md)), and the code used by Claude for macOS and Windows to load and verify MCPB bundles ([src/index.ts](src/index.ts)).
This repository provides three components: The bundle specification in [MANIFEST.md](MANIFEST.md), a CLI tool for creating bundles (see [CLI.md](CLI.md)), and the code used by Claude for macOS and Windows to load and verify MCPB bundles ([packages/cli/src/index.ts](packages/cli/src/index.ts)).

- For developers of local MCP servers, we aim to make distribution and installation of said servers convenient
- For developers of apps supporting local MCP servers, we aim to make it easy to add support for MCPB bundles
Expand All @@ -24,7 +24,15 @@ At the core, MCPB are simple zip files containing your entire MCP server and a `
To make this process easier, this package offers a CLI that helps you with the creation of both the `manifest.json` and the final `.mcpb` file. To install it, run:

```sh
npm install -g @anthropic-ai/mcpb
npm install -g @modelcontextprotocol/mcpb-cli
```

# For App Developers

To validate MCPB manifests and reuse the schema helpers directly, install the schemas package:

```sh
npm install @modelcontextprotocol/mcpb-schemas
```

1. In a folder containing your local MCP server, run `mcpb init`. This command will guide you through the creation of a `manifest.json`.
Expand Down
9 changes: 6 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
export default {
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testMatch: ["**/test/**/*.test.ts"],
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts"],
collectCoverageFrom: ["packages/**/src/**/*.ts", "!**/*.d.ts"],
moduleFileExtensions: ["ts", "js", "json"],
transform: {
"^.+\\.ts$": [
"ts-jest",
{
tsConfig: "tsconfig.test.json",
tsconfig: "tsconfig.jest.json",
},
],
},
moduleNameMapper: {
"^@modelcontextprotocol/mcpb-schemas$":
"<rootDir>/packages/schemas/src/index.ts",
"^@modelcontextprotocol/mcpb-cli$": "<rootDir>/packages/cli/src/index.ts",
"^(\\.{1,2}/.*)\\.js$": "$1",
},
};
85 changes: 13 additions & 72 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,77 +1,29 @@
{
"name": "@anthropic-ai/mcpb",
"description": "Tools for building MCP Bundles",
"version": "2.1.2",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./browser": {
"types": "./dist/browser.d.ts",
"import": "./dist/browser.js",
"require": "./dist/browser.js"
},
"./node": {
"types": "./dist/node.d.ts",
"import": "./dist/node.js",
"require": "./dist/node.js"
},
"./cli": {
"types": "./dist/cli.d.ts",
"import": "./dist/cli.js",
"require": "./dist/cli.js"
},
"./mcpb-manifest-v0.1.schema.json": "./dist/mcpb-manifest-v0.1.schema.json",
"./mcpb-manifest-v0.2.schema.json": "./dist/mcpb-manifest-v0.2.schema.json",
"./mcpb-manifest-v0.3.schema.json": "./dist/mcpb-manifest-v0.3.schema.json",
"./mcpb-manifest-latest.schema.json": "./dist/mcpb-manifest-latest.schema.json",
"./schemas": {
"types": "./dist/schemas/index.d.ts",
"import": "./dist/schemas/index.js",
"require": "./dist/schemas/index.js"
},
"./schemas/*": {
"types": "./dist/schemas/*.d.ts",
"import": "./dist/schemas/*.js",
"require": "./dist/schemas/*.js"
},
"./schemas-loose": {
"types": "./dist/schemas-loose.d.ts",
"import": "./dist/schemas-loose.js",
"require": "./dist/schemas-loose.js"
}
},
"bin": "dist/cli/cli.js",
"files": [
"dist",
"schemas"
"name": "mcpb-workspace",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "yarn run build:code && yarn run build:schema",
"build:code": "tsc",
"build:schema": "node ./scripts/build-mcpb-schema.js",
"dev": "tsc --watch",
"build": "yarn workspace @modelcontextprotocol/mcpb-schemas run build && yarn workspace @modelcontextprotocol/mcpb-cli run build",
"build:code": "yarn run build:schemas && yarn run build:cli",
"build:cli": "yarn workspace @modelcontextprotocol/mcpb-cli run build",
"build:schemas": "yarn workspace @modelcontextprotocol/mcpb-schemas run build",
"dev": "yarn workspace @modelcontextprotocol/mcpb-cli run dev",
"test": "jest",
"test:watch": "jest --watch",
"prepublishOnly": "npm run build",
"prepublishOnly": "yarn run build",
"fix": "eslint --ext .ts . --fix && prettier -w .",
"lint": "tsc -p ./tsconfig.json && eslint --ext .ts .",
"lint": "tsc -p ./packages/cli/tsconfig.json && tsc -p ./packages/schemas/tsconfig.json && eslint --ext .ts .",
"dev-version": "./scripts/create-dev-version.js"
},
"author": "Anthropic <support@anthropic.com>",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/node": "^22.15.3",
"@types/node-forge": "1.3.11",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript-eslint/eslint-plugin": "^8.55.0",
"@typescript-eslint/parser": "^8.55.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.10.0",
"eslint-import-resolver-typescript": "^3.6.1",
Expand All @@ -83,17 +35,6 @@
"ts-jest": "^29.3.2",
"typescript": "^5.6.3"
},
"dependencies": {
"@inquirer/prompts": "^6.0.1",
"commander": "^13.1.0",
"fflate": "^0.8.2",
"galactus": "^1.0.0",
"ignore": "^7.0.5",
"node-forge": "^1.3.2",
"pretty-bytes": "^5.6.0",
"zod": "^3.25.67",
"zod-to-json-schema": "^3.24.6"
},
"resolutions": {
"@babel/helpers": "7.27.1",
"@babel/parser": "7.27.3"
Expand Down
48 changes: 48 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@modelcontextprotocol/mcpb-cli",
"description": "Tools for building MCP Bundles",
"version": "2.1.2",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./cli": {
"types": "./dist/cli.d.ts",
"import": "./dist/cli.js",
"require": "./dist/cli.js"
},
"./node": {
"types": "./dist/node.d.ts",
"import": "./dist/node.js",
"require": "./dist/node.js"
}
},
"bin": "dist/cli/cli.js",
"files": [
"dist"
],
"scripts": {
"build": "yarn run build:code",
"build:code": "tsc -p tsconfig.json",
"dev": "tsc -p tsconfig.json --watch"
},
"author": "Anthropic <support@anthropic.com>",
"license": "MIT",
"dependencies": {
"@inquirer/prompts": "^6.0.1",
"@modelcontextprotocol/mcpb-schemas": "workspace:*",
"commander": "^13.1.0",
"fflate": "^0.8.2",
"galactus": "^1.0.0",
"ignore": "^7.0.5",
"node-forge": "^1.3.2",
"pretty-bytes": "^5.6.0",
"zod": "^3.25.67"
}
}
5 changes: 0 additions & 5 deletions src/cli.ts → packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
export * from "./cli/init.js";
export * from "./cli/pack.js";

// Include all shared exports
export * from "./schemas/index.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";

// Include node exports since CLI needs them
export * from "./node/files.js";
export * from "./node/sign.js";
Expand Down
File renamed without changes.
9 changes: 4 additions & 5 deletions src/cli/init.ts → packages/cli/src/cli/init.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { confirm, input, select } from "@inquirer/prompts";
import { existsSync, readFileSync, writeFileSync } from "fs";
import { basename, join, resolve } from "path";

import {
DEFAULT_MANIFEST_VERSION,
MANIFEST_SCHEMAS,
} from "../shared/constants.js";
import type { McpbManifestAny } from "../types.js";
type McpbManifestAny,
} from "@modelcontextprotocol/mcpb-schemas";
import { existsSync, readFileSync, writeFileSync } from "fs";
import { basename, join, resolve } from "path";

interface PackageJson {
name?: string;
Expand All @@ -23,7 +22,7 @@
if (existsSync(packageJsonPath)) {
try {
return JSON.parse(readFileSync(packageJsonPath, "utf-8"));
} catch (e) {

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

'e' is defined but never used

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

'e' is defined but never used

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

'e' is defined but never used

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

'e' is defined but never used

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

'e' is defined but never used

Check warning on line 25 in packages/cli/src/cli/init.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

'e' is defined but never used
// Ignore package.json parsing errors
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/cli/pack.ts → packages/cli/src/cli/pack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { confirm } from "@inquirer/prompts";
import {
getManifestVersionFromRawData,
MANIFEST_SCHEMAS,
} from "@modelcontextprotocol/mcpb-schemas";
import { createHash } from "crypto";
import type { Zippable } from "fflate";
import { zipSync } from "fflate";
Expand All @@ -13,9 +17,7 @@ import { basename, join, relative, resolve, sep } from "path";

import { getAllFilesWithCount, readMcpbIgnorePatterns } from "../node/files.js";
import { validateManifest } from "../node/validate.js";
import { MANIFEST_SCHEMAS } from "../shared/constants.js";
import { getLogger } from "../shared/log.js";
import { getManifestVersionFromRawData } from "../shared/manifestVersionResolve.js";
import { initExtension } from "./init.js";

interface PackOptions {
Expand Down
File renamed without changes.
5 changes: 0 additions & 5 deletions src/index.ts → packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@ export * from "./cli/unpack.js";
export * from "./node/files.js";
export * from "./node/sign.js";
export * from "./node/validate.js";
export * from "./schemas/index.js";
export * from "./shared/common.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";
export * from "./types.js";
4 changes: 4 additions & 0 deletions packages/cli/src/node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Node.js-specific exports
export * from "./node/files.js";
export * from "./node/sign.js";
export * from "./node/validate.js";
File renamed without changes.
3 changes: 1 addition & 2 deletions src/node/sign.ts → packages/cli/src/node/sign.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { McpbSignatureInfoSchema } from "@modelcontextprotocol/mcpb-schemas";
import { execFile } from "child_process";
import { readFileSync, writeFileSync } from "fs";
import { mkdtemp, rm, writeFile } from "fs/promises";
Expand All @@ -7,8 +8,6 @@
import { promisify } from "util";
import type { z } from "zod";

import type { McpbSignatureInfoSchema } from "../shared/common.js";

// Signature block markers
const SIGNATURE_HEADER = "MCPB_SIG_V1";
const SIGNATURE_FOOTER = "MCPB_SIG_END";
Expand Down Expand Up @@ -173,7 +172,7 @@
return { status: "unsigned" };
}
}
} catch (error) {

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

'error' is defined but never used

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

'error' is defined but never used

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

'error' is defined but never used

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 175 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

'error' is defined but never used
return { status: "unsigned" };
}

Expand Down Expand Up @@ -319,7 +318,7 @@
"codeSign",
]);
return true;
} catch (error) {

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

'error' is defined but never used

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

'error' is defined but never used

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

'error' is defined but never used

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 321 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

'error' is defined but never used
return false;
}
} else if (process.platform === "win32") {
Expand Down Expand Up @@ -383,11 +382,11 @@
certChainPath,
]);
return true;
} catch (error) {

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

'error' is defined but never used

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

'error' is defined but never used

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

'error' is defined but never used

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 385 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

'error' is defined but never used
return false;
}
}
} catch (error) {

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

'error' is defined but never used

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

'error' is defined but never used

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

'error' is defined but never used

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

'error' is defined but never used

Check warning on line 389 in packages/cli/src/node/sign.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

'error' is defined but never used
return false;
} finally {
if (tempDir) {
Expand Down
12 changes: 6 additions & 6 deletions src/node/validate.ts → packages/cli/src/node/validate.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import {
getManifestVersionFromRawData,
MANIFEST_SCHEMAS,
MANIFEST_SCHEMAS_LOOSE,
} from "@modelcontextprotocol/mcpb-schemas";
import { existsSync, readFileSync, statSync } from "fs";
import * as fs from "fs/promises";
import { DestroyerOfModules } from "galactus";
import * as os from "os";
import { dirname, isAbsolute, join, resolve } from "path";
import prettyBytes from "pretty-bytes";

import { unpackExtension } from "../cli/unpack.js";
import {
MANIFEST_SCHEMAS,
MANIFEST_SCHEMAS_LOOSE,
} from "../shared/constants.js";
import { getManifestVersionFromRawData } from "../shared/manifestVersionResolve.js";

/**
* Check if a buffer contains a valid PNG file signature
Expand Down Expand Up @@ -225,6 +224,7 @@ export async function cleanMcpb(inputPath: string) {
if (existsSync(nodeModulesPath)) {
console.log(" -- node_modules found, deleting development dependencies");

const { DestroyerOfModules } = await import("galactus");
const destroyer = new DestroyerOfModules({
rootDirectory: unpackPath,
});
Expand Down
File renamed without changes.
18 changes: 18 additions & 0 deletions packages/cli/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"types": [
"node"
]
},
"include": [
"src/**/*.ts",
"src/*.ts"
],
"exclude": [
"node_modules",
"dist"
]
}
Loading