Skip to content

Commit 19eaa0e

Browse files
committed
Add custom registry tutorial
Signed-off-by: Dan Barr <[email protected]>
1 parent 7a41825 commit 19eaa0e

File tree

2 files changed

+354
-2
lines changed

2 files changed

+354
-2
lines changed
Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
---
2+
title: Create a custom MCP registry
3+
description: Learn how to create a custom MCP registry for ToolHive.
4+
---
5+
6+
import JSONSchemaViewer from '@theme/JSONSchemaViewer';
7+
import Schema from '@site/static/api-specs/toolhive-registry-schema.json';
8+
import Tabs from '@theme/Tabs';
9+
import TabItem from '@theme/TabItem';
10+
11+
## Overview
12+
13+
ToolHive includes a built-in registry of MCP servers with verified
14+
configurations that meet a
15+
[minimum quality standard](../concepts/registry-criteria.md).
16+
17+
But you can also create your own custom registry to include the MCP servers that
18+
are relevant to your organization or specific use cases. This allows you to
19+
curate a list of servers that meet your specific needs.
20+
21+
## Why create a custom registry?
22+
23+
Creating a custom registry allows you to:
24+
25+
- Curate a list of MCP servers tailored to your organization's needs
26+
- Include private or internal servers not listed in the public registry
27+
- Pre-configure server settings for easier deployment
28+
- Ensure all servers meet your organization's quality and security standards
29+
30+
## Create your first custom registry
31+
32+
In this tutorial, you'll create a custom MCP registry for ToolHive and configure
33+
it to use your own curated list of MCP servers. By the end, you'll have a
34+
working custom registry that you can extend with your organization's specific
35+
MCP servers.
36+
37+
### What you'll build
38+
39+
You'll create a JSON registry file containing a simple MCP server entry,
40+
configure ToolHive to use your custom registry, and verify it works by listing
41+
and running servers from your registry.
42+
43+
### Prerequisites
44+
45+
Before you start, make sure you have:
46+
47+
- The ToolHive UI or CLI installed and working on your system
48+
- [ToolHive UI quickstart](./quickstart-ui.mdx)
49+
- [ToolHive CLI quickstart](./quickstart-cli.mdx)
50+
- Basic familiarity with JSON format
51+
- A text editor for creating the registry file
52+
53+
### Step 1: Create the registry file
54+
55+
First, create a new directory for your custom registry and navigate to it:
56+
57+
```bash
58+
mkdir my-custom-registry
59+
cd my-custom-registry
60+
```
61+
62+
Create a new file called `registry.json` and add the following content:
63+
64+
```json title='registry.json'
65+
{
66+
"$schema": "https://raw.githubusercontent.com/stacklok/toolhive/main/pkg/registry/data/schema.json",
67+
"version": "1.0.0",
68+
"last_updated": "2025-08-15T10:00:00Z",
69+
"servers": {
70+
"my-fetch": {
71+
"description": "A custom web content fetching MCP server for our organization",
72+
"image": "ghcr.io/stackloklabs/gofetch/server:latest",
73+
"status": "Active",
74+
"tier": "Community",
75+
"transport": "streamable-http",
76+
"args": ["--user-agent", "Mozilla/5.0 (compatible;MyOrgFetchBot/1.0)"],
77+
"tags": ["web", "fetch", "content"],
78+
"tools": ["fetch"],
79+
"permissions": {
80+
"network": {
81+
"outbound": {
82+
"allow_host": [".example.com", "api.mycompany.com"],
83+
"allow_port": [80, 443]
84+
}
85+
}
86+
}
87+
}
88+
}
89+
}
90+
```
91+
92+
This registry defines a single MCP server called `my-fetch` with:
93+
94+
- A description explaining its purpose
95+
- The container image to use
96+
- Required metadata like status and tier
97+
- A list of tools it provides
98+
- Command-line arguments for customization
99+
- Network permissions for security
100+
101+
### Step 2: Configure ToolHive to use your registry
102+
103+
Configure ToolHive to use your custom registry.
104+
105+
<Tabs groupId='interface' queryString='interface'>
106+
<TabItem value='ui' label='ToolHive UI' default>
107+
108+
1. Open the ToolHive application
109+
2. Navigate to **Settings****Registry**
110+
3. Select the **Local Registry** option
111+
4. Enter the full path to your `registry.json` file (for example:
112+
`/Users/<YOUR_NAME>/my-custom-registry/registry.json`)
113+
5. Click **Save** to apply the configuration
114+
115+
The UI will validate the registry file and confirm it's been set successfully.
116+
117+
</TabItem>
118+
<TabItem value='cli' label='CLI'>
119+
120+
Set the registry file using the full path:
121+
122+
```bash
123+
thv config set-registry /Users/<YOUR_NAME>/my-custom-registry/registry.json
124+
```
125+
126+
Verify the configuration was applied:
127+
128+
```bash
129+
thv config get-registry
130+
```
131+
132+
You should see the path to your registry file displayed.
133+
134+
</TabItem>
135+
</Tabs>
136+
137+
### Step 3: Test your custom registry
138+
139+
Verify your custom registry is working.
140+
141+
<Tabs groupId='interface' queryString='interface'>
142+
<TabItem value='ui' label='ToolHive UI' default>
143+
144+
1. Navigate to the **Registry** page from the menu bar
145+
2. You should see your `my-fetch` server displayed alongside any other servers
146+
in your custom registry
147+
3. Click on the server to view its details, including description, tools, and
148+
configuration options
149+
150+
</TabItem>
151+
<TabItem value='cli' label='CLI'>
152+
153+
List the servers in your custom registry:
154+
155+
```bash
156+
thv registry list
157+
```
158+
159+
You should see your `my-fetch` server listed. Get detailed information about it:
160+
161+
```bash
162+
thv registry info my-fetch
163+
```
164+
165+
This displays the server's configuration, tools, and permissions as defined in
166+
your registry.
167+
168+
</TabItem>
169+
</Tabs>
170+
171+
### Step 4: Run a server from your registry
172+
173+
Finally, run the MCP server from your custom registry.
174+
175+
<Tabs groupId='interface' queryString='interface'>
176+
<TabItem value='ui' label='ToolHive UI' default>
177+
178+
1. On the **Registry** page, click on your `my-fetch` server
179+
2. Click the **Install server** button
180+
3. Configure any required settings (the defaults from your registry will be
181+
pre-populated)
182+
4. Click **Install server** to start the MCP server
183+
5. Navigate to the **MCP Servers** page to see your running server and manage it
184+
185+
The server will appear in your MCP servers list, where you can start, stop, view
186+
logs, and manage it like any other MCP server.
187+
188+
</TabItem>
189+
<TabItem value='cli' label='CLI'>
190+
191+
```bash
192+
thv run my-fetch
193+
```
194+
195+
The server should start successfully, demonstrating that your custom registry is
196+
working correctly.
197+
198+
</TabItem>
199+
</Tabs>
200+
201+
### Step 5: Add more servers (optional)
202+
203+
You can extend your registry by adding more servers to the `servers` object. For
204+
example, add a second server (note this is just an example, it will not function
205+
if you try to run it):
206+
207+
```json title='registry.json'
208+
{
209+
"$schema": "https://raw.githubusercontent.com/stacklok/toolhive/main/pkg/registry/data/schema.json",
210+
"version": "1.0.0",
211+
"last_updated": "2025-08-15T10:00:00Z",
212+
"servers": {
213+
"my-fetch": {
214+
// ... existing server configuration
215+
},
216+
"company-tools": {
217+
"description": "Internal company tools and utilities MCP server",
218+
"image": "registry.company.com/mcp/company-tools:v1.2.0",
219+
"status": "Active",
220+
"tier": "Community",
221+
"transport": "stdio",
222+
"tools": ["get_employee_info", "create_ticket", "check_inventory"],
223+
"tags": ["internal", "company", "tools"],
224+
"env_vars": [
225+
{
226+
"name": "COMPANY_API_KEY",
227+
"description": "API key for accessing company internal services",
228+
"required": true,
229+
"secret": true
230+
}
231+
]
232+
}
233+
}
234+
}
235+
```
236+
237+
After updating the file, the new server is immediately available for ToolHive
238+
CLI commands. For the UI, navigate to the registry settings and click **Save**
239+
to see the new server listed.
240+
241+
## Production considerations
242+
243+
While this tutorial uses a local file for simplicity, in production environments
244+
you should:
245+
246+
- **Host your registry on a secure HTTP server**
247+
- **Use version control** to track changes to your registry
248+
- **Implement proper access controls** to prevent unauthorized modifications
249+
- **Set up automated validation** to ensure registry entries follow the schema
250+
- **Regularly update** the registry with new servers and remove deprecated ones
251+
252+
For production use, configure ToolHive to use a remote registry URL:
253+
254+
```bash
255+
thv config set-registry https://registry.example.com/mcp-registry.json
256+
```
257+
258+
## What you've learned
259+
260+
You've successfully:
261+
262+
- Created a custom MCP registry following the JSON schema
263+
- Configured ToolHive to use your custom registry
264+
- Added MCP servers with proper metadata and permissions
265+
- Tested your registry by listing and running servers
266+
267+
You can now maintain your own curated list of MCP servers tailored to your
268+
organization's needs. The registry can include both public servers from
269+
container registries and private servers hosted within your organization.
270+
271+
## Next steps
272+
273+
- Explore the full [schema reference](#schema-reference) below to understand all
274+
available configuration options
275+
- Learn about [custom permissions](../guides-cli/custom-permissions.mdx) for
276+
fine-grained security control
277+
- Set up [secrets management](../guides-cli/secrets-management.mdx) for servers
278+
requiring API keys
279+
280+
## Cleanup: Revert to the default registry
281+
282+
If you want to switch back to using ToolHive's built-in registry after
283+
completing this tutorial, you can easily revert your configuration.
284+
285+
<Tabs groupId='interface' queryString='interface'>
286+
<TabItem value='ui' label='ToolHive UI' default>
287+
288+
To revert to the default registry through the UI:
289+
290+
1. Navigate to **Settings****Registry**
291+
2. Select the **Default Registry** option
292+
3. Click **Save** to apply the configuration
293+
294+
The UI will confirm that you're now using the built-in ToolHive registry.
295+
296+
</TabItem>
297+
<TabItem value='cli' label='CLI'>
298+
299+
To revert to the default registry using the CLI:
300+
301+
```bash
302+
thv config unset-registry
303+
```
304+
305+
Verify that you're back to using the default registry:
306+
307+
```bash
308+
thv config get-registry
309+
```
310+
311+
You should see a message indicating that the built-in registry is being used.
312+
313+
</TabItem>
314+
</Tabs>
315+
316+
After reverting, all registry commands
317+
([`thv registry list`](../reference/cli/thv_registry_list.md),
318+
[`thv registry info`](../reference/cli/thv_registry_info.md),
319+
[`thv search`](../reference/cli/thv_search.md)) will use ToolHive's built-in
320+
registry instead of your custom one.
321+
322+
## Schema reference
323+
324+
This is the JSON schema for the ToolHive registry. It defines the structure and
325+
constraints for the registry entries, ensuring that all entries conform to a
326+
consistent format.
327+
328+
To use this schema in your own custom registry file, add a `$schema` property at
329+
the top of your JSON file, like this:
330+
331+
```json
332+
{
333+
"$schema": "https://raw.githubusercontent.com/stacklok/toolhive/main/pkg/registry/data/schema.json",
334+
...
335+
}
336+
```
337+
338+
<JSONSchemaViewer schema={Schema} />

sidebars.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ const sidebars: SidebarsConfig = {
1919

2020
{
2121
type: 'category',
22-
label: 'Tutorials',
22+
label: 'Quickstarts',
2323
description: 'Step-by-step guides to get started with ToolHive',
2424
link: {
2525
type: 'generated-index',
26-
slug: 'toolhive/tutorials',
26+
slug: 'toolhive/quickstart',
2727
description:
2828
'Learn how to use ToolHive with these step-by-step tutorials',
2929
},
@@ -138,6 +138,20 @@ const sidebars: SidebarsConfig = {
138138
],
139139
},
140140

141+
{
142+
type: 'category',
143+
label: 'Tutorials',
144+
description: 'Step-by-step guides to using ToolHive effectively',
145+
link: {
146+
type: 'generated-index',
147+
slug: 'toolhive/tutorials',
148+
description:
149+
'Learn how to use ToolHive with these step-by-step tutorials',
150+
},
151+
collapsed: false,
152+
items: ['toolhive/tutorials/custom-registry'],
153+
},
154+
141155
'toolhive/faq',
142156
],
143157
};

0 commit comments

Comments
 (0)