|
| 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} /> |
0 commit comments