Skip to content

Commit 59ae557

Browse files
committed
Auto-generate discriminated unions from OpenAPI discriminators
- Add discriminators to OpenAPI spec for transport and Argument types - Enhance schema generation tool to auto-convert discriminators to allOf with if/then blocks - Replace manual discriminated union patterns with auto-generated schema - Ensures schema stays in sync with OpenAPI spec and produces cleaner validation errors
1 parent da2f77c commit 59ae557

File tree

3 files changed

+254
-70
lines changed

3 files changed

+254
-70
lines changed

docs/reference/api/openapi.yaml

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
openapi: 3.1.0
22
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
3-
$id: https://modelcontextprotocol.io/schemas/draft/2025-10-11/server-registry-openapi
3+
$id: https://modelcontextprotocol.io/schemas/draft/2025-09-29/server-registry-openapi
44
info:
55
title: MCP Server Registry API
6-
version: "2025-10-11"
6+
version: "2025-09-29"
77
summary: API for discovering and accessing MCP server metadata
88
description: |
99
Specification for a theoretical REST API that serves up metadata about MCP servers.
1010
license:
1111
name: MIT
1212
identifier: MIT
1313

14-
tags:
15-
- name: servers
16-
description: Operations for discovering and retrieving MCP servers
17-
- name: publish
18-
description: Operations for publishing MCP servers to the registry
19-
2014
paths:
2115
/v0/servers:
2216
get:
23-
tags: [servers]
2417
summary: List MCP servers
2518
description: Returns a list of all registered MCP servers
2619
parameters:
@@ -39,28 +32,6 @@ paths:
3932
required: false
4033
schema:
4134
type: integer
42-
- name: search
43-
in: query
44-
description: Search servers by name (substring match)
45-
required: false
46-
schema:
47-
type: string
48-
example: "filesystem"
49-
- name: updated_since
50-
in: query
51-
description: Filter servers updated since timestamp (RFC3339 datetime)
52-
required: false
53-
schema:
54-
type: string
55-
format: date-time
56-
example: "2025-08-07T13:15:04.280Z"
57-
- name: version
58-
in: query
59-
description: Filter by version ('latest' for latest version, or an exact version like '1.2.3')
60-
required: false
61-
schema:
62-
type: string
63-
example: "1.2.3"
6435
responses:
6536
'200':
6637
description: A list of MCP servers
@@ -70,7 +41,6 @@ paths:
7041
$ref: '#/components/schemas/ServerList'
7142
/v0/servers/{serverName}/versions:
7243
get:
73-
tags: [servers]
7444
summary: List all versions of an MCP server
7545
description: Returns all available versions for a specific MCP server, ordered by publication date (newest first)
7646
parameters:
@@ -100,7 +70,6 @@ paths:
10070
example: "Server not found"
10171
/v0/servers/{serverName}/versions/{version}:
10272
get:
103-
tags: [servers]
10473
summary: Get specific MCP server version
10574
description: Returns detailed information about a specific version of an MCP server. Use the special version `latest` to get the latest version.
10675
parameters:
@@ -137,13 +106,12 @@ paths:
137106
example: "Server not found"
138107
/v0/publish:
139108
post:
140-
tags: [publish]
141109
summary: Publish MCP server (Optional)
142110
description: |
143111
Publish a new MCP server to the registry or update an existing one.
144-
112+
145113
**Note**: This endpoint is optional for registry implementations. Read-only registries may not provide this functionality.
146-
114+
147115
Authentication mechanism is registry-specific and may vary between implementations.
148116
security:
149117
- bearerAuth: []
@@ -347,11 +315,17 @@ components:
347315
description: A hint to help clients determine the appropriate runtime for the package. This field should be provided when `runtimeArguments` are present.
348316
examples: [npx, uvx, docker, dnx]
349317
transport:
350-
anyOf:
318+
description: Transport protocol configuration for the package
319+
discriminator:
320+
propertyName: type
321+
mapping:
322+
stdio: '#/components/schemas/StdioTransport'
323+
streamable-http: '#/components/schemas/StreamableHttpTransport'
324+
sse: '#/components/schemas/SseTransport'
325+
oneOf:
351326
- $ref: '#/components/schemas/StdioTransport'
352327
- $ref: '#/components/schemas/StreamableHttpTransport'
353328
- $ref: '#/components/schemas/SseTransport'
354-
description: Transport protocol configuration for the package
355329
runtimeArguments:
356330
type: array
357331
description: A list of arguments to be passed to the package's runtime command (such as docker or npx). The `runtimeHint` field should be provided when `runtimeArguments` are present.
@@ -478,7 +452,12 @@ components:
478452

479453
Argument:
480454
description: "Warning: Arguments construct command-line parameters that may contain user-provided input. This creates potential command injection risks if clients execute commands in a shell environment. For example, a malicious argument value like ';rm -rf ~/Development' could execute dangerous commands. Clients should prefer non-shell execution methods (e.g., posix_spawn) when possible to eliminate injection risks entirely. Where not possible, clients should obtain consent from users or agents to run the resolved command before execution."
481-
anyOf:
455+
discriminator:
456+
propertyName: type
457+
mapping:
458+
positional: '#/components/schemas/PositionalArgument'
459+
named: '#/components/schemas/NamedArgument'
460+
oneOf:
482461
- $ref: '#/components/schemas/PositionalArgument'
483462
- $ref: '#/components/schemas/NamedArgument'
484463

