Create a custom MCP registry
Overview
ToolHive includes a built-in registry of MCP servers with verified configurations that meet a minimum quality standard.
But you can also create your own custom registry to include the MCP servers that are relevant to your organization or specific use cases. This allows you to curate a list of servers that meet your specific needs.
Why create a custom registry?
Creating a custom registry allows you to:
- Curate a list of MCP servers tailored to your organization's needs
- Include private or internal servers not listed in the public registry
- Pre-configure server settings for easier deployment
- Ensure all servers meet your organization's quality and security standards
For production environments, you can also deploy the ToolHive Registry Server to host your registry with authentication, multiple data sources, and automatic synchronization. This tutorial focuses on creating the registry data file itself, which the Registry Server can also consume as a file source.
Create your first custom registry
In this tutorial, you'll create a custom MCP registry for ToolHive and configure it to use your own curated list of MCP servers. By the end, you'll have a working custom registry that you can extend with your organization's specific MCP servers.
What you'll build
You'll create a JSON registry file containing a packaged MCP server and a remote MCP server, configure ToolHive to use your custom registry, and verify it works by listing and running servers from your registry.
Prerequisites
Before you start, make sure you have:
- The ToolHive UI or CLI installed and working on your system
- Basic familiarity with JSON format
- A text editor for creating the registry file
Step 1: Create the registry file
First, create a new directory for your custom registry and navigate to it:
mkdir my-custom-registry
cd my-custom-registry
Create a new file called registry.json and add the following content:
{
"$schema": "https://raw.githubusercontent.com/stacklok/toolhive-core/main/registry/types/data/upstream-registry.schema.json",
"version": "1.0.0",
"meta": {
"last_updated": "2025-08-15T10:00:00Z"
},
"data": {
"servers": [
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "corp.acme/my-fetch",
"title": "Acme Web Fetch",
"description": "A custom web content fetching MCP server for our organization",
"repository": {
"url": "https://github.acme.corp/platform/mcp-fetch",
"source": "github"
},
"version": "1.2.1",
"packages": [
{
"registryType": "oci",
"identifier": "ghcr.io/stackloklabs/gofetch/server:latest",
"transport": {
"type": "streamable-http",
"url": "http://localhost:8080"
}
}
],
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"io.github.stacklok": {
"ghcr.io/stackloklabs/gofetch/server:latest": {
"custom_metadata": {
"author": "Platform Engineering",
"owner": "platform-team@acme.corp",
"internal_ticket": "MCP-042",
"license": "Proprietary"
},
"status": "Active",
"tier": "Community",
"tags": ["web", "fetch", "content"],
"tools": ["fetch"],
"args": [
"--user-agent",
"Mozilla/5.0 (compatible;MyOrgFetchBot/1.0)"
],
"permissions": {
"network": {
"outbound": {
"allow_host": [".example.com", "api.acme.corp"],
"allow_port": [80, 443]
}
}
}
}
}
}
}
},
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.stacklok/toolhive-doc-mcp-remote",
"description": "Search ToolHive docs for help with using and contributing to the project (hosted version)",
"title": "ToolHive Docs (Remote)",
"version": "1.0.0",
"remotes": [
{
"type": "streamable-http",
"url": "https://toolhive-doc-mcp.stacklok.com/mcp"
}
],
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"io.github.stacklok": {
"https://toolhive-doc-mcp.stacklok.com/mcp": {
"custom_metadata": {
"author": "Stacklok",
"homepage": "https://github.com/StacklokLabs/toolhive-doc-mcp",
"license": "Apache-2.0"
},
"metadata": {
"last_updated": "2026-04-13T03:04:50Z",
"stars": 3
},
"overview": "The toolhive-doc-mcp-remote server allows you to search ToolHive documentation for help with using and contributing to the project.",
"status": "Active",
"tags": ["remote", "docs", "search", "stacklok"],
"tier": "Official",
"tools": ["query_docs", "get_chunk"]
}
}
}
}
}
]
}
}
This registry contains two MCP server entries in data.servers:
my-fetch- a packaged server distributed as a container image, with custom arguments and network permissionstoolhive-doc-mcp-remote- a remote server hosted at a URL
Each server entry includes everything ToolHive needs to run it:
- A
titlefield - the display name shown in the UI and CLI listings - A
packagesentry (for packaged servers) or aremotesentry (for remote servers) describing how to reach the server and its transport type - ToolHive-specific metadata (status, tier, tools, permissions, args) in the
_metaextension block, keyed by the publisher namespace and the package identifier or remote URL
Both entries also include a custom_metadata block under _meta. This is a
free-form object you can use to track whatever information matters to your
organization - things like the owning team, an internal ticket reference, a
license, or links to internal documentation. ToolHive preserves these fields so
they're available wherever you consume the registry.
Step 2: Configure ToolHive to use your registry
Configure ToolHive to use your custom registry.
- ToolHive UI
- CLI
- Open the ToolHive application
- Navigate to Settings → Registry
- Select the Local Registry option
- Enter the full path to your
registry.jsonfile (for example:/Users/<YOUR_NAME>/my-custom-registry/registry.json) - Click Save to apply the configuration
The UI will validate the registry file and confirm it's been set successfully.
Set the registry file using the full path:
thv config set-registry /Users/<YOUR_NAME>/my-custom-registry/registry.json
Verify the configuration was applied:
thv config get-registry
You should see the path to your registry file displayed.
Step 3: Test your custom registry
Verify your custom registry is working.
- ToolHive UI
- CLI
- Navigate to the Registry page from the menu bar
- You should see your
my-fetchandtoolhive-doc-mcp-remoteservers displayed - Click on a server to view its details, including description, tools, and configuration options
List the servers in your custom registry:
thv registry list
You should see both my-fetch and toolhive-doc-mcp-remote listed. Get
detailed information about a server:
thv registry info my-fetch
This displays the server's configuration, tools, and permissions as defined in your registry.
Step 4: Run a server from your registry
Finally, run the MCP server from your custom registry.
- ToolHive UI
- CLI
- On the Registry page, click on your
my-fetchserver - Click the Install server button
- Configure any required settings (the defaults from your registry will be pre-populated)
- Click Install server to start the MCP server
- Navigate to the MCP Servers page to see your running server and manage it
The server will appear in your MCP servers list, where you can start, stop, view logs, and manage it like any other MCP server.
thv run my-fetch
The server should start successfully, demonstrating that your custom registry is working correctly.
Step 5: Add more servers (optional)
You can extend your registry by adding more servers to data.servers. For
example, add a second server (note this is just an example, it will not function
if you try to run it):
{
"$schema": "https://raw.githubusercontent.com/stacklok/toolhive-core/main/registry/types/data/upstream-registry.schema.json",
"version": "1.0.0",
"meta": { "last_updated": "2025-08-15T10:00:00Z" },
"data": {
"servers": [
{
// ... existing entries ...
},
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "corp.acme/company-tools",
"title": "Acme Internal Tools",
"description": "Internal company tools and utilities MCP server",
"version": "2.0.3",
"packages": [
{
"registryType": "oci",
"identifier": "registry.acme.corp/mcp/company-tools:v2.0.3",
"transport": { "type": "stdio" },
"environmentVariables": [
{
"name": "COMPANY_API_KEY",
"description": "API key for accessing company internal services",
"isRequired": true,
"isSecret": true
}
]
}
],
"_meta": {
"io.modelcontextprotocol.registry/publisher-provided": {
"io.github.stacklok": {
"registry.acme.corp/mcp/company-tools:v2.0.3": {
"status": "Active",
"tier": "Community",
"tags": ["internal", "company", "tools"],
"tools": [
"get_employee_info",
"create_ticket",
"check_inventory"
]
}
}
}
}
}
]
}
}
After updating the file, the new server is immediately available for ToolHive CLI commands. For the UI, navigate to the registry settings and click Save to see the new server listed.
Production considerations
While this tutorial uses a local file for simplicity, production deployments should harden the registry with:
- Hosting on a secure HTTP server
- Version control to track changes to your registry
- Access controls to prevent unauthorized modifications
- Automated validation to ensure registry entries follow the schema
- Regular updates to add new servers and remove deprecated ones
If you host the registry as a static file, point ToolHive at the URL:
thv config set-registry https://registry.acme.corp/mcp-registry.json
For more capable production deployments, run the ToolHive Registry Server. It consumes the same schema you've built in this tutorial as a file source, and adds built-in authentication, multiple data sources, Kubernetes integration, and automatic synchronization. Follow the Registry Server quickstart to deploy your own.
What you've learned
You've successfully:
- Created a custom MCP registry following the JSON schema
- Configured ToolHive to use your custom registry
- Added both packaged and remote MCP servers with proper metadata and permissions
- Tested your registry by listing and running a server
You can now maintain your own curated list of MCP servers tailored to your organization's needs. The registry can include packaged servers from container registries (public or private) as well as remote servers hosted at a URL.
Next steps
- Deploy a ToolHive Registry Server to host your registry with authentication, multiple data sources, and automatic synchronization
- Explore the full upstream registry schema reference to understand all available configuration options
- Learn about custom permissions for fine-grained security control
- Set up secrets management for servers requiring API keys
Cleanup: Revert to the default registry
If you want to switch back to using ToolHive's built-in registry after completing this tutorial, you can easily revert your configuration.
- ToolHive UI
- CLI
To revert to the default registry through the UI:
- Navigate to Settings → Registry
- Select the Default Registry option
- Click Save to apply the configuration
The UI will confirm that you're now using the built-in ToolHive registry.
To revert to the default registry using the CLI:
thv config unset-registry
Verify that you're back to using the default registry:
thv config get-registry
You should see a message indicating that the built-in registry is being used.
After reverting, all registry commands
(thv registry list,
thv registry info,
thv search) will use ToolHive's built-in
registry instead of your custom one.