Split OpenAPI specs into base and official registry versions (#171)

Closes #149

As noted in the FAQ update here, this is a helpful starting point in
thinking about this:

```
### What is the difference between "Official MCP Registry", "MCP Registry", "MCP registry", "MCP Registry API", etc?

There are four underlying concepts:
- "MCP Server Registry API" (or "MCP Registry API"): The OpenAPI specification defined in [openapi.yaml](./server-registry-api/openapi.yaml). This is a reusable API specification that anyone building any sort of "MCP server registry" should consider adopting / aligning with.
- "Official MCP Registry" (or "MCP Registry"): The application that lives at `https://registry.modelcontextprotocol.io`. This registry currently only catalogs MCP servers, but may be extended in the future to also catalog MCP client/host apps and frameworks.
- "Official MCP Registry API": The REST API that lives at `https://registry.modelcontextprotocol.io/api`, with an OpenAPI specification defined at [official-registry-openapi.yaml](./server-registry-api/official-registry-openapi.yaml)
- "MCP server registry" (or "MCP registry"): A third party, likely commercial, implementation of the MCP Server Registry API or derivative specification.
```

Prior to this PR, we were just treating "MCP Server Registry API" and
"Official MCP Registry API" to be the same thing. They are not the same:
the latter is inherently a more constrained version of the former. A
private deployment of a similar registry need not have constraints like
"the only valid source code repositories are `github` and `gitlab`".

This PR separates out the definitions to match that path forward.

## Notable Changes

### Base OpenAPI spec (`openapi.yaml`)
- Removed official-registry-specific constraints:
  - No maximum limit on `/servers` endpoint
  - No enum constraint on `Repository.source`
  - No enum constraint on `Package.registry_name`
- Removed `/v0` prefix from paths (it's now just baked into the
`official` one's URL prefix)
- Added `$id` for proper schema identification

### Official Registry OpenAPI spec (`official-registry-openapi.yaml`)
- Created as a derivative of the base spec using `$ref`
- Re-adds official-registry-specific constraints:
  - `Repository.source` enum: `[github]`
  - `Package.registry_name` enum: `[npm, docker, pypi, nuget]`

### Documentation updates
- Added `server-registry-api/README.md` explaining the relationship
between specs
- Updated FAQ to clarify terminology
- Reorganized docs structure
This commit is contained in:
Tadas Antanavicius 2025-07-09 17:46:01 -07:00 • committed by GitHub
commit 05422afffb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 70 additions and 19 deletions

View file

@ -13,6 +13,14 @@ The MCP Registry is the official centralized metadata repository for publicly-ac
- Standardized installation and configuration information
- Namespace management through DNS verification
### What is the difference between "Official MCP Registry", "MCP Registry", "MCP registry", "MCP Registry API", etc?
There are four underlying concepts:
- "MCP Server Registry API" (or "MCP Registry API"): The OpenAPI specification defined in [openapi.yaml](./server-registry-api/openapi.yaml). This is a reusable API specification that anyone building any sort of "MCP server registry" should consider adopting / aligning with.
- "Official MCP Registry" (or "MCP Registry"): The application that lives at `https://registry.modelcontextprotocol.io`. This registry currently only catalogs MCP servers, but may be extended in the future to also catalog MCP client/host apps and frameworks.
- "Official MCP Registry API": The REST API that lives at `https://registry.modelcontextprotocol.io/api`, with an OpenAPI specification defined at [official-registry-openapi.yaml](./server-registry-api/official-registry-openapi.yaml)
- "MCP server registry" (or "MCP registry"): A third party, likely commercial, implementation of the MCP Server Registry API or derivative specification.
### Is the MCP Registry a package registry?
No. The MCP Registry stores metadata about MCP servers and references to where they're hosted (npm, PyPI, NuGet, Docker Hub, etc.), but does not host the actual source code or packages.

View file

@ -0,0 +1,14 @@
# Registry API
There are a variety of use cases where an MCP Server Registry API is useful to the MCP ecosystem. At least the following:
- Implementation of a centralized, publicly available catalog of all publicly accessible MCP server implementations
- Implementation of a private catalog of MCP server implementations exclusively accessible by a specific group of people (e.g. a single enterprise)
These scenarios would benefit from a standard "MCP server registry API" specification that they could potentially compose, as well as share resources (like SDK implementations).
The centralized, publicly available catalog ("Official MCP Registry") needs additional constraints that need not apply to the broader "MCP server registry API"
References:
- [openapi.yaml](./openapi.yaml) - A reusable API specification (MCP Server Registry API) that anyone building any sort of "MCP server registry" should consider adopting / aligning with.
- [examples.md](./api_examples.md) - Example manifestations of the OpenAPI specification
- [official-registry-openapi.ayml](./official-registry-openapi.yaml) - The specification backing the Official MCP Registry; a derivative of the MCP Server Registry API specification.

View file

@ -0,0 +1,288 @@
# Examples
## /v0/servers
### Request
```http
GET /v0/servers?limit=5000&offset=0
```
### Response
```json
{
"servers": [
{
"id": "a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1",
"name": "io.modelcontextprotocol/filesystem",
"description": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations.",
"repository": {
"url": "https://github.com/modelcontextprotocol/servers",
"source": "github",
"id": "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9"
},
"version_detail": {
"version": "1.0.2",
"release_date": "2023-06-15T10:30:00Z",
"is_latest": true
}
}
],
"next": "https://registry.modelcontextprotocol.io/servers?offset=50",
"total_count": 1
}
```
## /v0/servers/:id
### Request
```http
GET /v0/servers/a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1?version=0.0.3
```
### Response
```json
{
"id": "a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1",
"name": "io.modelcontextprotocol/filesystem",
"description": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations.",
"repository": {
"url": "https://github.com/modelcontextprotocol/servers",
"source": "github",
"id": "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9"
},
"version_detail": {
"version": "1.0.2",
"release_date": "2023-06-15T10:30:00Z",
"is_latest": true
},
"packages": [
{
"registry_name": "npm",
"name": "@modelcontextprotocol/server-filesystem",
"version": "1.0.2",
"package_arguments": [
{
"type": "positional",
"value_hint": "target_dir",
"description": "Path to access",
"default": "/Users/username/Desktop",
"is_required": true,
"is_repeated": true
}
],
"environment_variables": [
{
"name": "LOG_LEVEL",
"description": "Logging level (debug, info, warn, error)",
"default": "info"
}
]
},
{
"registry_name": "docker",
"name": "mcp/filesystem",
"version": "1.0.2",
"runtime_arguments": [
{
"type": "named",
"description": "Mount a volume into the container",
"name": "--mount",
"value": "type=bind,src={source_path},dst={target_path}",
"is_required": true,
"is_repeated": true,
"variables": {
"source_path": {
"description": "Source path on host",
"format": "filepath",
"is_required": true
},
"target_path": {
"description": "Path to mount in the container. It should be rooted in `/project` directory.",
"is_required": true,
"default": "/project",
}
}
}
],
"package_arguments": [
{
"type": "positional",
"value_hint": "target_dir",
"value": "/project",
}
],
"environment_variables": [
{
"name": "LOG_LEVEL",
"description": "Logging level (debug, info, warn, error)",
"default": "info"
}
]
}
],
"remotes": [
{
"transport_type": "sse",
"url": "https://mcp-fs.example.com/sse"
}
]
}
```
### Server Configuration Examples
#### Local Server with npx
API Response:
```json
{
"id": "brave-search-12345",
"name": "io.modelcontextprotocol/brave-search",
"description": "MCP server for Brave Search API integration",
"repository": {
"url": "https://github.com/modelcontextprotocol/servers",
"source": "github",
"id": "abc123de-f456-7890-ghij-klmnopqrstuv"
},
"version_detail": {
"version": "1.0.2",
"release_date": "2023-06-15T10:30:00Z",
"is_latest": true
},
"packages": [
{
"registry_name": "npm",
"name": "@modelcontextprotocol/server-brave-search",
"version": "1.0.2",
"environment_variables": [
{
"name": "BRAVE_API_KEY",
"description": "Brave Search API Key",
"is_required": true,
"is_secret": true
}
]
}
]
}
```
claude_desktop_config.json:
```json
{
"brave-search": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-brave-search"
],
"env": {
"BRAVE_API_KEY": "YOUR_API_KEY_HERE"
}
}
}
```
#### Local Server with Docker
API Response:
```json
{
"id": "filesystem-67890",
"name": "io.modelcontextprotocol/filesystem",
"description": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations",
"repository": {
"url": "https://github.com/modelcontextprotocol/servers",
"source": "github",
"id": "d94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9"
},
"version_detail": {
"version": "1.0.2",
"release_date": "2023-06-15T10:30:00Z",
"is_latest": true
},
"packages": [
{
"registry_name": "docker",
"name": "mcp/filesystem",
"version": "1.0.2",
"runtime_arguments": [
{
"type": "named",
"description": "Mount a volume into the container",
"name": "--mount",
"value": "type=bind,src={source_path},dst={target_path}",
"is_required": true,
"is_repeated": true,
"variables": {
"source_path": {
"description": "Source path on host",
"format": "filepath",
"is_required": true
},
"target_path": {
"description": "Path to mount in the container. It should be rooted in `/project` directory.",
"is_required": true,
"default": "/project",
}
}
}
],
"package_arguments": [
{
"type": "positional",
"value_hint": "target_dir",
"value": "/project",
}
]
}
]
}
```
claude_desktop_config.json:
```json
{
"filesystem": {
"server": "@modelcontextprotocol/servers/src/filesystem@1.0.2",
"package": "docker",
"settings": {
"--mount": [
{ "source_path": "/Users/username/Desktop", "target_path": "/project/desktop" },
{ "source_path": "/path/to/other/allowed/dir", "target_path": "/project/other/allowed/dir,ro" },
]
}
}
}
```
#### Remote Server
API Response:
```json
{
"id": "remote-fs-54321",
"name": "Remote Brave Search Server",
"description": "Cloud-hosted MCP Brave Search server",
"repository": {
"url": "https://github.com/example/remote-fs",
"source": "github",
"id": "xyz789ab-cdef-0123-4567-890ghijklmno"
},
"version_detail": {
"version": "1.0.2",
"release_date": "2023-06-15T10:30:00Z",
"is_latest": true
},
"remotes": [
{
"transport_type": "sse",
"url": "https://mcp-fs.example.com/sse"
}
]
}
```

View file

@ -0,0 +1,42 @@
openapi: 3.1.0
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
info:
title: Official MCP Registry API
summary: Official API for discovering and accessing MCP servers metadata with registry constraints
description: |
Extends the base MCP Server Registry API with additional constraints for the official registry and adding additional functionality.
The Official Registry allows server creators to publish and maintain metadata about their servers in a standardized format.
The read side of the API enables MCP client applications and "server aggregator" type consumers to discover and install MCP servers.
version: 0.0.1
contact:
name: MCP Community Working Group
license:
name: MIT
identifier: MIT
servers:
- url: https://registry.modelcontextprotocol.io/api/v0
description: Official MCP Registry
paths:
/servers:
$ref: 'https://modelcontextprotocol.io/schemas/draft/2025-07-09/server-registry-openapi#/paths/~1servers'
/servers/{id}:
$ref: 'https://modelcontextprotocol.io/schemas/draft/2025-07-09/server-registry-openapi#/paths/~1servers~1{id}'
components:
schemas:
Repository:
allOf:
- $ref: 'https://modelcontextprotocol.io/schemas/draft/2025-07-09/server-registry-openapi#/components/schemas/Repository'
- type: object
properties:
source:
enum: [github]
Package:
allOf:
- $ref: 'https://modelcontextprotocol.io/schemas/draft/2025-07-09/server-registry-openapi#/components/schemas/Package'
- type: object
properties:
registry_name:
enum: [npm, docker, pypi, nuget]

View file

@ -0,0 +1,339 @@
openapi: 3.1.0
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
$id: https://modelcontextprotocol.io/schemas/draft/2025-07-09/server-registry-openapi
info:
title: MCP Server Registry API
summary: API for discovering and accessing MCP server metadata
description: |
Specification for a theoretical REST API that serves up metadata about MCP servers.
license:
name: MIT
identifier: MIT
paths:
/servers:
get:
summary: List MCP servers
description: Returns a list of all registered MCP servers
parameters:
- name: limit
in: query
description: Number of results per page
schema:
type: integer
minimum: 1
- name: offset
in: query
description: Number of results to skip for pagination
schema:
type: integer
default: 0
minimum: 0
responses:
'200':
description: A list of MCP servers
content:
application/json:
schema:
$ref: '#/components/schemas/ServerList'
/servers/{id}:
get:
summary: Get MCP server details
description: Returns detailed information about a specific MCP server
parameters:
- name: id
in: path
required: true
description: Unique ID of the server
schema:
type: string
format: uuid
- name: version
in: query
description: Desired MCP server version
schema:
type: string
responses:
'200':
description: Detailed server information
content:
application/json:
schema:
$ref: '#/components/schemas/ServerDetail'
'404':
description: Server not found
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Server not found"
components:
schemas:
Repository:
type: object
required:
- url
- source
- id
properties:
url:
type: string
format: uri
example: "https://github.com/modelcontextprotocol/servers"
source:
type: string
example: "github"
id:
type: string
example: "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9"
Server:
type: object
required:
- id
- name
- description
- version_detail
properties:
id:
type: string
format: uuid
example: "a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1"
name:
type: string
description: Human-readable description of the server's functionality
example: "io.modelcontextprotocol/filesystem"
description:
type: string
example: "Node.js server implementing Model Context Protocol (MCP) for filesystem operations."
repository:
$ref: '#/components/schemas/Repository'
version_detail:
$ref: '#/components/schemas/VersionDetail'
VersionDetail:
type: object
required:
- version
- release_date
- is_latest
properties:
version:
type: string
example: "1.0.2"
description: Equivalent of Implementation.version in MCP specification.
release_date:
type: string
format: date-time
example: "2023-06-15T10:30:00Z"
description: Datetime that the MCP server version was published to the registry.
is_latest:
type: boolean
example: true
description: Whether the MCP server version is the latest version available in the registry.
ServerList:
type: object
required:
- servers
- total_count
properties:
servers:
type: array
items:
$ref: '#/components/schemas/Server'
next:
type: string
format: uri
example: "https://registry.modelcontextprotocol.io/servers?offset=50"
total_count:
type: integer
example: 1
Package:
type: object
required:
- registry_name
- name
- version
properties:
registry_name:
type: string
description: Package registry type
example: "npm"
name:
type: string
description: Package name in the registry
example: "io.modelcontextprotocol/filesystem"
version:
type: string
description: Package version
example: "1.0.2"
runtime_hint:
type: string
description: A hint to help clients determine the appropriate runtime for the package. This field should be provided when `runtime_arguments` are present.
examples: [npx, uvx, dnx]
runtime_arguments:
type: array
description: A list of arguments to be passed to the package's runtime command (such as docker or npx). The `runtime_hint` field should be provided when `runtime_arguments` are present.
items:
$ref: '#/components/schemas/Argument'
package_arguments:
type: array
description: A list of arguments to be passed to the package's binary.
items:
$ref: '#/components/schemas/Argument'
environment_variables:
type: array
description: A mapping of environment variables to be set when running the package.
items:
$ref: '#/components/schemas/KeyValueInput'
Input:
type: object
properties:
description:
description: A description of the input, which clients can use to provide context to the user.
type: string
is_required:
type: boolean
default: false
format:
type: string
description: |
Specifies the input format. Supported values include `filepath`, which should be interpreted as a file on the user's filesystem.
When the input is converted to a string, booleans should be represented by the strings "true" and "false", and numbers should be represented as decimal values.
enum: [string, number, boolean, filepath]
default: string
value:
type: string
description: |
The default value for the input. If this is not set, the user may be prompted to provide a value. If a value is set, it should not be configurable by end users.
Identifiers wrapped in `{curly_braces}` will be replaced with the corresponding properties from the input `variables` map. If an identifier in braces is not found in `variables`, or if `variables` is not provided, the `{curly_braces}` substring should remain unchanged.
is_secret:
type: boolean
description: Indicates whether the input is a secret value (e.g., password, token). If true, clients should handle the value securely.
default: false
default:
type: string
description: The default value for the input.
choices:
type: array
description: A list of possible values for the input. If provided, the user must select one of these values.
items:
type: string
example: []
InputWithVariables:
allOf:
- $ref: '#/components/schemas/Input'
- type: object
properties:
variables:
type: object
description: A map of variable names to their values. Keys in the input `value` that are wrapped in `{curly_braces}` will be replaced with the corresponding variable values.
additionalProperties:
$ref: '#/components/schemas/Input'
PositionalArgument:
description: A positional input is a value inserted verbatim into the command line.
allOf:
- $ref: '#/components/schemas/InputWithVariables'
- type: object
required:
- type
- value_hint
properties:
type:
type: string
enum: [positional]
example: "positional"
value_hint:
type: string
description: An identifier-like hint for the value. This is not part of the command line, but can be used by client configuration and to provide hints to users.
example: file_path
is_repeated:
type: boolean
description: Whether the argument can be repeated multiple times in the command line.
default: false
NamedArgument:
description: A command-line `--flag={value}`.
allOf:
- $ref: '#/components/schemas/InputWithVariables'
- type: object
required:
- type
- name
properties:
type:
type: string
enum: [named]
example: "named"
name:
type: string
description: The flag name, including any leading dashes.
example: "--port"
is_repeated:
type: boolean
description: Whether the argument can be repeated multiple times.
default: false
KeyValueInput:
allOf:
- $ref: '#/components/schemas/InputWithVariables'
- type: object
required:
- name
properties:
name:
type: string
description: Name of the header or environment variable.
example: SOME_VARIABLE
Argument:
anyOf:
- $ref: '#/components/schemas/PositionalArgument'
- $ref: '#/components/schemas/NamedArgument'
Remote:
type: object
required:
- transport_type
- url
properties:
transport_type:
type: string
enum: [streamable, sse]
description: Transport protocol type
example: "sse"
url:
type: string
format: uri
description: Remote server URL
example: "https://mcp-fs.example.com/sse"
headers:
type: array
description: HTTP headers to include
items:
$ref: '#/components/schemas/KeyValueInput'
ServerDetail:
description: Schema for a static representation of an MCP server. Used in various contexts related to discovery, installation, and configuration.
allOf:
- $ref: '#/components/schemas/Server'
- type: object
properties:
packages:
type: array
items:
$ref: '#/components/schemas/Package'
remotes:
type: array
items:
$ref: '#/components/schemas/Remote'