Refs #28. After some thinking, this tries for a 'best of both worlds' approach. Simple arguments can be present essentially as the original spec recommended. As discussed, we don't specify the args for `npx` and friends directly, so a simple package is merely... ```yaml - name: my-api-mcp # ... packages: - type: npm name: "@c4312/my-api-mcp" version: "0.0.1" arguments: # Named inputs in 'arguments' generate a `--name=<value>` - type: named name: "api-key" is_required: true is_secret: true ``` However, I think we need to be able to specify runtime args in some cases, otherwise the registry eventually mirrors all docker configs and options which is not a great situation to be in. So, I suggest a `runtime_args` in the same format. Say I wanted that for npm, I could: ```yaml - name: my-api-mcp # ... packages: - type: npm name: "@c4312/my-api-mcp" version: "0.0.1" runtime_arguments: # Arguments with a pre-specified `value` don't get prompted for input - type: positional value: "--experimental-eventsource" ``` But Docker mounts are... complex, and ultimately we may deal with cases that need multiple inputs in an argument like that. So for that I suggest the third kind of "templated" input that does basic replacements and has `properties` that follow the same general input schema: ```yaml - name: server-filesystem # ... packages: - type: docker name: "mcp/filesystem" version: "0.0.1" runtime_arguments: - type: template description: Mount paths to access. required: true repated: true template: "--mount=type=bind,src={host_path},dst={container_path}" values: host_path: description: Path to access on the local machine required: true format: filepath container_path: description: Path to mount in the container. It should be rooted in `/project` directory. required: true format: string default: "/project" arguments: - type: positional value: "/project" ``` And then client config ends up being pretty simple, for the above case for example a client could have this config: ``` { "filesystem": { "server": "@modelcontextprotocol/servers/src/filesystem@1.0.2", "package": "docker", "settings": { "mount_config": [ { "source_path": "/Users/username/Desktop", "target_path": "/project/desktop" }, { "source_path": "/path/to/other/allowed/dir", "target_path": "//projects/other/allowed/dir,ro" }, ] } } } ``` Which might generate a CLI: ``` docker run \ --mount=type=bind,src=/Users/username/Desktop,dst=/project/desktop \ --mount=type=bind,src=/path/to/other/allowed/dir,dst=/project/other/allowed/dir,ro \ mcp/filesystem:1.0.2 \ /project ``` I think this does a good job of accomplishing the goals we care about: - We get nicely defined inputs that are easy to extend, easy to process, and easy for clients to configure. - Versioning is enforced as we don't require the package to specify the identifier to npx/uvx/etc. - We _usually_ can break away from a dependency on a specific runtime. This promise is broken a bit with `runtime_arguments`, most packages should not need this and those that do are those inherently more tightly coupled to a specific runtime like Docker (e.g. they would be pretty uncommon for Node or Python.) - We don't have a suple complex template system with loops and fallbacks and conditionals, like we would if we tried to have a single template string for a command.
327 lines
9.8 KiB
YAML
327 lines
9.8 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: MCP Server Registry API
|
|
summary: API for discovering and accessing MCP servers metadata
|
|
description: |
|
|
REST API that centralizes metadata about publicly available MCP servers by allowing server creators to submit
|
|
and maintain metadata about their servers in a standardized format. This 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:
|
|
# TODO: Still think a unique name would be better; maybe we open a public discussion on the topic and let people submit ideas?
|
|
- url: https://registry.modelcontextprotocol.io
|
|
description: MCP Server Registry
|
|
# TODO: Webhooks here would be interesting, but out of scope for MVP
|
|
|
|
paths:
|
|
/v0/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 (maximum 5000)
|
|
schema:
|
|
type: integer
|
|
default: 5000
|
|
maximum: 5000
|
|
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'
|
|
/v0/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:
|
|
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
|
|
Repository:
|
|
type: object
|
|
required:
|
|
- url
|
|
- source
|
|
- id
|
|
properties:
|
|
url:
|
|
type: string
|
|
format: uri
|
|
example: "https://github.com/modelcontextprotocol/servers"
|
|
source:
|
|
type: string
|
|
enum: [github, gitlab] # TODO: Add all supported sources as a whitelist
|
|
example: "github"
|
|
id:
|
|
type: string
|
|
example: "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9"
|
|
|
|
Server:
|
|
type: object
|
|
required:
|
|
- id
|
|
- name
|
|
- description
|
|
- repository
|
|
- version_detail
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
example: "a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1"
|
|
name:
|
|
type: string
|
|
example: "@modelcontextprotocol/servers/src/filesystem"
|
|
description:
|
|
type: string
|
|
example: "Node.js server implementing Model Context Protocol (MCP) for filesystem operations."
|
|
repository:
|
|
$ref: '#/components/schemas/Repository'
|
|
version_detail:
|
|
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.
|
|
$schema: "https://json-schema.org/draft/2020-12/schema"
|
|
|
|
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
|
|
enum: [npm, docker, pypi, homebrew]
|
|
example: "npm"
|
|
name:
|
|
type: string
|
|
example: "@modelcontextprotocol/server-filesystem"
|
|
version:
|
|
type: string
|
|
example: "1.0.2"
|
|
runtime_arguments:
|
|
type: array
|
|
description: List of arguments passed to the package's runtime command (such as docker or npx).
|
|
items:
|
|
$ref: '#/components/schemas/Input'
|
|
arguments:
|
|
type: array
|
|
description: List of arguments passed to the package's binary.
|
|
items:
|
|
$ref: '#/components/schemas/Input'
|
|
environment_variables:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/NamedInput'
|
|
|
|
UserInput:
|
|
type: object
|
|
properties:
|
|
description:
|
|
type: string
|
|
is_required:
|
|
type: boolean
|
|
default: false
|
|
is_repeated:
|
|
type: boolean
|
|
description: Whether the input can be repeated multiple times in the command line.
|
|
default: false
|
|
format:
|
|
type: string
|
|
description: Input format. Includes a variety of standardized formats, including `filepath`, which should be interpreted as a file on the user's filesystem.
|
|
enum: [string, number, boolean, array, filepath]
|
|
default: string
|
|
value:
|
|
type: string
|
|
description: The default value for the input. If this is not set, the user will be asked to provide a value.
|
|
is_secret:
|
|
type: boolean
|
|
description: 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.
|
|
|
|
PositionalInput:
|
|
description: A positional input is a value inserted verbatim into the command line.
|
|
allOf:
|
|
- $ref: '#/components/schemas/UserInput'
|
|
- type: object
|
|
required:
|
|
- type
|
|
properties:
|
|
type:
|
|
type: string
|
|
enum: [positional]
|
|
example: "positional"
|
|
|
|
NamedInput:
|
|
description: A command-line `--flag={value}`, named environment variable or header.
|
|
allOf:
|
|
- $ref: '#/components/schemas/UserInput'
|
|
- type: object
|
|
required:
|
|
- type
|
|
- name
|
|
properties:
|
|
type:
|
|
type: string
|
|
enum: [named]
|
|
example: "named"
|
|
name:
|
|
type: string
|
|
example: "--port"
|
|
|
|
TemplateInput:
|
|
- type: object
|
|
required:
|
|
- type
|
|
- template
|
|
- name
|
|
properties:
|
|
type:
|
|
type: string
|
|
enum: [template]
|
|
name:
|
|
type: string
|
|
example: mount_config
|
|
description: The name of the input, which can be used by clients as an identifier to reference the input. It is not present in the generated command line.
|
|
description:
|
|
type: string
|
|
is_required:
|
|
type: boolean
|
|
is_repeated:
|
|
type: boolean
|
|
description: Whether the input can be repeated multiple times in the command line.
|
|
template:
|
|
type: string
|
|
description: The template string that will be used to generate the value. Values wrapped in `{curly_braces}` will be replaced with the corresponding properties.
|
|
example: "--mount=type=bind,src={host_path},dst={container_path}"
|
|
properties:
|
|
type: object
|
|
additionalProperties:
|
|
$ref: '#/components/schemas/UserInput'
|
|
|
|
Input:
|
|
anyOf:
|
|
- $ref: '#/components/schemas/PositionalInput'
|
|
- $ref: '#/components/schemas/NamedInput'
|
|
- $ref: '#/components/schemas/TemplateInput'
|
|
|
|
Remote:
|
|
type: object
|
|
required:
|
|
- transport_type
|
|
- url
|
|
properties:
|
|
transport_type:
|
|
type: string
|
|
enum: [streamable, sse]
|
|
example: "sse"
|
|
url:
|
|
type: string
|
|
format: uri
|
|
example: "https://mcp-fs.example.com/sse"
|
|
headers:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/NamedInput'
|
|
|
|
ServerDetail:
|
|
allOf:
|
|
- $ref: '#/components/schemas/Server'
|
|
- type: object
|
|
properties:
|
|
package_canonical:
|
|
type: string
|
|
enum: [npm, docker, pypi, crates]
|
|
example: "npm"
|
|
packages:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Package'
|
|
remotes:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Remote'
|