Skip to content

Commit 57efb58

Browse files
feat: Add support for MCP Bundles (MCPB) in registry (#295)
## Motivation and Context - Add MCPB as a new registry_name option - Add file_hashes field to package model for integrity verification - Implement URL validation restricting MCPB packages to GitHub/GitLab hosts - Require SHA-256 hash for all MCPB packages - Add example MCPB package in documentation - Update schemas and OpenAPI specification See issue #260 ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> ## Breaking Changes N/A, registry has not yet been launched ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [x] I have added or updated documentation as needed --------- Co-authored-by: Adam Jones <[email protected]>
1 parent c3b72ef commit 57efb58

File tree

19 files changed

+2014
-2040
lines changed

19 files changed

+2014
-2040
lines changed

data/seed.json

Lines changed: 1597 additions & 1201 deletions
Large diffs are not rendered by default.

docs/server-json/examples.md

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ _These examples show the PublishRequest format used by the `/v0/publish` API end
2020
},
2121
"packages": [
2222
{
23-
"registry_name": "npm",
24-
"name": "@modelcontextprotocol/server-brave-search",
23+
"registry_type": "npm",
24+
"registry_base_url": "https://registry.npmjs.org",
25+
"identifier": "@modelcontextprotocol/server-brave-search",
2526
"version": "1.0.2",
2627
"environment_variables": [
2728
{
@@ -58,8 +59,9 @@ Suppose your MCP server application requires a `mcp start` CLI arguments to star
5859
},
5960
"packages": [
6061
{
61-
"registry_name": "nuget",
62-
"name": "Knapcode.SampleMcpServer",
62+
"registry_type": "nuget",
63+
"registry_base_url": "https://api.nuget.org",
64+
"identifier": "Knapcode.SampleMcpServer",
6365
"version": "0.4.0-beta",
6466
"package_arguments": [
6567
{
@@ -106,8 +108,9 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp
106108
},
107109
"packages": [
108110
{
109-
"registry_name": "npm",
110-
"name": "@modelcontextprotocol/server-filesystem",
111+
"registry_type": "npm",
112+
"registry_base_url": "https://registry.npmjs.org",
113+
"identifier": "@modelcontextprotocol/server-filesystem",
111114
"version": "1.0.2",
112115
"package_arguments": [
113116
{
@@ -128,8 +131,9 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp
128131
]
129132
},
130133
{
131-
"registry_name": "docker",
132-
"name": "mcp/filesystem",
134+
"registry_type": "docker-hub",
135+
"registry_base_url": "https://docker.io",
136+
"identifier": "mcp/filesystem:1.0.2",
133137
"version": "1.0.2",
134138
"runtime_arguments": [
135139
{
@@ -168,7 +172,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp
168172
}
169173
]
170174
}
171-
]
175+
]
172176
},
173177
"x-publisher": {
174178
"tool": "ci-publisher",
@@ -235,8 +239,9 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp
235239
},
236240
"packages": [
237241
{
238-
"registry_name": "pypi",
239-
"name": "weather-mcp-server",
242+
"registry_type": "pypi",
243+
"registry_base_url": "https://pypi.org",
244+
"identifier": "weather-mcp-server",
240245
"version": "0.5.0",
241246
"runtime_hint": "uvx",
242247
"environment_variables": [
@@ -252,7 +257,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp
252257
"default": "celsius"
253258
}
254259
]
255-
}
260+
}
256261
]
257262
},
258263
"x-publisher": {
@@ -287,8 +292,9 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
287292
},
288293
"packages": [
289294
{
290-
"registry_name": "nuget",
291-
"name": "Knapcode.SampleMcpServer",
295+
"registry_type": "nuget",
296+
"registry_base_url": "https://api.nuget.org",
297+
"identifier": "Knapcode.SampleMcpServer",
292298
"version": "0.5.0",
293299
"runtime_hint": "dnx",
294300
"environment_variables": [
@@ -299,7 +305,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
299305
"is_secret": false
300306
}
301307
]
302-
}
308+
}
303309
]
304310
},
305311
"x-publisher": {
@@ -333,8 +339,9 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
333339
},
334340
"packages": [
335341
{
336-
"registry_name": "docker",
337-
"name": "example/database-manager-mcp",
342+
"registry_type": "docker-hub",
343+
"registry_base_url": "https://docker.io",
344+
"identifier": "example/database-manager-mcp",
338345
"version": "3.1.0",
339346
"runtime_arguments": [
340347
{
@@ -433,20 +440,21 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
433440
},
434441
"packages": [
435442
{
436-
"registry_name": "npm",
437-
"name": "@example/hybrid-mcp-server",
443+
"registry_type": "npm",
444+
"registry_base_url": "https://registry.npmjs.org",
445+
"identifier": "@example/hybrid-mcp-server",
438446
"version": "1.5.0",
439447
"runtime_hint": "npx",
440-
"package_arguments": [
441-
{
442-
"type": "named",
443-
"name": "--mode",
444-
"description": "Operation mode",
445-
"default": "local",
446-
"choices": ["local", "cached", "proxy"]
447-
}
448-
]
449-
}
448+
"package_arguments": [
449+
{
450+
"type": "named",
451+
"name": "--mode",
452+
"description": "Operation mode",
453+
"default": "local",
454+
"choices": ["local", "cached", "proxy"]
455+
}
456+
]
457+
}
450458
],
451459
"remotes": [
452460
{
@@ -490,6 +498,46 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
490498
}
491499
```
492500

501+
## MCP Bundle (MCPB) Package Example
502+
503+
```json
504+
{
505+
"server": {
506+
"name": "io.modelcontextprotocol/text-editor",
507+
"description": "MCP Bundle server for advanced text editing capabilities",
508+
"repository": {
509+
"url": "https://github.com/modelcontextprotocol/text-editor-mcpb",
510+
"source": "github"
511+
},
512+
"version_detail": {
513+
"version": "1.0.2"
514+
},
515+
"packages": [
516+
{
517+
"registry_type": "mcpb",
518+
"registry_base_url": "https://github.com",
519+
"identifier": "https://github.com/modelcontextprotocol/text-editor-mcpb/releases/download/v1.0.2/text-editor.mcpb",
520+
"version": "1.0.2",
521+
"file_sha256": "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce"
522+
}
523+
]
524+
},
525+
"x-publisher": {
526+
"tool": "mcpb-publisher",
527+
"version": "1.0.0",
528+
"build_info": {
529+
"timestamp": "2023-12-02T09:15:00Z",
530+
"bundle_format": "mcpb-v1"
531+
}
532+
}
533+
}
534+
```
535+
536+
This example shows an MCPB (MCP Bundle) package that:
537+
- Is hosted on GitHub Releases (an allowlisted provider)
538+
- Includes a SHA-256 hash for integrity verification
539+
- Can be downloaded and executed directly by MCP clients that support MCPB
540+
493541
## Deprecated Server Example
494542

495543
```json
@@ -508,8 +556,9 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6.
508556
},
509557
"packages": [
510558
{
511-
"registry_name": "npm",
512-
"name": "@legacy/old-weather-server",
559+
"registry_type": "npm",
560+
"registry_base_url": "https://registry.npmjs.org",
561+
"identifier": "@legacy/old-weather-server",
513562
"version": "0.9.5",
514563
"environment_variables": [
515564
{

docs/server-json/registry-schema.json

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,23 @@
1717
"packages": {
1818
"items": {
1919
"properties": {
20-
"registry_name": {
20+
"registry_type": {
2121
"enum": [
2222
"npm",
23-
"pypi",
24-
"docker",
25-
"nuget"
23+
"pypi",
24+
"docker-hub",
25+
"nuget",
26+
"mcpb"
27+
]
28+
},
29+
"registry_base_url": {
30+
"enum": [
31+
"https://registry.npmjs.org",
32+
"https://pypi.org",
33+
"https://docker.io",
34+
"https://api.nuget.org",
35+
"https://github.com",
36+
"https://gitlab.com"
2637
]
2738
},
2839
"runtime_hint": {

docs/server-json/server.schema.json

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,34 @@
8080
},
8181
"Package": {
8282
"type": "object",
83-
"required": [
84-
"registry_name",
85-
"name",
86-
"version"
87-
],
8883
"properties": {
89-
"registry_name": {
84+
"registry_type": {
9085
"type": "string",
91-
"description": "Package registry type",
92-
"example": "npm"
86+
"description": "Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'docker-hub', 'nuget', 'mcpb')",
87+
"examples": ["npm", "pypi", "docker-hub", "nuget", "mcpb"]
9388
},
94-
"name": {
89+
"registry_base_url": {
9590
"type": "string",
96-
"description": "Package name in the registry",
97-
"example": "io.modelcontextprotocol/filesystem"
91+
"format": "uri",
92+
"description": "Base URL of the package registry",
93+
"examples": ["https://registry.npmjs.org", "https://pypi.org", "https://docker.io", "https://api.nuget.org", "https://github.com", "https://gitlab.com"]
94+
},
95+
"identifier": {
96+
"type": "string",
97+
"description": "Package identifier - either a package name (for registries) or URL (for direct downloads)",
98+
"examples": ["@modelcontextprotocol/server-brave-search", "https://github.com/example/releases/download/v1.0.0/package.mcpb"]
9899
},
99100
"version": {
100101
"type": "string",
101102
"description": "Package version",
102103
"example": "1.0.2",
103104
"minLength": 1
104105
},
106+
"file_sha256": {
107+
"type": "string",
108+
"description": "SHA-256 hash of the package file for integrity verification.",
109+
"example": "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce"
110+
},
105111
"runtime_hint": {
106112
"type": "string",
107113
"description": "A hint to help clients determine the appropriate runtime for the package. This field should be provided when `runtime_arguments` are present.",

docs/server-registry-api/openapi.yaml

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ paths:
9595
version_detail:
9696
version: "1.0.2"
9797
packages:
98-
- registry_name: "npm"
99-
name: "@modelcontextprotocol/server-filesystem"
98+
- registry_type: "npm"
99+
registry_base_url: "https://registry.npmjs.org"
100+
identifier: "@modelcontextprotocol/server-filesystem"
100101
version: "1.0.2"
101102
x-publisher:
102103
tool: "publisher-cli"
@@ -117,8 +118,9 @@ paths:
117118
version_detail:
118119
version: "1.0.0"
119120
packages:
120-
- registry_name: "npm"
121-
name: "@example/mcp-demo-server"
121+
- registry_type: "npm"
122+
registry_base_url: "https://registry.npmjs.org"
123+
identifier: "@example/mcp-demo-server"
122124
version: "1.0.0"
123125
x-publisher:
124126
contact_email: "[email protected]"
@@ -272,23 +274,41 @@ components:
272274

273275
Package:
274276
type: object
275-
required:
276-
- registry_name
277-
- name
278-
- version
279277
properties:
280-
registry_name:
278+
registry_type:
281279
type: string
282-
description: Package registry type
283-
example: "npm"
284-
name:
280+
description: Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'docker-hub', 'nuget', 'mcpb')
281+
examples:
282+
- "npm"
283+
- "pypi"
284+
- "docker-hub"
285+
- "nuget"
286+
- "mcpb"
287+
registry_base_url:
285288
type: string
286-
description: Package name in the registry
287-
example: "io.modelcontextprotocol/filesystem"
289+
format: uri
290+
description: Base URL of the package registry
291+
examples:
292+
- "https://registry.npmjs.org"
293+
- "https://pypi.org"
294+
- "https://docker.io"
295+
- "https://api.nuget.org"
296+
- "https://github.com"
297+
- "https://gitlab.com"
298+
identifier:
299+
type: string
300+
description: Package identifier - either a package name (for registries) or URL (for direct downloads)
301+
examples:
302+
- "@modelcontextprotocol/server-brave-search"
303+
- "https://github.com/example/releases/download/v1.0.0/package.mcpb"
288304
version:
289305
type: string
290306
description: Package version
291307
example: "1.0.2"
308+
file_sha256:
309+
type: string
310+
description: SHA-256 hash of the package file for integrity verification.
311+
example: "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce"
292312
runtime_hint:
293313
type: string
294314
description: A hint to help clients determine the appropriate runtime for the package. This field should be provided when `runtime_arguments` are present.

0 commit comments

Comments
 (0)