@@ -80,11 +80,50 @@ Create a new file called `registry.json` and add the following content:
8080 }
8181 }
8282 }
83- }
83+ },
84+ "groups" : [
85+ {
86+ "name" : " dev-toolkit" ,
87+ "description" : " Essential MCP servers for development workflows" ,
88+ "servers" : {
89+ "fetch-tool" : {
90+ "description" : " A web content fetching MCP server for development" ,
91+ "image" : " ghcr.io/stackloklabs/gofetch/server:latest" ,
92+ "status" : " Active" ,
93+ "tier" : " Community" ,
94+ "transport" : " streamable-http" ,
95+ "args" : [" --user-agent" , " Mozilla/5.0 (compatible;DevBot/1.0)" ],
96+ "tags" : [" web" , " fetch" , " dev" ],
97+ "tools" : [" fetch" ],
98+ "permissions" : {
99+ "network" : {
100+ "outbound" : {
101+ "allow_host" : [" .github.com" , " .stackoverflow.com" ],
102+ "allow_port" : [80 , 443 ]
103+ }
104+ }
105+ }
106+ }
107+ }
108+ }
109+ ]
84110}
85111```
86112
87- This registry defines a single MCP server called ` my-fetch ` with:
113+ This registry defines:
114+
115+ - A single MCP server called ` my-fetch ` in the top-level ` servers ` section
116+ - A group called ` dev-toolkit ` with its own independent server called
117+ ` fetch-tool `
118+
119+ Groups are optional - you can omit the entire ` groups ` section if you only need
120+ individual servers. Groups are independent entities that contain their own
121+ complete server definitions. The ` dev-toolkit ` group includes a ` fetch-tool `
122+ server that's similar to the top-level ` my-fetch ` server but with different
123+ configuration (different user agent, different allowed hosts for development
124+ purposes).
125+
126+ Each server definition includes:
88127
89128- A description explaining its purpose
90129- The container image to use
@@ -93,6 +132,9 @@ This registry defines a single MCP server called `my-fetch` with:
93132- Command-line arguments for customization
94133- Network permissions for security
95134
135+ Groups provide an organizational layer that allows you to run multiple related
136+ servers together as a cohesive unit.
137+
96138### Step 2: Configure ToolHive to use your registry
97139
98140Configure ToolHive to use your custom registry.
@@ -190,6 +232,15 @@ thv run my-fetch
190232The server should start successfully, demonstrating that your custom registry is
191233working correctly.
192234
235+ You can also run the entire group:
236+
237+ ``` bash
238+ thv group run dev-toolkit
239+ ```
240+
241+ This starts all servers in the ` dev-toolkit ` group (in this case, just the
242+ ` fetch-tool ` server).
243+
193244</TabItem >
194245</Tabs >
195246
@@ -233,6 +284,156 @@ After updating the file, the new server is immediately available for ToolHive
233284CLI commands. For the UI, navigate to the registry settings and click ** Save**
234285to see the new server listed.
235286
287+ ## Working with groups
288+
289+ Groups allow you to organize related MCP servers and run them together as a
290+ cohesive unit. This is particularly useful for:
291+
292+ - ** Team-specific toolkits** : Create groups for different teams (frontend,
293+ backend, DevOps)
294+ - ** Workflow-based organization** : Group servers needed for specific workflows
295+ (testing, deployment, monitoring)
296+ - ** Environment-specific configurations** : Different server configurations for
297+ development, staging, and production
298+
299+ ### Group structure
300+
301+ Groups in your registry have the following structure:
302+
303+ ``` json
304+ {
305+ "groups" : [
306+ {
307+ "name" : " group-name" ,
308+ "description" : " Description of what this group provides" ,
309+ "servers" : {
310+ "server-name" : {
311+ // Complete server definition
312+ }
313+ },
314+ "remote_servers" : {
315+ "remote-server-name" : {
316+ // Complete remote server definition
317+ }
318+ }
319+ }
320+ ]
321+ }
322+ ```
323+
324+ ### Key characteristics of groups
325+
326+ - ** Independent server definitions** : Each group contains complete server
327+ configurations, not references to top-level servers
328+ - ** Self-contained** : Groups can define servers with the same names as top-level
329+ servers but with different configurations
330+ - ** Organizational only** : Groups provide organization but don't affect server
331+ runtime behavior
332+ - ** Flexible membership** : Servers can appear in multiple groups with different
333+ configurations
334+
335+ ### Example: Multi-group registry
336+
337+ Here's a more comprehensive example showing how groups can organize servers for
338+ different purposes:
339+
340+ ``` json title='advanced-registry.json'
341+ {
342+ "$schema" : " https://raw.githubusercontent.com/stacklok/toolhive/main/pkg/registry/data/schema.json" ,
343+ "version" : " 1.0.0" ,
344+ "last_updated" : " 2025-08-15T10:00:00Z" ,
345+ "servers" : {
346+ "production-fetch" : {
347+ "description" : " Production web content fetching server" ,
348+ "image" : " ghcr.io/stackloklabs/gofetch/server:latest" ,
349+ "status" : " Active" ,
350+ "tier" : " Community" ,
351+ "transport" : " streamable-http" ,
352+ "permissions" : {
353+ "network" : {
354+ "outbound" : {
355+ "allow_host" : [" .company.com" ],
356+ "allow_port" : [443 ]
357+ }
358+ }
359+ }
360+ }
361+ },
362+ "groups" : [
363+ {
364+ "name" : " frontend-dev" ,
365+ "description" : " Tools for frontend development team" ,
366+ "servers" : {
367+ "dev-fetch" : {
368+ "description" : " Development web content fetching with broader access" ,
369+ "image" : " ghcr.io/stackloklabs/gofetch/server:latest" ,
370+ "status" : " Active" ,
371+ "tier" : " Community" ,
372+ "transport" : " streamable-http" ,
373+ "permissions" : {
374+ "network" : {
375+ "outbound" : {
376+ "allow_host" : [" *" ],
377+ "allow_port" : [80 , 443 ]
378+ }
379+ }
380+ }
381+ }
382+ }
383+ },
384+ {
385+ "name" : " testing-suite" ,
386+ "description" : " Servers needed for automated testing workflows" ,
387+ "servers" : {
388+ "test-fetch" : {
389+ "description" : " Restricted fetch server for testing" ,
390+ "image" : " ghcr.io/stackloklabs/gofetch/server:latest" ,
391+ "status" : " Active" ,
392+ "tier" : " Community" ,
393+ "transport" : " streamable-http" ,
394+ "args" : [" --timeout" , " 5s" ],
395+ "permissions" : {
396+ "network" : {
397+ "outbound" : {
398+ "allow_host" : [" test.example.com" ],
399+ "allow_port" : [443 ]
400+ }
401+ }
402+ }
403+ }
404+ }
405+ }
406+ ]
407+ }
408+ ```
409+
410+ This registry provides:
411+
412+ - A production-ready ` production-fetch ` server at the top level
413+ - A ` frontend-dev ` group with a more permissive ` dev-fetch ` server
414+ - A ` testing-suite ` group with a restricted ` test-fetch ` server
415+
416+ Each server has the same base image but different configurations appropriate for
417+ its use case.
418+
419+ ### Running groups
420+
421+ You can run entire groups using the group command:
422+
423+ ``` bash
424+ # Run all servers in the frontend-dev group
425+ thv group run frontend-dev
426+
427+ # Run all servers in the testing-suite group
428+ thv group run testing-suite
429+
430+ # You can also pass environment variables and secrets to group runs
431+ thv group run frontend-dev --env DEV_MODE=true --secret API_KEY=my-secret
432+ ```
433+
434+ Groups provide a convenient way to start multiple related servers with a single
435+ command.
436+
236437## Production considerations
237438
238439While this tutorial uses a local file for simplicity, in production environments
@@ -257,11 +458,13 @@ You've successfully:
257458- Created a custom MCP registry following the JSON schema
258459- Configured ToolHive to use your custom registry
259460- Added MCP servers with proper metadata and permissions
260- - Tested your registry by listing and running servers
461+ - Created groups to organize related servers
462+ - Tested your registry by listing and running both individual servers and groups
261463
262- You can now maintain your own curated list of MCP servers tailored to your
263- organization's needs. The registry can include both public servers from
264- container registries and private servers hosted within your organization.
464+ You can now maintain your own curated list of MCP servers and groups tailored to
465+ your organization's needs. The registry can include both public servers from
466+ container registries and private servers hosted within your organization,
467+ organized into logical groups for different teams or workflows.
265468
266469## Next steps
267470
0 commit comments