Co-authored with Claude Code, but I've closely reviewed/modified/vetted
all changes; ready for final review.
## Summary
This PR adds LocalTransport and RemoteTransport separation with URL
template variable support for remote servers, enabling e.g. multi-tenant
deployments with configurable endpoints.
**Key additions:**
- LocalTransport (for Packages) and RemoteTransport (for Remotes)
- URL template variables for remote transports (e.g., `{tenant_id}` in
URLs)
- Pattern validation ensuring URLs are URL-like while allowing templates
- Full test coverage via Go validator tests and documentation examples
## ⚠️ server.json Update
This PR updates the `server.json` schema. A new schema version will be
cut after this lands.
## Problem
The current schema describes URL templating with `{curly_braces}` for
transports but provides no mechanism for Remote contexts to define what
those variables should resolve to, making the feature unusable for
remote servers.
Referenced issue: #394
- Users need multi-tenant remote servers with different endpoints per
deployment
- Each tenant/region has its own URL (e.g., `us-cell1.example.com`,
`emea-cell1.example.com`)
- Current schema doesn't support parameterized remote URLs
## Solution
### Schema Architecture
**LocalTransport** (for Package context):
```typescript
LocalTransport = StdioTransport | StreamableHttpTransport | SseTransport
```
- Used in Package context (non-breaking rename of existing behavior)
- Variables in `{curly_braces}` reference parent Package
arguments/environment variables
- Supports all three transport types including stdio
**RemoteTransport** (for Remote context):
```typescript
RemoteTransport = (StreamableHttpTransport | SseTransport) + { variables: object }
```
- Extends StreamableHttp/Sse via `allOf` composition - no duplication!
- Adds `variables` object for URL templating
- Only supports streamable-http and sse (stdio not valid for remotes)
### Key Changes
**1. Schema Updates** (`openapi.yaml`, `server.schema.json`):
- Added `LocalTransport` union type for Package context
- Added `RemoteTransport` with `allOf` composition extending base
transports
- Updated Package to reference `LocalTransport`
- Updated remotes to reference `RemoteTransport`
- Added URL pattern validation: `^https?://[^\\s]+$` to both
StreamableHttp and SSE
- Removed `format: uri` from SSE (was blocking template variables)
**2. Go Types** (`pkg/model/types.go`):
- Base `Transport` struct unchanged for Package context
- `RemoteTransport` struct for remotes with `Variables` field
- Both work with existing validation infrastructure
**3. Validators** (`internal/validators/`):
- `validateRemoteTransport()` validates Remote-specific constraints
- `collectRemoteTransportVariables()` extracts available variables
- `IsValidTemplatedURL()` validates template variables reference defined
variables
- `IsValidRemoteURL()` handles template variable substitution before
localhost check
- 6 new test cases for remote transport variable validation
**4. Documentation Examples** (`generic-server-json.md`):
- Remote Server with URL Templating (StreamableHttp with `{tenant_id}`)
- SSE Remote with URL Templating (SSE with `{tenant_id}`)
- Local Server with URL Templating (Package with `{port}`)
- All examples validate via existing `validate-examples` tool
## Example: Remote Transport with Variables
```json
{
"remotes": [
{
"type": "streamable-http",
"url": "https://api.example.com/mcp/{tenant_id}/{region}",
"variables": {
"tenant_id": {
"description": "Tenant identifier",
"isRequired": true,
"choices": ["us-cell1", "emea-cell1", "apac-cell1"]
},
"region": {
"description": "Deployment region",
"isRequired": true
}
}
}
]
}
```
Clients configure the variables, and `{tenant_id}` and `{region}` get
replaced to connect to tenant-specific endpoints like
`https://api.example.com/mcp/us-cell1/east`.
## Architecture Details
**Context-based variable resolution:**
- **Package + LocalTransport**: `{port}` references `--port` argument or
`PORT` env var from parent Package
- **Remote + RemoteTransport**: `{tenant_id}` references
`variables.tenant_id` defined in the transport itself
- **Code reuse**: StreamableHttp/Sse definitions shared via `allOf`, not
duplicated
- **Validation**: Template variables validated against available
variables for each context
---
## Follow-on Work
Follow-on work will be done to adopt the feedback in
https://github.com/modelcontextprotocol/registry/pull/570#issuecomment-3367417636
regarding variable naming/prioritzation/scoping conventions, but should
not have any impact on the shape being introduced here (just
validations).
---------
Co-authored-by: yuna0x0 <yuna@yuna0x0.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Connor Peet <connor@peet.io>
Prepared by Claude Code, reviewed by me.
## Summary
- Update all API endpoint paths from `/v0/` to `/v0.1/` in the OpenAPI
spec
- Bump OpenAPI spec version from `2025-10-17` to `2025-12-01` (in `$id`
and `info.version`)
## Rationale
This ensures sub-registries implementing the spec are adhering to the
stable v0.1 version rather than the unstable v0. The API freeze (v0.1)
provides stability guarantees that sub-registries need.
## Additional cleanup
### Make `_meta` optional in `ServerResponse`
The `_meta` field (and its `io.modelcontextprotocol.registry/official`
extension) were never intended to be required parts of the spec.
Sub-registries may not use these registry-specific metadata fields, so
they should be optional.
### Move extensions docs to use /v0.1/ instead of /v0/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
This resolves
https://github.com/modelcontextprotocol/registry/issues/738. There are
two issues with the NuGet.org integration today:
1. Change the `registryBaseUrl` for NuGet to
`https://api.nuget.org/v3/index.json`. `https://api.nuget.org` is not
the entry point for our service and is not specific enough.
`https://api.nuget.org/v3/index.json` is the value that users put into
their tooling to connect to our public registry (it is installed by
default in .NET client tooling).
2. Use the service index API to get the URL pattern for package READMEs.
- This URL is not guaranteed to be stable. The service index URL
(`registryBaseUrl`) is, however.
Additionally, I polished up the error messages so various error modes
are clearer. When packages are published to NuGet.org, they take 2-5
minutes to become available due to validations we run.
Some possible states that are now handled and described more helpfully
are:
- Version exists, but the package has no README
- The ID exists, but the version does not
- The ID does not exist at all
There are only 3 authors (me, another MSFT person, and a community
member) explicitly setting the old value. The DB migration will fix the
issue. A future publish will fail with the validation error but the
error message is clear.
`registry type and base URL do not match: 'https://api.nuget.org' is not
valid for registry type 'nuget'. Expected:
https://api.nuget.org/v3/index.json`
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
- Unit tests, new and existing
- Manual test locally
- Set old data in the DB, `docker compose up`, confirm the migration
updates the specific package
## Breaking Changes
Yes, but minimal impact expected, unless there is a dependency on the
specific `https://api.nuget.org` value downstream. I am not aware of any
such dependency, and the new value is more proper and specific.
## 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)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
For more information about the NuGet API see:
https://learn.microsoft.com/en-us/nuget/api/overview#service-index (I
wrote most of the docs).
Introduces a standardized way for registries to provide experimental or
community-driven features without committing them to the core API
specification.
## Summary
- Extensions live under `/v0/x/<namespace>/<extension>` URL structure
- Simple conventions: REST, JSON responses, cursor pagination, optional
auth
- Composable design building on core APIs where possible
This enables experimentation with features like search (#389) and MCP
server integration (#24) while keeping the core API minimal and stable.
Fixes#776
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The `--file=PATH` pattern does not work. The path is an optional,
positional argument not a named option.
The `--dry-run` option is not supported.
Look at the implementation:
d092dd6390/cmd/publisher/commands/publish.go (L19)
## How Has This Been Tested?
Try these options yourself, they are ignored.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Update all documentation to reference the stable `/v0.1/` API version
instead of the development `/v0/` version.
Didn't update internal references (e.g. in admin-only docs) as that
probably make sense to keep pointed at v0 as the "dev" option.
Authored by Claude Code, reviewed by me.
---------
Co-authored-by: Claude <noreply@anthropic.com>
The schema in this repo may contain unreleased changes, so labeling it
with a dated version URL is misleading. Change to use a `draft` URL
instead, and add documentation for the schema contribution process.
- Update $id in server.schema.json to use draft URL
- Update example $schema URL in openapi.yaml
- Add Draft (Unreleased) section to CHANGELOG.md
- Add CONTRIBUTING.md with process for making/releasing schema changes
Written by Claude Code, reviewed and tweaked by me.
Co-authored-by: Claude <noreply@anthropic.com>
## What this fixes
The API changelog had a section header dated `2025-11-17`, but the
openapi.yaml version is `2025-10-17`. This was confusing because they
appeared to be tracking the same thing but didn't match.
## What happened
1. Various API changes (v0.1 introduction, endpoint removal) were made
in early-to-mid October
2. On **Oct 17**, commit 0828bc4 bumped the openapi.yaml version to
`2025-10-17`
3. These changes sat under an "Unreleased" section in the changelog
4. On **Nov 17**, commit 7b3f01a converted "Unreleased" → `2025-11-17`
as part of the v1.3.9 release process
The problem: `2025-11-17` was the date the release was cut, not the API
version. Since there were no openapi.yaml changes between Oct 17 and Nov
17, the changelog section should match the API version (`2025-10-17`),
not the internal release date.
## The fix
Change the changelog header from `## 2025-11-17` to `## 2025-10-17` to
align with the openapi.yaml version that consumers actually use.
@domdomegg am I correct in thinking this was just a typo? Or was the
distinction intentional?
Authored by Claude Code, reviewed by me.
Co-authored-by: Claude <noreply@anthropic.com>
Follow-up to #728.
This fixes broken links due to file renames.
Fixes#788.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following adds a DELETE method to the reference API specification of
the registry.
The endpoint is consistent with the rest of the spec and provides a
standardised way for registry implementations to support deletion if
they choose to.
**Details:**
* Endpoint: DELETE /v0/servers/{serverName}/versions/{version}
* Uses tags: [publish] (same as POST /v0/publish for write operations)
* Requires security: bearerAuth authentication
* Returns ServerResponse on success (200) - matching POST pattern
* Same error responses: 401 (Unauthorized), 403 (Forbidden), 500
(Internal error)
* Added 404 (Not Found) for when server/version doesn't exist
* Parameters match the GET endpoint format with URL-encoding examples
* Marked as "(Optional)" in summary
* Explicit note that it's not implemented by the official registry
* States it's included for standardization purposes
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
---------
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
This PR reorganizes and extends the existing documentation in
preparation for publishing on https://modelcontextprotocol.io/.
The current plan is for docs to remain in this repo, and be synced to
the `modelcontextprotocol/modelcontextprotocol` whenever necessary
(e.g., accompanying a release of the registry). I have included a script
in
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1725
(`bin/pull-registry-docs.sh`) that can be run manually to perform the
sync.
If we later decide to permanently move the docs to the
`modelcontextprotocol/modelcontextprotocol` repo, that also works.
This PR puts all https://modelcontextprotocol.io/ docs into
`docs/modelcontextprotocol-io/`. Docs outside that subdirectory, such as
`docs/administration/admin-operations.md`, are intended to be accessible
solely via this repo. One major exception is the
`docs/reference/server-json/` subdirectory, which will depend on the
resolution of
https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1649.
However, I think we could address that in a follow-up PR.
---------
Co-authored-by: Adam Jones <adamj+git@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
Microsoft uses `mcr.microsoft.com` to host our public containers. These
are syndicated to Docker Hub but image references use
`mcr.microsoft.com` which is not currently supported by the Official MCP
Registry.
See https://github.com/modelcontextprotocol/registry/issues/753.
Microsoft teams want to use MCR-based images for Microsoft MCP servers.
I believe we should be adding ACR support as well, so that our customers
using Azure Container Registry can use the MCP Registry as well.
In short, MCR is used for Microsoft managed containers. ACR is a
solution for Azure customers to host their own containers.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Unit tests.
Manual test: local push of a server.json with
`mcr.microsoft.com/azure-sdk/azure-mcp:2.0.0-beta.1` and
`azurearcjumpstart.azurecr.io/hello-arc:latest` in it. The error is now
about missing annotation not unsupported OCI registry.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
No.
## 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Add a standardized OAuth 2.1-based authentication specification for MCP
sub-registries, aligned with the MCP Authorization Specification.
This enables:
- Private registry entries with access control
- Permission-based server visibility
- Client code reuse (clients can use their existing MCP auth
implementation)
The spec is intended for downstream sub-registries. The official
registry remains public for reading.
Fixes#751
---------
Co-authored-by: Claude <noreply@anthropic.com>
Updates the API changelog to reflect the v1.3.9 release date
(2025-11-17).
This moves the 'Unreleased' section to a dated section as part of the
v1.3.9 release process.
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Resolve https://github.com/modelcontextprotocol/registry/issues/768 and
https://github.com/modelcontextprotocol/registry/issues/494.
Require HTTPS for remote URLs. Currently all remote URLs on the MCP
Registry are HTTPS.
Also fix a test bug when running on Windows (bad temp path).
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Unit tests.
Published a server.json locally with a website URL not matching the
server name.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [ ] ~I have added or updated documentation as needed~ N/A
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
<!-- Provide a brief summary of your changes -->
## Motivation and Context
This allows the private key used for DNS or HTTP based authentication to
be stored securely in a cloud key management system. These services
often provide HSM storage which makes it very hard to leak the private
key.
The full context is described in my design document here:
https://github.com/modelcontextprotocol/registry/issues/482#issuecomment-3437117171
## How Has This Been Tested?
I have tested it against PROD using an Ed25519 key stored in Google KMS.
I have added unit tests. I have tested both ECDSA P-384 and Ed25519 with
Az KV and Google KMS against a locally running server.
## Breaking Changes
None intended.
## 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)
- [x] 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
---------
Co-authored-by: adam jones <domdomegg+git@gmail.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR:
* Deprecates the existing OCI reference parser
* Deprecates the existing OCI way of authenticating and accessing the
image manifest
* Replaces the above by leveraging go-containerregistry
* Introduces support for Google Artifact Registry
* Enables us to easily add support for other OCI-compliant registries in
the future
* Introduces better error handling
* Introduces custom context timeouts for validation
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Related to #427
---------
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Motivation and Context
See
https://github.com/modelcontextprotocol/registry/issues/482#issuecomment-3436993157
for full details.
This adds ECDSA P-384 (a popular NIST approved curve) in addition to
Ed25519.
## How Has This Been Tested?
I have tested with a local deployment against `mcp.joelverhagen.com`.
Also, I have added significant tests.
## Breaking Changes
None. (hopefully)
## 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)
- [x] 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
@domdomegg and I spoke a bit about this on Discord:
https://discord.com/channels/1358869848138059966/1369487942862504016/1423710918180606052
---------
Co-authored-by: adam jones <domdomegg+git@gmail.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR:
* Makes mcpb package version property optional
* Bumps the schema and reflects that in the code
* Makes sure the publisher tests are being covered by doing `make check`
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
---------
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Addressing
https://github.com/modelcontextprotocol/registry/pull/634#issuecomment-3410615843
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
Updating openapi.yaml to be in sync with latest changes. Funcitonality
for search param introduced back in
https://github.com/modelcontextprotocol/registry/pull/374
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
## How Has This Been Tested?
N/A
## Breaking Changes
N/A
## 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)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] 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)
- [x] 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: Radoslav Dimitrov <radoslav@stacklok.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR adds a new v0.1 API version.
The goal is to mark v0.1 as a "freeze" point while keeping v0 as the
moving target for new features so integrators can start building on top
of something stable(r).
Details:
* This change is quite simple - we re-register the same handlers twice,
once as `v0` and once as `v0.1`
* Going forward, we'll keep v0.1 frozen while we add changes either on
top of both (non-breaking) or we'll have to branch if breaking changes
are necessary
* We all acknowledge this is not exactly best-practice, but it gives us
a way to gather feedback and allow clients to start integrating with the
API without breaking them (**note** this implies a follow up PR that
would branch the handlers used in v0.1).
* For integrators/clients: please provide your feedback - what works
well, what doesn't so we can take this into account going towards GA.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
No, this just adds a new API version alongside the existing one.
## 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)
- [ ] 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Fixes: #649
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
This PR adds a Go tool that extracts the ServerDetail schema from
openapi.yaml and generates server.schema.json, ensuring the two specs
stay in sync.
## Key Changes
### New Tooling
- **Go tool** at `tools/extract-server-schema/` that auto-discovers all
schemas referenced by ServerDetail and extracts them from OpenAPI
- **make targets**: `generate-schema` (generates schema) and
`check-schema` (verifies sync)
- `check-schema` is now included in `make validate` and `make check`
### Preserved Validation Constraints
The initial auto-generated schema lost many important validation rules
and descriptive guidance from the hand-crafted version. The OpenAPI spec
has been updated to preserve:
**Security & Descriptions:**
- Command injection security warning on Arguments
- Detailed field descriptions with usage guidance
- `placeholder` field for Input schema
**Validation Constraints:**
- `fileSha256` pattern validation (`^[a-f0-9]{64}$`)
- Package version restrictions (minLength: 1, no "latest")
- `transport` as required field in Package
- ServerDetail `name` pattern and length constraints (3-200 chars)
- Description, title, and version length limits
**Documentation:**
- Repository field descriptions (url, source, id, subfolder)
- PositionalArgument `valueHint` explains transport URL substitution
- Updated examples to match hand-crafted version (Weather API theme)
**Intentional Changes:**
- Removed `additionalProperties` constraints for flexibility
- Updated schema title to be more descriptive
- Added `$comment` noting auto-generation
See the commit "Preserve validation constraints in auto-generated
server.schema.json" for details.
### Fixed Missing Package.transport
- Added `transport` field to OpenAPI Package schema (was in Go model at
`pkg/model/types.go:30` but missing from OpenAPI)
- Split transport types into three separate schemas with proper
discriminated unions:
- `StdioTransport` - Only requires `type: stdio`
- `StreamableHttpTransport` - Requires `type` and `url`, supports
`headers`
- `SseTransport` - Requires `type` and `url`, supports `headers`
- `Package.transport` uses `anyOf` with all three types
- `ServerDetail.remotes` uses `anyOf` with only remote types (no stdio)
### Other Improvements
- Added `GOTOOLCHAIN=auto` to Makefile for Go 1.25 compatibility
- Added `DRIFT_ANALYSIS.md` documenting all schema drift issues found
between specs
## Benefits
**Single Source of Truth**: The OpenAPI spec now serves as the
authoritative schema definition, with server.schema.json automatically
derived from it.
**Better Validation**: All critical validation rules (patterns, length
constraints, required fields) and security warnings are preserved in the
generated schema.
**Improved Developer Experience**:
- Schema changes only need to be made in one place (openapi.yaml)
- CI validation ensures specs never drift apart
- Clear auto-generation comment prevents manual edits
## Validation
✅ All 20 examples validate correctly
✅ Lint passes with 0 issues
✅ Schema is in sync with OpenAPI
✅ All validation constraints from hand-crafted schema preserved
---------
Co-authored-by: Claude <noreply@anthropic.com>
Implements icon support based on the Model Context Protocol
specification, allowing servers to specify display icons with optional
size, MIME type, and theme variants.
## Changes
- Add `Icon` type to `pkg/model/types.go` with struct tags for automatic
API validation
- Add `icons` field to `ServerJSON` in `pkg/api/v0/types.go`
- Add icon validation in `internal/validators/validators.go`:
- Only HTTPS URLs allowed (no HTTP or data URIs)
- Maximum URL length of 255 characters
- Validates absolute URLs with proper scheme
- Update JSON schema and OpenAPI documentation with Icon definitions
- Add comprehensive test cases for icon validation
- Add example icon to seed.json (Airtable server)
- Change `websiteUrl` validation to HTTPS-only for consistency
## Implementation Details
The implementation uses a two-layer validation architecture:
1. **Huma framework** validates struct tags (`required`, `maxLength`,
`enum`, `pattern`) and returns 422 for violations
2. **Custom validators** handle business logic (HTTPS scheme
requirement, absolute URL requirement) and return 400 for violations
This approach leverages Huma's automatic validation while keeping
business-specific rules in the validator layer.
## Icon Field Specification
- `src` (required): HTTPS URL to icon resource, max 255 characters
- `mimeType` (optional): One of `image/png`, `image/jpeg`, `image/jpg`,
`image/svg+xml`, `image/webp`
- `sizes` (optional): Array of size strings in "WxH" format or "any" for
scalable formats
- `theme` (optional): Either "light" or "dark" to indicate intended
background
Multiple icons can be provided (e.g., for different themes or sizes).
Remove redundant endpoint as suggested in #617. Clients should now use
`GET /v0/servers/{serverName}/versions/latest` instead (using `latest`
as a special version value in the existing endpoint).
This simplifies the API surface and reduces implementation burden for
subregistries, while maintaining a clear migration path for consumers.
## Changes
- Removed `GET /v0/servers/{serverName}` endpoint
- Updated `GET /v0/servers/{serverName}/versions/{version}` to accept
`latest` as special version
- Updated all tests to use new endpoint pattern
- Updated documentation and OpenAPI spec
- Added breaking change notice to CHANGELOG
Fixes#617
Co-authored-by: Claude <noreply@anthropic.com>
- Clarified `value` field description to remove incorrect 'default'
wording
- Improved `valueHint` description to clarify its form and purpose
(labels and variable substitution)
- Fixed NamedArgument `description` to use correct flag syntax (--flag
{value})
- Enhanced `default` field description with guidance on valid values and
when to use placeholder instead
- Added optional Input `placeholder` field for input guidance and
examples
<!-- Provide a brief summary of your changes -->
## Motivation and Context
After implementing a configuration UX for the registry supporting all
schema elements, performing schema validation on all published servers
and analyzing failures, and hand reviewing approximately a hundred
server configurations, I found a number of concerning issues
(essentially misconfigurations, verified by the docs of the server in
question, which often did not fail schema validation). I also found
"proper" configurations which disagreed with the schema guidance (for
example, all named args usage).
I documented those issues and my recommendations here:
https://github.com/modelcontextprotocol/registry/discussions/572
The fairly modest changes in this PR will address these issues (or at
least make the correct usage more clear so that we can give more
explicit guidance that is consistent with the new schema, and generally
clean up these misconfiguration).
## How Has This Been Tested?
I used my own schema validation script to apply this schema to all
published servers. The changes are only documentation (description
updates) and the addition of a new field property, so no validation
behavior change was intended nor was any observed.
## Breaking Changes
No breaking changes
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [X] New feature (non-breaking change which adds functionality)
- [X] 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
- [ ] I have added or updated documentation as needed
## Summary
Introduces a new optional `title` field for MCP servers to provide a
clean, human-readable display name that clients and subregistries can
use for display purposes.
Fixes#606
## Changes
- Added `title` field to `ServerJSON` type (optional, max 100 chars)
- Added validation to reject titles ending with 'MCP Server', 'MCP
server', or 'MCP' suffixes
- Updated JSON schema and OpenAPI specification
- Added comprehensive test coverage for title validation
- Updated all documentation examples to demonstrate the new field
## Validation
The title field:
- Is optional (can be omitted)
- Must not be only whitespace if provided
- Must not end with MCP-related suffixes (case-insensitive)
- Can contain 'MCP' in the middle (e.g., "MCP Weather API" is valid)
Examples:
- ✅ Valid: "GitHub", "Weather API", "Slack Integration"
- ❌ Invalid: "GitHub MCP", "Weather MCP Server", "Slack-MCP"
---------
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR:
* Enforces schema validation on the API level (requests without schema
or older schema will fail)
* Updates the unit tests and examples to match that
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
**Note this can be considered breaking if clients have not included it
before.**
## 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)
- [ ] 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. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
---------
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
This PR simplifies the OpenAPI schema by merging the `Server` component
into `ServerDetail`, addressing the issue where the `Server` component
was never used independently.
## Changes
- Merged all Server properties directly into ServerDetail in both
OpenAPI spec and JSON schema
- Removed allOf construct for clearer, standalone definitions
- Deleted unused Server components
## Benefits
- Clearer schema structure
- Easier to understand without inheritance tracing
- Reduced maintenance complexity
- No functionality loss
## Validation
All schemas and documentation examples continue to validate
successfully.
Resolves#609
Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: adam jones <domdomegg@users.noreply.github.com>
## Summary
Changes `streamable-http` to be the recommended and primary transport
type in documentation examples, while keeping SSE as a secondary option
during the preview period.
## Changes
- ✅ Update all primary remote server examples to use `streamable-http`
- ✅ Reorder multi-transport examples to show `streamable-http` first
- ✅ Add note that SSE is deprecated but still supported during preview
- ✅ Update transport protocol requirements text to indicate
`streamable-http` (recommended) and `sse` (deprecated)
## Context
As noted in issue #487, the docs were using SSE as the primary example
despite it being deprecated in the MCP specification (2025-06-18) in
favor of streamable HTTP. This PR aligns the documentation with the spec
while maintaining backward compatibility information for the preview
period.
Per maintainer feedback on the issue:
- SSE is still supported during the preview phase
- Eventually SSE support will be removed
- The community would benefit from consistent messaging about the
preferred transport
## Files Changed
- `docs/guides/publishing/publish-server.md` - Main publishing guide
- `docs/reference/server-json/generic-server-json.md` - Reference
documentation with examples
## Approach
This takes a balanced approach:
- Makes streamable-http the clear primary/recommended option
- Keeps SSE documented as supported during preview (not hidden)
- Adds explicit note about deprecation status
- Minimal changes, focused on examples and ordering
Fixes#487🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR adds more clarity to the docs around what's considered
open source, closed source, public and private in the context of MCP
servers.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Summary
- Remove the `status` field from all server.json examples in
documentation
- Remove the deprecated server example that was primarily about
demonstrating the status field
- Update example count validation from 13 to 12
## Context
The `status` field was removed from the server.json schema in commit
b21c6f5 (#562). This PR cleans up the documentation to reflect that
change.
## Why didn't tests catch this?
The schema validation didn't catch the invalid `status` field because
the JSON schema doesn't have `additionalProperties: false` set. This
means the schema allows arbitrary additional properties by default.
## Test plan
- [x] All validation checks pass (`make check`)
- [x] Example count updated to match the new total (12 examples)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
This seems to be a regresion after rename, those fields were originally
required:
8d7e471fd3/docs/server-registry-api/openapi.yaml (L247-L252)
In
https://static.modelcontextprotocol.io/schemas/2025-09-16/server.schema.json,
those fields are also required.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
No
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] 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
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
- Add missing required fields (description, transport) to all
server.json examples
- Add $schema field to examples that were missing it
- Add version field to MCPB example
- Create validation tool for guide examples with $schema
- Integrate guide validation into Makefile and CI
Fixes#507🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: adam jones <domdomegg@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Wielded Claude Code to do this; across many iterations and have reviewed
all the code + largely rewritten the PR commentary here.
This PR implements the server ID consistency changes from
[#396](https://github.com/modelcontextprotocol/registry/issues/396). Our
goal is to:
- Rename `id` to `versionId` to make it clear that it is the ID for a
specific version, not a server
- Introduce `serverId` as a net new concept. This will be 1:1 with
`name`. While not strictly necessary (we could just use name as a PK),
the convention of having a UUID as an ID on our objects is just a
helpful subjective architecture decision. Plus also leaves open the door
to reconsidering the "should we allow renames" question.
## Key Changes
### 🗄️ Database Schema Changes
- **Renamed**: `id` column → `version_id` (unique identifier for each
server version)
### 📋 Metadata Structure Updates
- **JSON Schema**: Updated
`_meta.io.modelcontextprotocol.registry/official` to include:
- `serverId`: Consistent ID across all versions of a server
- `versionId`: Unique ID for this specific version (renamed from `id`)
### 🔧 API Endpoint Updates
- **New endpoint structure**: Changed from version-ID-based to
server-ID-based URLs:
- `GET /v0/servers/{server_id}` - Get latest version of server
- `GET /v0/servers/{server_id}?version=X.X.X` - Get specific version
- `GET /v0/servers/{server_id}/versions` - List all versions of a server
- `PUT /v0/servers/{server_id}?version=X.X.X` - Edit specific version
- **Consistent URL patterns**: All server endpoints now use `server_id`
as the primary identifier
### Database Migration Strategy
The migration (`005_add_server_id_rename_version_id.sql`):
1. Adds new `version_id` column
2. Generates deterministic UUIDs for servers with the same name
3. Updates JSON metadata to add `serverId` and rename `id` to
`versionId`
4. Copies existing `id` values to `version_id` column
5. Drops old `id` column and makes `version_id` the new primary key
## Testing
Besides of course automated tests passing, I:
1. Set up my local db with the pre-005-migration state, imported all the
production data
2. Ran the migration
3. Spot checked some diffs of the data that resulted --
```json
// before
{
"name": "io.github.ruvnet/ruv-swarm",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"id": "0a9cda7f-2b73-4839-844b-6582f335de42",
"is_latest": false,
"updated_at": "2025-09-10T17:21:34.92137012Z",
"published_at": "2025-09-10T17:15:32.69690433Z"
}
},
"version": "1.0.18",
"repository": {
"url": "",
"source": ""
},
"description": "Neural network swarm orchestration with WebAssembly acceleration and MCP integration"
}
// after
{
"name": "io.github.ruvnet/ruv-swarm",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "e8538952-96af-4a33-9e31-7fbed012521e",
"is_latest": false,
"versionId": "0a9cda7f-2b73-4839-844b-6582f335de42",
"updated_at": "2025-09-10T17:21:34.92137012Z",
"published_at": "2025-09-10T17:15:32.69690433Z"
}
},
"version": "1.0.18",
"repository": {
"url": "",
"source": ""
},
"description": "Neural network swarm orchestration with WebAssembly acceleration and MCP integration"
}
```
Servers that have multiple versions stayed consistent in their
`serverId`:
```json
// First version
{
"name": "app.getdialer/dialer",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "80f08bdb-f3e4-4f19-b072-1676ae49b663",
"is_latest": false,
"versionId": "04f25b17-331d-48d7-b08b-37baece208a7",
"updated_at": "2025-09-09T00:16:49.162620072Z",
"published_at": "2025-09-08T23:47:09.452137971Z"
}
},
"status": "active",
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
"remotes": [
{
"url": "https://getdialer.app/mcp",
"type": "streamable-http"
},
{
"url": "https://getdialer.app/sse",
"type": "sse"
}
],
"version": "1.0.0",
"repository": {
"url": "",
"source": ""
},
"description": "An MCP server that provides your you make outbound phone calls using your own phone number"
}
// Second version
{
"name": "app.getdialer/dialer",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "80f08bdb-f3e4-4f19-b072-1676ae49b663",
"is_latest": true,
"versionId": "faa26cb9-3aad-415e-aece-f715fff5fe5e",
"updated_at": "2025-09-09T00:16:49.107842808Z",
"published_at": "2025-09-09T00:16:49.107842808Z"
}
},
"status": "active",
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
"remotes": [
{
"url": "https://getdialer.app/mcp",
"type": "streamable-http"
},
{
"url": "https://getdialer.app/sse",
"type": "sse"
}
],
"version": "1.0.1",
"repository": {
"url": "",
"source": ""
},
"description": "An MCP server that provides lets you make outbound phone calls using your own phone number"
}
```
And I also tried publishing a test server anew; looked good:
```bash
⏺ Bash(curl -s "http://localhost:8080/v0/servers/102dc4e4-6ca8-40e6-aa11-cd45763d3352" | jq '.')
⎿ {
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
"name": "io.modelcontextprotocol.anonymous/test-claude-migration-server",
"description": "A test server to verify the new migration and API endpoints work correctly",
"status": "active",
"repository": {
"url": "https://github.com/example/test-claude-migration-server",
"source": "github",
"id": "example/test-claude-migration-server"
},
"version": "1.0.0",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "102dc4e4-6ca8-40e6-aa11-cd45763d3352",
"versionId": "48c9cd55-7bc4-4ac2-896e-59e81eb653e4",
"published_at": "2025-09-12T18:33:23.264203-07:00",
"updated_at": "2025-09-12T18:33:23.264203-07:00",
"is_latest": true
}
}
}
⏺ Bash(curl -s "http://localhost:8080/v0/servers/102dc4e4-6ca8-40e6-aa11-cd45763d3352/versions" | jq '.')
⎿ {
"servers": [
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
"name": "io.modelcontextprotocol.anonymous/test-claude-migration-server",
"description": "A test server to verify the new migration and API endpoints work correctly",
"status": "active",
"repository": {
"url": "https://github.com/example/test-claude-migration-server",
"source": "github",
"id": "example/test-claude-migration-server"
},
"version": "1.0.0",
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "102dc4e4-6ca8-40e6-aa11-cd45763d3352",
"versionId": "48c9cd55-7bc4-4ac2-896e-59e81eb653e4",
"published_at": "2025-09-12T18:33:23.264203-07:00",
"updated_at": "2025-09-12T18:33:23.264203-07:00",
"is_latest": true
}
}
}
],
"metadata": {
"count": 1
}
}
```
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Preeti Dewani <preetidewani1990@gmail.com>
Co-authored-by: adam jones <adamj+git@anthropic.com>
Co-authored-by: Adam Jones <adamj@anthropic.com>
## Summary
- Fixed `Remote` schema in OpenAPI spec to use correct field name `type`
instead of `transport_type`
- Updated enum values from `[streamable, sse]` to `[streamable-http,
sse]` to match actual API
## Context
The OpenAPI spec was inconsistent with the actual API implementation.
The live API at https://registry.modelcontextprotocol.io/v0/servers
returns `type: 'sse'` and `type: 'streamable-http'`, but the spec
defined `transport_type` with values `streamable` and `sse`.
This now matches:
- The Go constants in pkg/model/constants.go
- The actual API responses
## Summary
- Move package version 'remarks' to 'description' field in JSON schema
(remarks is not a standard JSON schema field)
- Confirmed non-semver version test coverage already exists
Addresses followup comments from #435.
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: adam jones <domdomegg@users.noreply.github.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
Currently there are a couple shortcomings I found in the
server.schema.json:
- It uses `https://json-schema.org/draft/2020-12/schema` which is
unfortunately [not supported by VS
Code](https://github.com/microsoft/vscode/issues/165219)
- The Package schema does not require properties that are required by
the service
This means that need to round trip with the publish endpoint (perhaps
spinning CI builds) to get the server.json right. It would be great if
we could shift left and get indications in VS Code easier.
I propose we downgrade the schema to
`http://json-schema.org/draft-07/schema#`. The only difference for us is
the name of `$def` pointers.
I looked that [SchemaStore](https://github.com/SchemaStore/schemastore)
and it looks like `draft-07` is by far the most popular. I believe the
concession of using an older schema is worth it to get VS Code editor
hints.
Schema version | Count in SchemaStore
-- | --
`http://json-schema.org/draft-04/schema#` | 292
`http://json-schema.org/draft-07/schema#` | 1972
`https://json-schema.org/draft/2019-09/schema` | 4
`https://json-schema.org/draft/2020-12/schema` | 4
<!-- Why is this change needed? What problem does it solve? -->
## Open questions
- [ ] Should package `transport` actually be required? Or should `stdio`
be assumed?
- [ ] Should package `registry_base_url` be required? All of the
examples have it it's not required by the publish endpoint.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
I have tried the new schema inside VS Code and I get helpful warning.
For example, these are the warnings for the old schema.
<img width="1561" height="919" alt="image"
src="https://github.com/user-attachments/assets/474170b8-acf8-4dca-a3d9-66c68c0d1902"
/>
I have run these:
`go run .\tools\validate-examples\main.go`
`go run .\tools\validate-schemas\main.go `
## Breaking Changes
I don't think these are breaking changes. I am expressing what the
publish endpoint enforces at runtime.
## 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)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] 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
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
<!-- Provide a brief summary of your changes -->
Validates that server versions are not ranges.
**NB:** This also introduces `validateVersion` as a check on the
top-level `ValidateServerJSON`, as previously we were only checking
version ranges of packages via `validatePackageField` (i.e. `latest`
would have still been a valid top level server version), despite #413's
wording suggesting otherwise.
## Motivation and Context
Solves https://github.com/modelcontextprotocol/registry/issues/415
## How Has This Been Tested?
Tests added in `internal/validators/validators_test.go`
`make check` is clean.
## Breaking Changes
As per @domdomegg's comment, we should
> check nobody has done this in the existing registry data (if they
have, we should explore and understand why people have done this / if
it's valid etc.).
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] 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)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Adds optional website_url field to the server.json schema allowing
publishers to provide a url to the server's homepage, documentation, or
project website. This provides a central link for users to learn more
about the server. Particularly useful when the server has custom
installation instructions or setup requirements.
Issue: #183
PR: #130
Discussion: #274
## Motivation and Context
This change addresses the need identified in #130, #183 and #274 for a
standardized way to direct users to an official landing page similar to
`homepage` used in NPM
([example](https://www.npmjs.com/package/@modelcontextprotocol/sdk)). It
is also serves as a viable option for MCP Servers that don't follow
typical package manager patterns (e.g., embedded in a Desktop app).
## How Has This Been Tested?
- Schema validation: All 13 example server.json files validate
successfully against the updated schema
- Go validator tests: Added additional test cases covering URL format
validation and namespace matching
- Run all checks: Updated example files to work with anonymous
publishing and verified `make check` passes
## Breaking Changes
None. The website_url field is optional and backward compatible with
existing server.json files.
## Types of changes
- [ ] 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)
- [x] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
Security considerations:
- Website URL validation enforces that the domain matches the
publisher's reverse-DNS namespace
- HTTP/HTTPS protocols are required (no file:// or other schemes)
- Validation is consistent with existing remote URL validation patterns
Update FAQ to clarify that the registry is primarily designed for
subregistries rather than individual clients or end-users.
I saw MCP client applications were listed here, which I think is not
what we were intending.
## Motivation and Context
We just want to highlight that Docker Hub will support this project with
updates to the `docker mcp` cli and the [mcp
hub](https://hub.docker.com/mcp) catalog.
The publishing guide incorrectly suggested users could verify their
server by directly accessing `/servers/{server-name}` or
`/v0/servers/{server-name}`, but the API only supports:
1. **Search by name**: `GET /v0/servers?search={server-name}`
2. **Get by UUID**: `GET /v0/servers/{uuid}`
This PR updates the documentation to show the correct verification
method using the search endpoint.
Fixes#410
Fixes#385
Updates DNS authentication documentation to correctly specify that TXT
records should be placed at the root domain (e.g., `example.com`) rather
than the `_mcp-registry` subdomain.
The implementation correctly looks up TXT records at the root domain,
but the documentation incorrectly instructed users to create records at
`_mcp-registry.<domain>`. This mismatch was causing authentication
failures.
## Why use root domain instead of subdomain?
The root domain approach is clearer: if you want to publish to
`com.example/my-server`, you authenticate with `example.com`, not
`_mcp-registry.example.com`.
It also aligns with other TXT DNS standards, e.g. SPF. (That said, there
are other DNS standards that use subdomains e.g. DKIM 🤷)
## Changes
- Updated publish-server.md to remove `_mcp-registry.` prefix from DNS
examples
- Updated CLI commands reference documentation
- Updated namespacing explanation documentation