Allow for vendor extensions on servers (#298)
<!-- Provide a brief summary of your changes -->
This PR serves as a placeholder and brings together all of the changes
related to supporting vendor extensions passed through the API. The idea
is to have a single place to track and review the work as it comes
together (even if it’s still a bit of a work in progress).
**The changes in this PR cover:**
* Updates on the data model
* Updates on both databases (in-memory and postgresql), added a new
table to PSQL for tracking the extensions leaving the server table only
for the clean server.json properties
* Updates the seed.json file (thus the big line change)
* Adds a seed-migrate tool to help migrating an existing seed file to
the new format
* Updates the seed import mechanism to support this
* Updates the existing tests - unit, integration and validation tests
* Adds the publish handler to the OpenAPI spec (it was missing)
* Fixes linting errors
* Updates on the API side on (publish, list, get) to support the new
format of `ServerResponse` -
```
{
"server": {},
"x-io.modelcontextprotocol.registry": {}, /*not available for publish since this gets populated by the registry*/
"x-publisher": {}
}
```
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Motivated by the discussions in:
https://github.com/modelcontextprotocol/registry/discussions/284
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Locally and by running all of the tests
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
Yes, it changes both the API and the format of the seed file
## 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)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
---
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
Co-authored-by: adam jones <domdomegg+git@gmail.com>
This commit is contained in:
parent
ebaf4c9c99
commit
8d7e471fd3
3 changed files with 19980 additions and 15589 deletions
38
tools/migrate-seed/testdata/README.md
vendored
Normal file
38
tools/migrate-seed/testdata/README.md
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Migration Test Data
|
||||
|
||||
This directory contains golden files for testing the seed migration CLI tool.
|
||||
|
||||
## Files
|
||||
|
||||
- **`legacy-input.json`** - Sample input file in the legacy seed format (flat structure with registry metadata mixed in)
|
||||
- **`expected-output.json`** - Expected output after migration to extension wrapper format
|
||||
|
||||
## Usage
|
||||
|
||||
The golden file test (`TestMigrationCLI_GoldenFile`) runs the migration tool on `legacy-input.json` and compares the output against `expected-output.json` to ensure the migration produces the correct result.
|
||||
|
||||
## Updating Golden Files
|
||||
|
||||
If you make changes to the migration logic, you may need to update the expected output:
|
||||
|
||||
1. Review the changes to ensure they're correct
|
||||
2. Regenerate the expected output:
|
||||
```bash
|
||||
cd cmd/migrate-seed
|
||||
../../bin/migrate-seed testdata/legacy-input.json testdata/expected-output.json
|
||||
```
|
||||
3. Verify the new output is correct by reviewing the diff
|
||||
4. Run the tests to ensure they pass
|
||||
|
||||
## Format Details
|
||||
|
||||
### Legacy Input Format
|
||||
- Flat JSON array of server objects
|
||||
- Registry metadata fields (`id`, `is_latest`, `release_date`) mixed directly in server objects
|
||||
- Version detail contains registry metadata
|
||||
|
||||
### Expected Output Format
|
||||
- Extension wrapper format
|
||||
- Each server wrapped in `"server"` field
|
||||
- Registry metadata in `"x-io.modelcontextprotocol.registry"` extension
|
||||
- No `"x-publisher"` extensions for seed data
|
||||
77
tools/migrate-seed/testdata/expected-output.json
vendored
Normal file
77
tools/migrate-seed/testdata/expected-output.json
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
[
|
||||
{
|
||||
"server": {
|
||||
"name": "io.github.21st-dev/magic-mcp",
|
||||
"description": "It's like v0 but in your Cursor/WindSurf/Cline. 21st dev Magic MCP server for working with your frontend like Magic",
|
||||
"status": "active",
|
||||
"repository": {
|
||||
"url": "https://github.com/21st-dev/magic-mcp",
|
||||
"source": "github",
|
||||
"id": "935450522"
|
||||
},
|
||||
"version_detail": {
|
||||
"version": "0.0.1-seed"
|
||||
},
|
||||
"packages": [
|
||||
{
|
||||
"registry_name": "npm",
|
||||
"name": "@21st-dev/magic",
|
||||
"version": "0.0.46",
|
||||
"environment_variables": [
|
||||
{
|
||||
"description": "${input:apiKey}",
|
||||
"name": "API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"x-io.modelcontextprotocol.registry": {
|
||||
"id": "4e9cf4cf-71f6-4aca-bae8-2d10a29ca2e0",
|
||||
"is_latest": true,
|
||||
"published_at": "0001-01-01T00:00:00Z",
|
||||
"release_date": "2025-05-16T18:56:49Z",
|
||||
"updated_at": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"server": {
|
||||
"name": "io.github.adfin-engineering/mcp-server-adfin",
|
||||
"description": "A Model Context Protocol Server for connecting with Adfin APIs",
|
||||
"status": "active",
|
||||
"repository": {
|
||||
"url": "https://github.com/Adfin-Engineering/mcp-server-adfin",
|
||||
"source": "github",
|
||||
"id": "951338147"
|
||||
},
|
||||
"version_detail": {
|
||||
"version": "0.0.1-seed"
|
||||
},
|
||||
"packages": [
|
||||
{
|
||||
"registry_name": "pypi",
|
||||
"name": "adfinmcp",
|
||||
"version": "0.1.0",
|
||||
"package_arguments": [
|
||||
{
|
||||
"description": "Path to the configuration file",
|
||||
"is_required": true,
|
||||
"format": "string",
|
||||
"value": "/config/adfin.json",
|
||||
"default": "/config/adfin.json",
|
||||
"type": "positional",
|
||||
"value_hint": "/path/to/config.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"x-io.modelcontextprotocol.registry": {
|
||||
"id": "d3669201-252f-403c-944b-c3ec0845782b",
|
||||
"is_latest": true,
|
||||
"published_at": "0001-01-01T00:00:00Z",
|
||||
"release_date": "2025-05-16T18:56:52Z",
|
||||
"updated_at": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
63
tools/migrate-seed/testdata/legacy-input.json
vendored
Normal file
63
tools/migrate-seed/testdata/legacy-input.json
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
[
|
||||
{
|
||||
"id": "4e9cf4cf-71f6-4aca-bae8-2d10a29ca2e0",
|
||||
"name": "io.github.21st-dev/magic-mcp",
|
||||
"description": "It's like v0 but in your Cursor/WindSurf/Cline. 21st dev Magic MCP server for working with your frontend like Magic",
|
||||
"repository": {
|
||||
"url": "https://github.com/21st-dev/magic-mcp",
|
||||
"source": "github",
|
||||
"id": "935450522"
|
||||
},
|
||||
"version_detail": {
|
||||
"version": "0.0.1-seed",
|
||||
"release_date": "2025-05-16T18:56:49Z",
|
||||
"is_latest": true
|
||||
},
|
||||
"packages": [
|
||||
{
|
||||
"registry_name": "npm",
|
||||
"name": "@21st-dev/magic",
|
||||
"version": "0.0.46",
|
||||
"environment_variables": [
|
||||
{
|
||||
"description": "${input:apiKey}",
|
||||
"name": "API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "d3669201-252f-403c-944b-c3ec0845782b",
|
||||
"name": "io.github.adfin-engineering/mcp-server-adfin",
|
||||
"description": "A Model Context Protocol Server for connecting with Adfin APIs",
|
||||
"repository": {
|
||||
"url": "https://github.com/Adfin-Engineering/mcp-server-adfin",
|
||||
"source": "github",
|
||||
"id": "951338147"
|
||||
},
|
||||
"version_detail": {
|
||||
"version": "0.0.1-seed",
|
||||
"release_date": "2025-05-16T18:56:52Z",
|
||||
"is_latest": true
|
||||
},
|
||||
"packages": [
|
||||
{
|
||||
"registry_name": "pypi",
|
||||
"name": "adfinmcp",
|
||||
"version": "0.1.0",
|
||||
"package_arguments": [
|
||||
{
|
||||
"description": "Path to the configuration file",
|
||||
"is_required": true,
|
||||
"format": "string",
|
||||
"value": "/config/adfin.json",
|
||||
"default": "/config/adfin.json",
|
||||
"type": "positional",
|
||||
"value_hint": "/path/to/config.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Loading…
Reference in a new issue