A standards-compliant MCP Registry API server for ToolHive
The ToolHive Registry API (thv-registry-api) implements the official Model Context Protocol (MCP) Registry API specification. It provides a standardized REST API for discovering and accessing MCP servers from multiple backend sources.
- Standards-compliant: Implements the official MCP Registry API specification
 - Multiple backends: Supports Kubernetes ConfigMaps and file-based registry data
 - Container-ready: Designed for deployment in Kubernetes clusters
 - Flexible deployment: Works standalone or as part of ToolHive infrastructure
 - Production-ready: Built-in health checks, graceful shutdown, and basic observability
 
- Go 1.23 or later
 - Task for build automation
 - Access to a Kubernetes cluster (for ConfigMap backend)
 
# Build the binary
task buildFrom a Kubernetes ConfigMap:
thv-registry-api serve \
  --from-configmap my-registry-cm \
  --registry-name my-registryFrom a local file:
thv-registry-api serve \
  --from-file /path/to/registry.json \
  --registry-name my-registryThe server starts on port 8080 by default. Use --address :PORT to customize.
The server implements the standard MCP Registry API:
GET /api/v0/servers- List all available MCP serversGET /api/v0/servers/{name}- Get details for a specific serverGET /api/v0/deployed- List deployed server instances (Kubernetes only)GET /api/v0/deployed/{name}- Get deployed instances of a specific server
See the MCP Registry API specification for full API details. Note: The current implementation is not strictly compliant with the standard. The deviations will be fixed in the next iterations.
The thv-registry-api serve command supports the following flags:
| Flag | Description | Required | Default | 
|---|---|---|---|
--address | 
Server listen address | No | :8080 | 
--from-configmap | 
ConfigMap name containing registry data | Yes* | - | 
--from-file | 
Path to registry.json file | Yes* | - | 
--registry-name | 
Registry identifier | Yes | - | 
*One of --from-configmap or --from-file must be specified (mutually exclusive)
Fetches registry data from a Kubernetes ConfigMap. Requires:
- Kubernetes API access (in-cluster or via kubeconfig)
 - ConfigMap with a 
registry.jsonkey containing MCP registry data - Appropriate RBAC permissions to read ConfigMaps
 
Reads registry data from a local file. Useful for:
- Mounting ConfigMaps as volumes in Kubernetes
 - Local development and testing
 - Static registry deployments
 
# Build the binary
task build
# Run linting
task lint
# Fix linting issues automatically
task lint-fix
# Run tests
task test
# Generate mocks
task gen
# Build container image
task build-imagecmd/thv-registry-api/
├── api/v1/              # REST API handlers and routes
├── app/                 # CLI commands and application setup
├── internal/service/    # Business logic and data providers
│   ├── file_provider.go     # File-based registry backend
│   ├── k8s_provider.go      # Kubernetes ConfigMap backend
│   ├── provider.go          # Provider interfaces
│   └── service.go           # Core service implementation
└── main.go              # Application entry point
The server follows a clean architecture pattern:
- API Layer (
api/v1): HTTP handlers implementing the MCP Registry API - Service Layer (
internal/service): Business logic for registry operations - Provider Layer: Pluggable backends for registry data sources
FileRegistryDataProvider: Reads from local filesK8sRegistryDataProvider: Fetches from Kubernetes ConfigMaps
 
The project uses table-driven tests with mocks generated via go.uber.org/mock:
# Generate mocks before testing
task gen
# Run all tests
task testThe Registry API is designed to run as a sidecar container alongside the ToolHive Operator's MCPRegistry controller. Example deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry-api
spec:
  template:
    spec:
      containers:
      - name: registry-api
        image: ghcr.io/stacklok/toolhive/thv-registry-api:latest
        args:
        - serve
        - --from-configmap=my-registry
        - --registry-name=my-registry
        ports:
        - containerPort: 8080# Build the image
task build-image
# Run with file backend
docker run -v /path/to/registry.json:/data/registry.json \
  ghcr.io/stacklok/toolhive/thv-registry-api:latest \
  serve --from-file /data/registry.json --registry-name my-registryThe Registry API server works seamlessly with the ToolHive ecosystem:
- ToolHive Operator: Automatically deployed as part of MCPRegistry resources
 
See the ToolHive documentation for more details.
We welcome contributions! Please see:
- Run 
task lint-fixbefore committing - Ensure tests pass with 
task test - Follow Go standard project layout
 - Use mockgen for test mocks, not hand-written mocks
 - See CLAUDE.md for AI assistant guidance
 
This project is licensed under the Apache 2.0 License.
Part of the ToolHive project - Simplify and secure MCP servers