Skip to content

Commit 5f9a7bf

Browse files
authored
Add JSON schema for the registry (#878)
1 parent 86d6145 commit 5f9a7bf

File tree

7 files changed

+471
-6
lines changed

7 files changed

+471
-6
lines changed

docs/registry/schema.json

Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://raw.githubusercontent.com/stacklok/toolhive/main/docs/registry/schema.json",
4+
"title": "ToolHive MCP Server Registry Schema",
5+
"description": "JSON Schema for the ToolHive MCP server registry. This schema validates the structure and content of registry.json entries for MCP servers. See docs/registry/management.md and docs/registry/heuristics.md for inclusion criteria and management processes.",
6+
"type": "object",
7+
"required": ["last_updated", "servers", "version"],
8+
"properties": {
9+
"last_updated": {
10+
"type": "string",
11+
"description": "Timestamp when the registry was last updated, in RFC3339 format",
12+
"format": "date-time"
13+
},
14+
"servers": {
15+
"type": "object",
16+
"description": "Collection of MCP server entries indexed by server name",
17+
"patternProperties": {
18+
"^[a-z0-9][a-z0-9-]+[a-z0-9]$": {
19+
"$ref": "#/definitions/server"
20+
}
21+
},
22+
"additionalProperties": false
23+
},
24+
"version": {
25+
"type": "string",
26+
"description": "Registry schema version",
27+
"pattern": "^\\d+\\.\\d+\\.\\d+$"
28+
}
29+
},
30+
"definitions": {
31+
"server": {
32+
"type": "object",
33+
"description": "MCP server entry definition",
34+
"required": [
35+
"description",
36+
"image",
37+
"status",
38+
"tier",
39+
"tools",
40+
"transport"
41+
],
42+
"properties": {
43+
"args": {
44+
"type": "array",
45+
"description": "Default command-line arguments passed to the MCP server container",
46+
"items": {
47+
"type": "string"
48+
},
49+
"default": []
50+
},
51+
"description": {
52+
"type": "string",
53+
"description": "Human-readable description of the server's purpose and functionality",
54+
"minLength": 10,
55+
"maxLength": 500
56+
},
57+
"docker_tags": {
58+
"type": "array",
59+
"description": "Available Docker tags for this server image",
60+
"items": {
61+
"type": "string"
62+
},
63+
"uniqueItems": true
64+
},
65+
"env_vars": {
66+
"type": "array",
67+
"description": "Environment variables that can be passed to the server",
68+
"items": {
69+
"$ref": "#/definitions/environment_variable"
70+
}
71+
},
72+
"image": {
73+
"type": "string",
74+
"description": "Container image reference for the MCP server",
75+
"pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?(:[0-9]+)?(/[a-z0-9]([a-z0-9._-]*[a-z0-9])?)*(:([a-zA-Z0-9][a-zA-Z0-9._-]*))?$",
76+
"examples": [
77+
"mcp/fetch:latest",
78+
"ghcr.io/github/github-mcp-server:latest",
79+
"mcr.microsoft.com/playwright/mcp",
80+
"example.com:5000/team/my-app:2.0"
81+
]
82+
},
83+
"metadata": {
84+
"description": "Additional information about the server such as popularity metrics",
85+
"$ref": "#/definitions/metadata"
86+
},
87+
"name": {
88+
"type": "string",
89+
"description": "Identifier for the MCP server, used when referencing the server in commands (auto-generated from the object key)"
90+
},
91+
"permissions": {
92+
"description": "Security profile and access permissions for the server",
93+
"$ref": "#/definitions/permissions"
94+
},
95+
"provenance": {
96+
"description": "Verification and signing metadata",
97+
"$ref": "#/definitions/provenance"
98+
},
99+
"repository_url": {
100+
"type": "string",
101+
"description": "URL of the source code repository for the server",
102+
"format": "uri"
103+
},
104+
"status": {
105+
"type": "string",
106+
"description": "Current status of the server (Active or Deprecated)",
107+
"enum": ["Active", "Deprecated"]
108+
},
109+
"tags": {
110+
"type": "array",
111+
"description": "Categorization tags for search and filtering",
112+
"items": {
113+
"type": "string",
114+
"pattern": "^[a-z0-9][a-z0-9_-]+[a-z0-9]$"
115+
},
116+
"minItems": 1,
117+
"uniqueItems": true
118+
},
119+
"target_port": {
120+
"type": "integer",
121+
"description": "Port for the container to expose (applicable to SSE and Streamable HTTP transports)",
122+
"minimum": 1,
123+
"maximum": 65535
124+
},
125+
"tier": {
126+
"type": "string",
127+
"description": "Tier classification of the server, (Official or Community)",
128+
"enum": ["Official", "Community"]
129+
},
130+
"tools": {
131+
"type": "array",
132+
"description": "List of tool names provided by this MCP server",
133+
"items": {
134+
"type": "string",
135+
"pattern": "^[\\w-]+$"
136+
},
137+
"minItems": 1,
138+
"uniqueItems": true
139+
},
140+
"transport": {
141+
"type": "string",
142+
"description": "Communication transport protocol used by the MCP server",
143+
"enum": ["stdio", "sse", "streamable-http"],
144+
"default": "stdio"
145+
}
146+
},
147+
"additionalProperties": false
148+
},
149+
"environment_variable": {
150+
"type": "object",
151+
"description": "Environment variable definition for MCP server configuration",
152+
"required": ["name", "description", "required"],
153+
"properties": {
154+
"name": {
155+
"type": "string",
156+
"description": "Environment variable name (e.g., API_KEY)",
157+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
158+
},
159+
"description": {
160+
"type": "string",
161+
"description": "Human-readable explanation of the variable's purpose",
162+
"minLength": 5,
163+
"maxLength": 200
164+
},
165+
"required": {
166+
"type": "boolean",
167+
"description": "Whether this environment variable is required for the server to function",
168+
"default": false
169+
},
170+
"secret": {
171+
"type": "boolean",
172+
"description": "Whether this environment variable contains sensitive information that should be stored as a secret",
173+
"default": false
174+
},
175+
"default": {
176+
"type": "string",
177+
"description": "Value to use if the environment variable is not explicitly provided (only used for non-required variables)"
178+
}
179+
},
180+
"additionalProperties": false
181+
},
182+
"permissions": {
183+
"type": "object",
184+
"description": "Security permissions applied to the MCP server",
185+
"required": [],
186+
"properties": {
187+
"network": {
188+
"$ref": "#/definitions/network_permissions"
189+
},
190+
"read": {
191+
"type": "array",
192+
"description": "File system paths the server needs read access to (will be mounted from the host)",
193+
"items": {
194+
"type": "string",
195+
"pattern": "^(/[^/\\0]+)+/?$"
196+
},
197+
"uniqueItems": true,
198+
"default": []
199+
},
200+
"write": {
201+
"type": "array",
202+
"description": "File system paths the server needs write access to (will be mounted from the host)",
203+
"items": {
204+
"type": "string",
205+
"pattern": "^(/[^/\\0]+)+/?$"
206+
},
207+
"uniqueItems": true,
208+
"default": []
209+
}
210+
},
211+
"additionalProperties": false
212+
},
213+
"network_permissions": {
214+
"type": "object",
215+
"description": "Network access permissions for the MCP server",
216+
"required": [],
217+
"properties": {
218+
"outbound": {
219+
"$ref": "#/definitions/outbound_permissions"
220+
}
221+
},
222+
"additionalProperties": false
223+
},
224+
"outbound_permissions": {
225+
"type": "object",
226+
"description": "Outbound network access permissions",
227+
"required": [],
228+
"properties": {
229+
"allow_host": {
230+
"type": "array",
231+
"description": "Allowed hostnames or domain patterns for outbound connections",
232+
"items": {
233+
"type": "string",
234+
"anyOf": [
235+
{
236+
"format": "hostname"
237+
},
238+
{
239+
"pattern": "^\\.[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?$"
240+
}
241+
]
242+
},
243+
"uniqueItems": true,
244+
"default": []
245+
},
246+
"allow_port": {
247+
"type": "array",
248+
"description": "Allowed port numbers for outbound connections",
249+
"items": {
250+
"type": "integer",
251+
"minimum": 1,
252+
"maximum": 65535
253+
},
254+
"uniqueItems": true,
255+
"default": []
256+
},
257+
"allow_transport": {
258+
"type": "array",
259+
"description": "Allowed transport protocols for outbound connections",
260+
"items": {
261+
"type": "string",
262+
"enum": ["tcp", "udp"]
263+
},
264+
"uniqueItems": true,
265+
"default": []
266+
},
267+
"insecure_allow_all": {
268+
"type": "boolean",
269+
"description": "Whether to allow all outbound connections (insecure, use with caution)",
270+
"default": false
271+
}
272+
},
273+
"additionalProperties": false
274+
},
275+
"metadata": {
276+
"type": "object",
277+
"description": "Metadata about the MCP server from external sources",
278+
"properties": {
279+
"last_updated": {
280+
"type": "string",
281+
"description": "Timestamp when the metadata was last updated, in RFC3339 format",
282+
"format": "date-time"
283+
},
284+
"pulls": {
285+
"type": "integer",
286+
"description": "Number of container image pulls",
287+
"minimum": 0
288+
},
289+
"stars": {
290+
"type": "integer",
291+
"description": "Number of repository stars",
292+
"minimum": 0
293+
}
294+
},
295+
"additionalProperties": false
296+
},
297+
"provenance": {
298+
"type": "object",
299+
"description": "Software supply chain provenance information for verified servers",
300+
"properties": {
301+
"cert_issuer": {
302+
"type": "string",
303+
"description": "Certificate issuer for provenance verification",
304+
"format": "uri",
305+
"examples": ["https://token.actions.githubusercontent.com"]
306+
},
307+
"repository_uri": {
308+
"type": "string",
309+
"description": "Repository URI used for provenance verification",
310+
"format": "uri"
311+
},
312+
"repository_ref": {
313+
"type": "string",
314+
"description": "Repository reference used for provenance verification"
315+
},
316+
"runner_environment": {
317+
"type": "string",
318+
"description": "Build environment where the server was built",
319+
"examples": ["github-hosted", "gitlab-hosted", "self-hosted"]
320+
},
321+
"signer_identity": {
322+
"type": "string",
323+
"description": "Identity of the signer for provenance verification"
324+
},
325+
"sigstore_url": {
326+
"type": "string",
327+
"description": "Sigstore TUF repository host for provenance verification",
328+
"format": "hostname",
329+
"default": "tuf-repo-cdn.sigstore.dev",
330+
"examples": ["tuf-repo.github.com", "tuf-repo-cdn.sigstore.dev"]
331+
},
332+
"attestation": {
333+
"description": "Verified attestation information",
334+
"$ref": "#/definitions/verified_attestation"
335+
}
336+
},
337+
"additionalProperties": false
338+
},
339+
"verified_attestation": {
340+
"type": "object",
341+
"description": "Verified attestation information",
342+
"properties": {
343+
"predicate_type": {
344+
"type": "string",
345+
"description": "Type of the attestation predicate",
346+
"format": "uri",
347+
"examples": [
348+
"https://slsa.dev/provenance/v0.2",
349+
"https://slsa.dev/provenance/v1"
350+
]
351+
},
352+
"predicate": {
353+
"description": "Attestation predicate data"
354+
}
355+
},
356+
"additionalProperties": false
357+
}
358+
}
359+
}

0 commit comments

Comments
 (0)