diff --git a/README.md b/README.md index 3c3b0ec..4ef1742 100644 --- a/README.md +++ b/README.md @@ -200,206 +200,7 @@ Publishing requires GitHub OAuth validation: GET /v0/swagger/index.html ``` -The API is documented using Swagger/OpenAPI. This page provides a complete reference of all endpoints with request/response schemas and allows you to test the API directly from your browser. - -### Health Check - -``` -GET /v0/health -``` - -Returns the health status of the service: -```json -{ - "status": "ok" -} -``` - -### Registry Endpoints - -#### List Registry Server Entries - -``` -GET /v0/servers -``` - -Lists MCP registry server entries with pagination support. - -Query parameters: -- `limit`: Maximum number of entries to return (default: 30, max: 100) -- `cursor`: Pagination cursor for retrieving next set of results - -Response example: -```json -{ - "servers": [ - { - "id": "123e4567-e89b-12d3-a456-426614174000", - "name": "Example MCP Server", - "url": "https://example.com/mcp", - "description": "An example MCP server", - "created_at": "2025-05-17T17:34:22.912Z", - "updated_at": "2025-05-17T17:34:22.912Z" - } - ], - "metadata": { - "next_cursor": "123e4567-e89b-12d3-a456-426614174000", - "count": 30 - } -} -``` - -#### Get Server Details - -``` -GET /v0/servers/{id} -``` - -Retrieves detailed information about a specific MCP server entry. - -Path parameters: -- `id`: Unique identifier of the server entry - -Response example: -```json -{ - "id": "01129bff-3d65-4e3d-8e82-6f2f269f818c", - "name": "io.github.gongrzhe/redis-mcp-server", - "description": "A Redis MCP server (pushed to https://github.com/modelcontextprotocol/servers/tree/main/src/redis) implementation for interacting with Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.", - "repository": { - "url": "https://github.com/GongRzhe/REDIS-MCP-Server", - "source": "github", - "id": "907849235" - }, - "version_detail": { - "version": "0.0.1-seed", - "release_date": "2025-05-16T19:13:21Z", - "is_latest": true - }, - "packages": [ - { - "registry_name": "docker", - "name": "@gongrzhe/server-redis-mcp", - "version": "1.0.0", - "package_arguments": [ - { - "description": "Docker image to run", - "is_required": true, - "format": "string", - "value": "mcp/redis", - "default": "mcp/redis", - "type": "positional", - "value_hint": "mcp/redis" - }, - { - "description": "Redis server connection string", - "is_required": true, - "format": "string", - "value": "redis://host.docker.internal:6379", - "default": "redis://host.docker.internal:6379", - "type": "positional", - "value_hint": "host.docker.internal:6379" - } - ] - } - ] -} -``` - -#### Publish a Server Entry - -``` -POST /v0/publish -``` - -Publishes a new MCP server entry to the registry. Authentication is required via Bearer token in the Authorization header. - -Headers: -- `Authorization`: Bearer token for authentication (e.g., `Bearer your_token_here`) -- `Content-Type`: application/json - -Request body example: -```json -{ - "description": "", - "name": "io.github./", - "packages": [ - { - "registry_name": "npm", - "name": "@/", - "version": "0.2.23", - "package_arguments": [ - { - "description": "Specify services and permissions.", - "is_required": true, - "format": "string", - "value": "-s", - "default": "-s", - "type": "positional", - "value_hint": "-s" - } - ], - "environment_variables": [ - { - "description": "API Key to access the server", - "name": "API_KEY" - } - ] - },{ - "registry_name": "docker", - "name": "@/-cli", - "version": "0.123.223", - "runtime_hint": "docker", - "runtime_arguments": [ - { - "description": "Specify services and permissions.", - "is_required": true, - "format": "string", - "value": "--mount", - "default": "--mount", - "type": "positional", - "value_hint": "--mount" - } - ], - "environment_variables": [ - { - "description": "API Key to access the server", - "name": "API_KEY" - } - ] - } - ], - "repository": { - "url": "https://github.com//", - "source": "github" - }, - "version_detail": { - "version": "0.0.1-" - } -} -``` - -Response example: -```json -{ - "message": "Server publication successful", - "id": "1234567890abcdef12345678" -} -``` - -### Ping Endpoint - -``` -GET /v0/ping -``` - -Simple ping endpoint that returns environment configuration information: -```json -{ - "environment": "dev", - "version": "registry-" -} -``` +The API is documented using Swagger/OpenAPI. This page provides a complete reference of all endpoints with request/response schemas and examples, and allows you to test the API directly from your browser. ## Configuration diff --git a/docs/faq.md b/docs/faq.md index 0fd6cc4..57dbd75 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -18,7 +18,7 @@ The MCP Registry is the official centralized metadata repository for publicly-ac 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) +- "Official MCP Registry API": The REST API that lives at `https://registry.modelcontextprotocol.io/api`, with an OpenAPI specification defined at [swagger.yaml](../internal/docs/swagger.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? diff --git a/docs/server-registry-api/README.md b/docs/server-registry-api/README.md index f951351..dfe62c6 100644 --- a/docs/server-registry-api/README.md +++ b/docs/server-registry-api/README.md @@ -10,5 +10,4 @@ The centralized, publicly available catalog ("Official MCP Registry") needs addi 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. \ No newline at end of file +- [swagger.yaml](../../internal/docs/swagger.yaml) - The specification backing the Official MCP Registry; a derivative of the MCP Server Registry API specification. diff --git a/docs/server-registry-api/examples.md b/docs/server-registry-api/examples.md deleted file mode 100644 index 519cddb..0000000 --- a/docs/server-registry-api/examples.md +++ /dev/null @@ -1,293 +0,0 @@ -# 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.", - "status": "active", - "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.", - "status": "active", - "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", - "status": "active", - "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", - "status": "active", - "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", - "status": "active", - "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" - } - ] -} -``` diff --git a/docs/server-registry-api/official-registry-openapi.yaml b/docs/server-registry-api/official-registry-openapi.yaml deleted file mode 100644 index bb08974..0000000 --- a/docs/server-registry-api/official-registry-openapi.yaml +++ /dev/null @@ -1,42 +0,0 @@ -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] diff --git a/docs/server-registry-api/openapi.yaml b/docs/server-registry-api/openapi.yaml index 3a7171f..b4fcb24 100644 --- a/docs/server-registry-api/openapi.yaml +++ b/docs/server-registry-api/openapi.yaml @@ -16,19 +16,18 @@ paths: summary: List MCP servers description: Returns a list of all registered MCP servers parameters: + - name: cursor + in: query + description: Pagination cursor for retrieving next set of results + required: false + schema: + type: string - name: limit in: query - description: Number of results per page + description: Maximum number of items to return + required: false 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 @@ -93,7 +92,6 @@ components: Server: type: object required: - - id - name - description - version_detail @@ -101,13 +99,14 @@ components: id: type: string format: uuid - example: "a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1" + example: "123e4567-e89b-12d3-a456-426614174000" name: type: string - description: Human-readable description of the server's functionality - example: "io.modelcontextprotocol/filesystem" + description: "Reverse DNS name of the MCP server" + example: "io.github.modelcontextprotocol/filesystem" description: type: string + description: "Human-readable description of the server's functionality" example: "Node.js server implementing Model Context Protocol (MCP) for filesystem operations." status: type: string @@ -119,6 +118,12 @@ components: $ref: '#/components/schemas/Repository' version_detail: $ref: '#/components/schemas/VersionDetail' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time VersionDetail: type: object @@ -145,19 +150,21 @@ components: 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 + metadata: + type: object + properties: + next_cursor: + type: string + description: Cursor for next page of results + count: + type: integer + description: Number of items in current page + example: 30 Package: type: object diff --git a/internal/docs/swagger.yaml b/internal/docs/swagger.yaml index 17aea9f..3f8a587 100644 --- a/internal/docs/swagger.yaml +++ b/internal/docs/swagger.yaml @@ -7,7 +7,7 @@ info: servers: - url: / description: Default server - + tags: - name: health description: Health checking operations @@ -98,6 +98,25 @@ paths: $ref: '#/components/schemas/Server' metadata: $ref: '#/components/schemas/PaginationMetadata' + example: + servers: + - id: "123e4567-e89b-12d3-a456-426614174000" + name: "io.github.modelcontextprotocol/filesystem" + description: "Node.js server implementing Model Context Protocol (MCP) for filesystem operations." + status: "active" + 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 + created_at: "2025-05-17T17:34:22.912Z" + updated_at: "2025-05-17T17:34:22.912Z" + metadata: + next_cursor: "123e4567-e89b-12d3-a456-426614174000" + count: 30 '400': description: Invalid cursor or limit parameter '405': @@ -124,6 +143,46 @@ paths: repo_ref: type: string description: Repository reference used for authentication (defaults to server name if not provided) + example: + server_detail: + description: "" + name: "io.github./" + packages: + - registry_name: "npm" + name: "@/" + version: "0.2.23" + package_arguments: + - description: "Specify services and permissions." + is_required: true + format: "string" + value: "-s" + default: "-s" + type: "positional" + value_hint: "-s" + environment_variables: + - description: "API Key to access the server" + name: "API_KEY" + - registry_name: "docker" + name: "@/-cli" + version: "0.123.223" + runtime_hint: "docker" + runtime_arguments: + - description: "Specify services and permissions." + is_required: true + format: "string" + value: "--mount" + default: "--mount" + type: "positional" + value_hint: "--mount" + environment_variables: + - description: "API Key to access the server" + name: "API_KEY" + repository: + url: "https://github.com//" + source: "github" + version_detail: + version: "0.0.1-" + repo_ref: "optional-repository-reference" responses: '201': description: Server published successfully @@ -192,7 +251,41 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Server' + $ref: '#/components/schemas/ServerDetail' + example: + id: "01129bff-3d65-4e3d-8e82-6f2f269f818c" + name: "io.github.gongrzhe/redis-mcp-server" + description: "A Redis MCP server implementation for interacting with Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools." + status: "active" + repository: + url: "https://github.com/GongRzhe/REDIS-MCP-Server" + source: "github" + id: "907849235" + version_detail: + version: "0.0.1-seed" + release_date: "2025-05-16T19:13:21Z" + is_latest: true + created_at: "2025-05-17T17:34:22.912Z" + updated_at: "2025-05-17T17:34:22.912Z" + packages: + - registry_name: "docker" + name: "@gongrzhe/server-redis-mcp" + version: "1.0.0" + package_arguments: + - description: "Docker image to run" + is_required: true + format: "string" + value: "mcp/redis" + default: "mcp/redis" + type: "positional" + value_hint: "mcp/redis" + - description: "Redis server connection string" + is_required: true + format: "string" + value: "redis://host.docker.internal:6379" + default: "redis://host.docker.internal:6379" + type: "positional" + value_hint: "host.docker.internal:6379" '400': description: Invalid ID format '404': @@ -211,6 +304,10 @@ components: schemas: Server: type: object + required: + - name + - description + - version_detail properties: id: type: string @@ -218,14 +315,22 @@ components: example: "123e4567-e89b-12d3-a456-426614174000" name: type: string - example: "Example MCP Server" - url: - type: string - format: uri - example: "https://example.com/mcp" + description: "Server name/identifier" + example: "io.github.modelcontextprotocol/filesystem" description: type: string - example: "An example MCP server" + description: "Human-readable description of the server's functionality" + example: "Node.js server implementing Model Context Protocol (MCP) for filesystem operations." + status: + type: string + enum: [active, deprecated] + default: active + description: "Server lifecycle status. 'deprecated' indicates the server is no longer recommended for new usage." + example: "active" + repository: + $ref: '#/components/schemas/Repository' + version_detail: + $ref: '#/components/schemas/VersionDetail' created_at: type: string format: date-time @@ -243,3 +348,187 @@ components: count: type: integer example: 30 + + 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" + + 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. + + 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' + + 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 + example: "docker" + runtime_arguments: + type: array + description: A list of arguments to be passed to the package's runtime command + 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: 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 + type: string + is_required: + type: boolean + default: false + format: + type: string + enum: [string, number, boolean, filepath] + default: string + value: + type: string + is_secret: + type: boolean + default: false + default: + type: string + choices: + type: array + items: + type: string + + InputWithVariables: + allOf: + - $ref: '#/components/schemas/Input' + - type: object + properties: + variables: + type: object + additionalProperties: + $ref: '#/components/schemas/Input' + + KeyValueInput: + allOf: + - $ref: '#/components/schemas/InputWithVariables' + - type: object + required: + - name + properties: + name: + type: string + description: Name of the header or environment variable + example: "API_KEY" + + Argument: + allOf: + - $ref: '#/components/schemas/InputWithVariables' + - type: object + required: + - type + properties: + type: + type: string + enum: [positional, named] + example: "positional" + name: + type: string + description: The flag name (for named arguments) + example: "--port" + is_repeated: + type: boolean + default: false + value_hint: + type: string + example: "file_path" + + 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'