registry/docs/reference/server-json/official-registry-requirements.md
Joel Verhagen 2ca4ae9977
Add support for ACR (Azure Container Registry) and MCR (Microsoft Container Registry) (#754)
<!-- 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
-->
2025-11-18 09:58:10 +02:00

134 lines
5.3 KiB
Markdown

# Official Registry Server.json Requirements
This document describes the additional requirements and validation rules that apply when publishing to the official MCP Registry at `registry.modelcontextprotocol.io`.
For step-by-step publishing instructions, see the [publishing guide](../../guides/publishing/publish-server.md).
## Overview
While the [generic server.json format](./generic-server-json.md) defines the base specification, the official registry enforces additional validation to ensure:
- **Namespace authentication** - Servers are published under appropriate namespaces
- **Package ownership verification** - Publishers actually control referenced packages
- **Remote server URL match** - Remote server base urls match namespaces
- **Restricted registry base urls** - Packages are from trusted public registries
- **`_meta` namespace restrictions** - Restricted to `publisher` key only
## Namespace Authentication
Publishers must prove ownership of their namespace. For example to publish to `com.example/server`, the publisher must prove they own the `example.com` domain.
See the [publishing guide](../../guides/publishing/publish-server.md) for authentication details for GitHub and domain namespaces.
## Package Ownership Verification
All packages must include metadata proving the publisher owns them. This prevents impersonation and ensures authenticity (see more reasoning in [#96](https://github.com/modelcontextprotocol/registry/issues/96)).
For detailed verification requirements for each registry type, see the [publishing guide](../../guides/publishing/publish-server.md).
## Remote Server URL Match
Remote servers must use URLs that match the publisher's domain from their namespace. For example, `com.example/server` can only use remote URLs on `example.com` or its subdomains.
## Restricted Registry Base URLs
Only trusted public registries are supported. Private registries and alternative mirrors are not allowed.
**Supported registries:**
- **NPM**: `https://registry.npmjs.org` only
- **PyPI**: `https://pypi.org` only
- **NuGet**: `https://api.nuget.org` only
- **Docker/OCI**:
- Docker Hub (`docker.io`)
- GitHub Container Registry (`ghcr.io`)
- Google Artifact Registry (`*.pkg.dev`)
- Azure Container Registry (`*.azurecr.io`)
- Microsoft Container Registry (`mcr.microsoft.com`)
- **MCPB**: `https://github.com` releases and `https://gitlab.com` releases only
## `_meta` Namespace Restrictions
The `_meta` field in `server.json` allows publishers to include custom metadata alongside their server definitions.
### Publisher-Provided Metadata
When publishing to the official registry, **only data under the specific key `io.modelcontextprotocol.registry/publisher-provided` will be preserved**. Any other keys in the `_meta` object are silently dropped during publishing and will not be stored or returned by the registry.
**Example:**
```jsonc
{
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"tool": "ci-publisher",
"version": "1.0.0",
"custom_data": "your data here"
},
"some.other.key": {
// This will be dropped and not preserved
}
}
}
```
**Size limit:** The publisher-provided extension is limited to 4KB (4096 bytes) of JSON. If the marshaled JSON exceeds this limit, publishing will fail with an error indicating the actual size.
### Registry API Metadata vs server.json Metadata
The `_meta` field in `server.json` is **different** from the `_meta` field returned in registry API responses:
- **In `server.json`**: The `_meta` field contains publisher-provided custom metadata under `io.modelcontextprotocol.registry/publisher-provided`
- **In API responses**: The `_meta` field is returned as a separate property at the response level (not inside `server.json`) and contains registry-managed metadata like:
- `status`: Server lifecycle status (active, deprecated, deleted)
- `publishedAt`: When the server was first published
- `updatedAt`: When the server was last updated
- `isLatest`: Whether this is the latest version
**Example: What you publish (server.json)**
```jsonc
{
"name": "io.github.example/my-server",
"version": "1.0.0",
"description": "My MCP server",
// ... other fields ...
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"tool": "ci-publisher",
"version": "2.0.0"
}
}
}
```
**Example: What the registry API returns**
```jsonc
{
"server": {
"name": "io.github.example/my-server",
"version": "1.0.0",
"description": "My MCP server",
// ... other fields ...
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"tool": "ci-publisher",
"version": "2.0.0"
}
}
},
"_meta": {
// Registry-managed metadata at response level
"status": "active",
"publishedAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"isLatest": true
}
}
```
Notice how the registry API response has **two** `_meta` fields:
1. Inside the `server` object: Your publisher-provided metadata (preserved from server.json)
2. At the response level: Registry-managed metadata (automatically added by the registry)
Registry-managed metadata cannot be set or overridden by publishers. See the [API documentation](../api/generic-registry-api.md) for the complete response structure.