@@ -616,15 +595,20 @@ components:
616595
type: string
617596
format: uri
618597
description: JSON Schema URI for this server.json format
619-
example: "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json"
598+
example: "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json"
620599
packages:
621600
type: array
622601
items:
623602
$ref: '#/components/schemas/Package'
624603
remotes:
625604
type: array
626605
items:
627-
anyOf:
606+
discriminator:
607+
propertyName: type
608+
mapping:
609+
streamable-http: '#/components/schemas/StreamableHttpTransport'
610+
sse: '#/components/schemas/SseTransport'
611+
oneOf:
628612
- $ref: '#/components/schemas/StreamableHttpTransport'
629613
- $ref: '#/components/schemas/SseTransport'
630614
_meta:

docs/reference/server-json/server.schema.json

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,50 @@
11
{
22
"$comment": "This file is auto-generated from docs/reference/api/openapi.yaml. Do not edit manually. Run 'make generate-schema' to update.",
3-
"$id": "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json",
3+
"$id": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
44
"$ref": "#/definitions/ServerDetail",
55
"$schema": "http://json-schema.org/draft-07/schema#",
66
"definitions": {
77
"Argument": {
8-
"anyOf": [
8+
"allOf": [
99
{
10-
"$ref": "#/definitions/PositionalArgument"
10+
"if": {
11+
"properties": {
12+
"type": {
13+
"const": "positional"
14+
}
15+
}
16+
},
17+
"then": {
18+
"$ref": "#/definitions/PositionalArgument"
19+
}
1120
},
1221
{
13-
"$ref": "#/definitions/NamedArgument"
22+
"if": {
23+
"properties": {
24+
"type": {
25+
"const": "named"
26+
}
27+
}
28+
},
29+
"then": {
30+
"$ref": "#/definitions/NamedArgument"
31+
}
32+
}
33+
],
34+
"description": "Warning: Arguments construct command-line parameters that may contain user-provided input. This creates potential command injection risks if clients execute commands in a shell environment. For example, a malicious argument value like ';rm -rf ~/Development' could execute dangerous commands. Clients should prefer non-shell execution methods (e.g., posix_spawn) when possible to eliminate injection risks entirely. Where not possible, clients should obtain consent from users or agents to run the resolved command before execution.",
35+
"properties": {
36+
"type": {
37+
"enum": [
38+
"positional",
39+
"named"
40+
],
41+
"type": "string"
1442
}
43+
},
44+
"required": [
45+
"type"
1546
],
16-
"description": "Warning: Arguments construct command-line parameters that may contain user-provided input. This creates potential command injection risks if clients execute commands in a shell environment. For example, a malicious argument value like ';rm -rf ~/Development' could execute dangerous commands. Clients should prefer non-shell execution methods (e.g., posix_spawn) when possible to eliminate injection risks entirely. Where not possible, clients should obtain consent from users or agents to run the resolved command before execution."
47+
"type": "object"
1748
},
1849
"Icon": {
1950
"description": "An optionally-sized icon that can be displayed in a user interface.",
@@ -262,18 +293,59 @@
262293
"type": "string"
263294
},
264295
"transport": {
265-
"anyOf": [
296+
"allOf": [
266297
{
267-
"$ref": "#/definitions/StdioTransport"
298+
"if": {
299+
"properties": {
300+
"type": {
301+
"const": "stdio"
302+
}
303+
}
304+
},
305+
"then": {
306+
"$ref": "#/definitions/StdioTransport"
307+
}
268308
},
269309
{
270-
"$ref": "#/definitions/StreamableHttpTransport"
310+
"if": {
311+
"properties": {
312+
"type": {
313+
"const": "streamable-http"
314+
}
315+
}
316+
},
317+
"then": {
318+
"$ref": "#/definitions/StreamableHttpTransport"
319+
}
271320
},
272321
{
273-
"$ref": "#/definitions/SseTransport"
322+
"if": {
323+
"properties": {
324+
"type": {
325+
"const": "sse"
326+
}
327+
}
328+
},
329+
"then": {
330+
"$ref": "#/definitions/SseTransport"
331+
}
274332
}
275333
],
276-
"description": "Transport protocol configuration for the package"
334+
"description": "Transport protocol configuration for the package",
335+
"properties": {
336+
"type": {
337+
"enum": [
338+
"stdio",
339+
"streamable-http",
340+
"sse"
341+
],
342+
"type": "string"
343+
}
344+
},
345+
"required": [
346+
"type"
347+
],
348+
"type": "object"
277349
},
278350
"version": {
279351
"description": "Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '\u003e=1.2.3', '1.x', '1.*').",
@@ -373,7 +445,7 @@
373445
"properties": {
374446
"$schema": {
375447
"description": "JSON Schema URI for this server.json format",
376-
"example": "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json",
448+
"example": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
377449
"format": "uri",
378450
"type": "string"
379451
},
@@ -427,14 +499,45 @@
427499
},
428500
"remotes": {
429501
"items": {
430-
"anyOf": [
502+
"allOf": [
431503
{
432-
"$ref": "#/definitions/StreamableHttpTransport"
504+
"if": {
505+
"properties": {
506+
"type": {
507+
"const": "streamable-http"
508+
}
509+
}
510+
},
511+
"then": {
512+
"$ref": "#/definitions/StreamableHttpTransport"
513+
}
433514
},
434515
{
435-
"$ref": "#/definitions/SseTransport"
516+
"if": {
517+
"properties": {
518+
"type": {
519+
"const": "sse"
520+
}
521+
}
522+
},
523+
"then": {
524+
"$ref": "#/definitions/SseTransport"
525+
}
436526
}
437-
]
527+
],
528+
"properties": {
529+
"type": {
530+
"enum": [
531+
"streamable-http",
532+
"sse"
533+
],
534+
"type": "string"
535+
}
536+
},
537+
"required": [
538+
"type"
539+
],
540+
"type": "object"
438541
},
439542
"type": "array"
440543
},

0 commit comments

Comments
 (0)