Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ _out/
dist
self-signed-cert.pem
self-signed-key.pem
*.dxt
*.mcpb
invalid-json.json
**/server/lib/**
134 changes: 67 additions & 67 deletions CLI.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
# DXT CLI Documentation
# MCPB CLI Documentation

The DXT CLI provides tools for building Desktop Extensions.
The MCPB CLI provides tools for building MCP Bundles.

## Installation

```bash
npm install -g @anthropic-ai/dxt
npm install -g @anthropic-ai/mcpb
```

```
Usage: dxt [options] [command]
Usage: mcpb [options] [command]

Tools for building Desktop Extensions
Tools for building MCP Bundles

Options:
-V, --version output the version number
-h, --help display help for command

Commands:
init [directory] Create a new DXT extension manifest
validate <manifest> Validate a DXT manifest file
pack <directory> [output] Pack a directory into a DXT extension
sign [options] <dxt-file> Sign a DXT extension file
verify <dxt-file> Verify the signature of a DXT extension file
info <dxt-file> Display information about a DXT extension file
unsign <dxt-file> Remove signature from a DXT extension file
init [directory] Create a new MCPB extension manifest
validate <manifest> Validate a MCPB manifest file
pack <directory> [output] Pack a directory into a MCPB extension
sign [options] <mcpb-file> Sign a MCPB extension file
verify <mcpb-file> Verify the signature of a MCPB extension file
info <mcpb-file> Display information about a MCPB extension file
unsign <mcpb-file> Remove signature from a MCPB extension file
help [command] display help for command
```

## Commands

### `dxt init [directory]`
### `mcpb init [directory]`

Creates a new DXT extension manifest interactively.
Creates a new MCPB extension manifest interactively.

```bash
# Initialize in current directory
dxt init
mcpb init

# Initialize in a specific directory
dxt init my-extension/
mcpb init my-extension/
```

The command will prompt you for:
Expand All @@ -58,53 +58,53 @@ The command will prompt you for:

After creating the manifest, it provides helpful next steps based on your server type.

### `dxt validate <path>`
### `mcpb validate <path>`

Validates a DXT manifest file against the schema. You can provide either a direct path to a manifest.json file or a directory containing one.
Validates a MCPB manifest file against the schema. You can provide either a direct path to a manifest.json file or a directory containing one.

```bash
# Validate specific manifest file
dxt validate manifest.json
mcpb validate manifest.json

# Validate manifest in directory
dxt validate ./my-extension
dxt validate .
mcpb validate ./my-extension
mcpb validate .
```

### `dxt pack <directory> [output]`
### `mcpb pack <directory> [output]`

Packs a directory into a DXT extension file.
Packs a directory into a MCPB extension file.

```bash
# Pack current directory into extension.dxt
dxt pack .
# Pack current directory into extension.mcpb
mcpb pack .

# Pack with custom output filename
dxt pack my-extension/ my-extension-v1.0.dxt
mcpb pack my-extension/ my-extension-v1.0.mcpb
```

The command automatically:

- Validates the manifest.json
- Excludes common development files (.git, node_modules/.cache, .DS_Store, etc.)
- Creates a compressed .dxt file (ZIP with maximum compression)
- Creates a compressed .mcpb file (ZIP with maximum compression)

### `dxt sign <dxt-file>`
### `mcpb sign <mcpb-file>`

Signs a DXT extension file with a certificate.
Signs a MCPB extension file with a certificate.

```bash
# Sign with default certificate paths
dxt sign my-extension.dxt
mcpb sign my-extension.mcpb

# Sign with custom certificate and key
dxt sign my-extension.dxt --cert /path/to/cert.pem --key /path/to/key.pem
mcpb sign my-extension.mcpb --cert /path/to/cert.pem --key /path/to/key.pem

# Sign with intermediate certificates
dxt sign my-extension.dxt --cert cert.pem --key key.pem --intermediate intermediate1.pem intermediate2.pem
mcpb sign my-extension.mcpb --cert cert.pem --key key.pem --intermediate intermediate1.pem intermediate2.pem

# Create and use a self-signed certificate
dxt sign my-extension.dxt --self-signed
mcpb sign my-extension.mcpb --self-signed
```

Options:
Expand All @@ -114,12 +114,12 @@ Options:
- `--intermediate, -i`: Paths to intermediate certificate files
- `--self-signed`: Create a self-signed certificate if none exists

### `dxt verify <dxt-file>`
### `mcpb verify <mcpb-file>`

Verifies the signature of a signed DXT extension file.
Verifies the signature of a signed MCPB extension file.

```bash
dxt verify my-extension.dxt
mcpb verify my-extension.mcpb
```

Output includes:
Expand All @@ -130,12 +130,12 @@ Output includes:
- Certificate fingerprint
- Warning if self-signed

### `dxt info <dxt-file>`
### `mcpb info <mcpb-file>`

Displays information about a DXT extension file.
Displays information about a MCPB extension file.

```bash
dxt info my-extension.dxt
mcpb info my-extension.mcpb
```

Shows:
Expand All @@ -144,12 +144,12 @@ Shows:
- Signature status
- Certificate details (if signed)

### `dxt unsign <dxt-file>`
### `mcpb unsign <mcpb-file>`

Removes the signature from a DXT extension file (for development/testing).
Removes the signature from a MCPB extension file (for development/testing).

```bash
dxt unsign my-extension.dxt
mcpb unsign my-extension.mcpb
```

## Certificate Requirements
Expand All @@ -176,18 +176,18 @@ mkdir my-awesome-extension
cd my-awesome-extension

# 2. Initialize the extension
dxt init
mcpb init

# 3. Follow the prompts to configure your extension
# The tool will create a manifest.json with all necessary fields

# 4. Create your server implementation based on the entry point you specified

# 5. Pack the extension
dxt pack .
mcpb pack .

# 6. (Optional) Sign the extension
dxt sign my-awesome-extension.dxt --self-signed
mcpb sign my-awesome-extension.mcpb --self-signed
```

### Development Workflow
Expand All @@ -197,44 +197,44 @@ dxt sign my-awesome-extension.dxt --self-signed
mkdir my-extension
cd my-extension

# 2. Initialize with dxt init or create manifest.json manually
dxt init
# 2. Initialize with mcpb init or create manifest.json manually
mcpb init

# 3. Implement your server
# For Node.js: create server/index.js
# For Python: create server/main.py
# For Binary: add your executable

# 4. Validate manifest
dxt validate manifest.json
mcpb validate manifest.json

# 5. Pack extension
dxt pack . my-extension.dxt
mcpb pack . my-extension.mcpb

# 6. (Optional) Sign for testing
dxt sign my-extension.dxt --self-signed
mcpb sign my-extension.mcpb --self-signed

# 7. Verify signature
dxt verify my-extension.dxt
mcpb verify my-extension.mcpb

# 8. Check extension info
dxt info my-extension.dxt
mcpb info my-extension.mcpb
```

### Production Workflow

```bash
# 1. Pack your extension
dxt pack my-extension/
mcpb pack my-extension/

# 2. Sign with production certificate
dxt sign my-extension.dxt \
mcpb sign my-extension.mcpb \
--cert production-cert.pem \
--key production-key.pem \
--intermediate intermediate-ca.pem root-ca.pem

# 3. Verify before distribution
dxt verify my-extension.dxt
mcpb verify my-extension.mcpb
```

## Excluded Files
Expand All @@ -250,12 +250,12 @@ When packing an extension, the following files/patterns are automatically exclud
- `.env.local`, `.env.*.local`
- `package-lock.json`, `yarn.lock`

### Custom Exclusions with .dxtignore
### Custom Exclusions with .mcpbignore

You can create a `.dxtignore` file in your extension directory to specify additional files and patterns to exclude during packing. This works similar to `.npmignore` or `.gitignore`:
You can create a `.mcpbignore` file in your extension directory to specify additional files and patterns to exclude during packing. This works similar to `.npmignore` or `.gitignore`:

```
# .dxtignore example
# .mcpbignore example
# Comments start with #
*.test.js
src/**/*.test.ts
Expand All @@ -266,38 +266,38 @@ temp/
docs/
```

The `.dxtignore` file supports:
The `.mcpbignore` file supports:

- **Exact matches**: `filename.txt`
- **Simple globs**: `*.log`, `temp/*`
- **Directory paths**: `docs/`, `coverage/`
- **Comments**: Lines starting with `#` are ignored
- **Empty lines**: Blank lines are ignored

When a `.dxtignore` file is found, the CLI will display the number of additional patterns being applied. These patterns are combined with the default exclusion list.
When a `.mcpbignore` file is found, the CLI will display the number of additional patterns being applied. These patterns are combined with the default exclusion list.

## Technical Details

### Signature Format

DXT uses PKCS#7 (Cryptographic Message Syntax) for digital signatures:
MCPB uses PKCS#7 (Cryptographic Message Syntax) for digital signatures:

- Signatures are stored in DER-encoded PKCS#7 SignedData format
- The signature is appended to the DXT file with markers (`DXT_SIG_V1` and `DXT_SIG_END`)
- The entire DXT content (excluding the signature block) is signed
- The signature is appended to the MCPB file with markers (`MCPB_SIG_V1` and `MCPB_SIG_END`)
- The entire MCPB content (excluding the signature block) is signed
- Detached signature format - the original ZIP content remains unmodified

### Signature Structure

```
[Original DXT ZIP content]
DXT_SIG_V1
[Original MCPB ZIP content]
MCPB_SIG_V1
[Base64-encoded PKCS#7 signature]
DXT_SIG_END
MCPB_SIG_END
```

This approach allows:

- Backward compatibility (unsigned DXT files are valid ZIP files)
- Backward compatibility (unsigned MCPB files are valid ZIP files)
- Easy signature verification and removal
- Support for certificate chains with intermediate certificates
14 changes: 7 additions & 7 deletions MANIFEST.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DXT Manifest.json Spec
# MCPB Manifest.json Spec

Current version: `0.1`
Last updated: 2025-06-17
Expand All @@ -11,7 +11,7 @@ A basic `manifest.json` with just the required fields looks like this:

```json
{
"dxt_version": "0.1", // DXT spec version this manifest conforms to
"mcpb_version": "0.1", // MCPB spec version this manifest conforms to
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only breaking schema change

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly to avoid another breaking change, you could do the same thing we're doing in modelcontextprotocol/registry#308

tldr: instead of mcpb_version, use $schema pointing at a versioned JSON schema. This:

  • makes it more obvious what exactly the file is for
  • gives people nice IDE typehinting
  • provides very clear versioning support
  • is standards compliant

I think given we're moving this all to the MCP org anyway, happy for you to host on https://github.com/modelcontextprotocol/static (e.g. raise a PR like modelcontextprotocol/static#1). You can also just use a URL like https://static.modelcontextprotocol.io/schemas/2025-07-09/mcpb.schema.json then we can add the actual file later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @domdomegg for the suggestion! That makes the schema validation workflow a lot clearer, actually. Opened a PR here: modelcontextprotocol/static#2.

I'll update this PR to reflect the updated schema before merging

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh also - I'll call out that diff is slightly outdated, it's been updated mpcb_version -> manifest_version

"name": "my-extension", // Machine-readable name (used for CLI, APIs)
"version": "1.0.0", // Semantic version of your extension
"description": "A simple MCP extension", // Brief description of what the extension does
Expand All @@ -37,7 +37,7 @@ A basic `manifest.json` with just the required fields looks like this:

```json
{
"dxt_version": "0.1",
"mcpb_version": "0.1",
"name": "my-extension",
"version": "1.0.0",
"description": "A simple MCP extension",
Expand Down Expand Up @@ -71,7 +71,7 @@ A full `manifest.json` with most of the optional fields looks like this:

```json
{
"dxt_version": "0.1",
"mcpb_version": "0.1",
"name": "My MCP Extension",
"display_name": "My Awesome MCP Extension",
"version": "1.0.0",
Expand Down Expand Up @@ -162,7 +162,7 @@ A full `manifest.json` with most of the optional fields looks like this:

### Required Fields

- **dxt_version**: Specification version this extension conforms to
- **mcpb_version**: Specification version this extension conforms to
- **name**: Machine-readable name (used for CLI, APIs)
- **version**: Semantic version (semver)
- **description**: Brief description
Expand Down Expand Up @@ -190,7 +190,7 @@ A full `manifest.json` with most of the optional fields looks like this:

## Compatibility

The `compatibility` object specifies all requirements for running the extension. All fields, including the `compatibility` field itself, are optional. If you specify nothing, clients implementing DXT are encouraged to run the extension on any system.
The `compatibility` object specifies all requirements for running the extension. All fields, including the `compatibility` field itself, are optional. If you specify nothing, clients implementing MCPB are encouraged to run the extension on any system.

```json
{
Expand Down Expand Up @@ -291,7 +291,7 @@ The `server` object defines how to run the MCP server:

1. **Python**: `server.type = "python"`
- Requires `entry_point` to Python file
- All dependencies must be bundled in the DXT
- All dependencies must be bundled in the MCPB
- Can use `server/lib` for packages or `server/venv` for full virtual environment
- Python runtime version specified in `compatibility.runtimes.python`

Expand Down
Loading
Loading