Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
ToolHive
https://github.com/stacklok/toolhive
Admin
ToolHive simplifies and secures the deployment and management of Model Context Protocol (MCP)
...
Tokens:
218,757
Snippets:
1,783
Trust Score:
9.2
Update:
2 months ago
Context
Skills
Chat
Benchmark
73.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# ToolHive ToolHive is a lightweight, secure manager for MCP (Model Context Protocol) servers that provides container-based isolation for running MCP servers safely. It acts as a thin client for Docker/Podman/Colima Unix socket APIs, enabling instant deployment of MCP servers with security guardrails. ToolHive supports multiple deployment modes: a CLI (`thv`) for local development, a REST API for programmatic integration, and a Kubernetes Operator for enterprise-scale deployments. The platform includes a Gateway for secure endpoint orchestration, a Registry Server for curating trusted MCP server catalogs, a Runtime for deploying and managing servers across local and cloud environments, and a Portal for simplified cross-platform access. ToolHive integrates with popular AI clients like Claude Desktop, Cursor, VS Code, and GitHub Copilot, providing centralized control over security policies, authentication, authorization, and auditing through OIDC/OAuth SSO support and Cedar-based policy language. ## CLI Commands ### Run an MCP Server The `run` command starts MCP servers from the registry, container images, protocol schemes (uvx, npx, go), or remote URLs with full lifecycle management. ```bash # Run a server from the registry thv run filesystem # Run with custom arguments thv run github -- --toolsets repos # Run from a container image thv run ghcr.io/github/github-mcp-server # Run using protocol schemes (Python with uv) thv run uvx://mcp-server-git # Run using npx (Node.js) thv run npx://@modelcontextprotocol/server-everything # Run with custom name and group thv run filesystem --name my-fs --group production # Run a remote MCP server with OAuth authentication thv run https://mcp.example.com/api --name remote-server \ --remote-auth \ --remote-auth-client-id <oauth-client-id> \ --remote-auth-client-secret <oauth-client-secret> # Run from an exported configuration file thv run --from-config ./my-server-config.json # Run with specific transport and network mode thv run ghcr.io/example/mcp-server --transport sse --network host ``` ### List and Manage Workloads The `list`, `stop`, `restart`, and `rm` commands manage the lifecycle of running MCP server workloads. ```bash # List all running workloads thv list # List all workloads including stopped ones thv list --all # List workloads in a specific group thv list --group production # Output as JSON thv list --format json # Stop a specific workload thv stop my-server # Stop all workloads thv stop --all # Stop all workloads in a group thv stop --group production # Restart workloads thv restart my-server thv restart --all # Remove a workload thv rm my-server # Remove all workloads thv rm --all # Force remove without confirmation thv rm my-server --force ``` ### View Logs The `logs` command retrieves container logs for debugging MCP servers. ```bash # View logs for a workload thv logs my-server # Follow logs in real-time thv logs my-server --follow # View last N lines thv logs my-server --tail 100 # View proxy logs (for proxy-mode servers) thv logs my-server --proxy ``` ### Manage Secrets The `secret` command manages encrypted secrets for MCP server environment variables with support for multiple backends. ```bash # Set up encrypted secrets provider thv secret setup encrypted # Set up 1Password secrets provider thv secret setup 1password --vault "MCP Secrets" # Create a new secret thv secret set GITHUB_TOKEN ghp_xxxxxxxxxxxx # List all secrets (names only, not values) thv secret list # Delete a secret thv secret delete GITHUB_TOKEN # Use secrets in a server run thv run github --secret GITHUB_TOKEN ``` ### Manage Groups The `group` command organizes MCP servers into logical groups for easier management and client configuration. ```bash # Create a new group thv group create production # List all groups thv group list # Delete a group thv group delete staging # Add a workload to a group during run thv run filesystem --group production ``` ### Export Configuration The `export` command exports a workload's configuration for backup or migration. ```bash # Export workload configuration to stdout thv export my-server # Export to a file thv export my-server > my-server-config.json # Export as JSON format thv export my-server --format json ``` ### Start API Server The `serve` command starts the ToolHive REST API server for programmatic access. ```bash # Start API server on default port thv serve # Start on specific address thv serve --address 0.0.0.0:8080 # Start with Unix socket thv serve --socket /var/run/toolhive.sock # Enable debug mode and API documentation thv serve --debug --docs # Start with OIDC authentication thv serve --oidc-issuer https://auth.example.com \ --oidc-audience toolhive-api ``` ## REST API ### Workloads API The Workloads API manages MCP server lifecycle through RESTful endpoints at `/api/v1beta/workloads`. ```bash # List all workloads curl -X GET "http://localhost:8080/api/v1beta/workloads" # List all workloads including stopped curl -X GET "http://localhost:8080/api/v1beta/workloads?all=true" # Filter by group curl -X GET "http://localhost:8080/api/v1beta/workloads?group=production" # Expected response: # { # "workloads": [ # {"name": "filesystem", "status": "running", "port": 8081, "image": "..."}, # {"name": "github", "status": "running", "port": 8082, "image": "..."} # ] # } # Create a new workload from registry curl -X POST "http://localhost:8080/api/v1beta/workloads" \ -H "Content-Type: application/json" \ -d '{ "name": "my-filesystem", "image": "ghcr.io/stackloklabs/mcp-filesystem", "transport": "stdio", "group": "default", "env": [{"name": "READ_ONLY", "value": "true"}], "args": ["/data"] }' # Response: {"name": "my-filesystem", "port": 8083} # Create a remote proxy workload curl -X POST "http://localhost:8080/api/v1beta/workloads" \ -H "Content-Type: application/json" \ -d '{ "name": "remote-mcp", "url": "https://mcp.example.com/api" }' # Get workload details curl -X GET "http://localhost:8080/api/v1beta/workloads/my-filesystem" # Get workload status curl -X GET "http://localhost:8080/api/v1beta/workloads/my-filesystem/status" # Response: {"status": "running"} # Stop a workload (async, returns 202) curl -X POST "http://localhost:8080/api/v1beta/workloads/my-filesystem/stop" # Restart a workload (async, returns 202) curl -X POST "http://localhost:8080/api/v1beta/workloads/my-filesystem/restart" # Delete a workload (async, returns 202) curl -X DELETE "http://localhost:8080/api/v1beta/workloads/my-filesystem" # Bulk stop workloads by group curl -X POST "http://localhost:8080/api/v1beta/workloads/stop" \ -H "Content-Type: application/json" \ -d '{"group": "production"}' # Bulk delete by names curl -X POST "http://localhost:8080/api/v1beta/workloads/delete" \ -H "Content-Type: application/json" \ -d '{"names": ["server1", "server2"]}' # Get workload logs curl -X GET "http://localhost:8080/api/v1beta/workloads/my-filesystem/logs" # Export workload configuration curl -X GET "http://localhost:8080/api/v1beta/workloads/my-filesystem/export" ``` ### Registry API The Registry API manages the MCP server registry at `/api/v1beta/registry` for discovering and configuring available servers. ```bash # List registries curl -X GET "http://localhost:8080/api/v1beta/registry" # Response: # { # "registries": [{ # "name": "default", # "version": "1.0.0", # "last_updated": "2025-01-15T10:00:00Z", # "server_count": 50, # "type": "url", # "source": "https://registry.toolhive.dev/registry.json" # }] # } # Get registry details curl -X GET "http://localhost:8080/api/v1beta/registry/default" # Update registry source to a URL curl -X PUT "http://localhost:8080/api/v1beta/registry/default" \ -H "Content-Type: application/json" \ -d '{"url": "https://custom.registry.example.com/registry.json"}' # Update registry to use MCP Registry API curl -X PUT "http://localhost:8080/api/v1beta/registry/default" \ -H "Content-Type: application/json" \ -d '{"api_url": "https://api.registry.example.com/v1"}' # Update registry to local file curl -X PUT "http://localhost:8080/api/v1beta/registry/default" \ -H "Content-Type: application/json" \ -d '{"local_path": "/path/to/custom-registry.json"}' # Reset to built-in registry (unset custom config) curl -X PUT "http://localhost:8080/api/v1beta/registry/default" \ -H "Content-Type: application/json" \ -d '{}' # List servers in registry curl -X GET "http://localhost:8080/api/v1beta/registry/default/servers" # Response includes both container and remote servers: # { # "servers": [{"name": "filesystem", "image": "...", "transport": "stdio"}], # "remote_servers": [{"name": "github-remote", "url": "https://..."}] # } # Get specific server details curl -X GET "http://localhost:8080/api/v1beta/registry/default/servers/filesystem" ``` ### Groups API The Groups API manages logical groupings of MCP servers at `/api/v1beta/groups`. ```bash # List all groups curl -X GET "http://localhost:8080/api/v1beta/groups" # Response: {"groups": [{"name": "default"}, {"name": "production"}]} # Create a new group curl -X POST "http://localhost:8080/api/v1beta/groups" \ -H "Content-Type: application/json" \ -d '{"name": "staging"}' # Response: {"name": "staging"} # Get group details curl -X GET "http://localhost:8080/api/v1beta/groups/production" # Delete a group curl -X DELETE "http://localhost:8080/api/v1beta/groups/staging" ``` ### Clients API The Clients API registers and manages AI client configurations at `/api/v1beta/clients`. ```bash # List registered clients curl -X GET "http://localhost:8080/api/v1beta/clients" # Register a client to receive MCP server configs curl -X POST "http://localhost:8080/api/v1beta/clients" \ -H "Content-Type: application/json" \ -d '{"name": "claude-desktop", "groups": ["production"]}' # Bulk register multiple clients curl -X POST "http://localhost:8080/api/v1beta/clients/register" \ -H "Content-Type: application/json" \ -d '{ "clients": [ {"name": "cursor"}, {"name": "vscode-server"} ], "groups": ["default", "development"] }' # Unregister a client curl -X DELETE "http://localhost:8080/api/v1beta/clients/claude-desktop" # Unregister client from specific group curl -X DELETE "http://localhost:8080/api/v1beta/clients/cursor/groups/staging" ``` ### Secrets API The Secrets API manages secure credential storage at `/api/v1beta/secrets`. ```bash # Setup encrypted secrets provider curl -X POST "http://localhost:8080/api/v1beta/secrets" \ -H "Content-Type: application/json" \ -d '{"provider_type": "encrypted"}' # Setup 1Password secrets provider curl -X POST "http://localhost:8080/api/v1beta/secrets" \ -H "Content-Type: application/json" \ -d '{ "provider_type": "1password", "config": {"vault": "MCP Secrets"} }' # Get current secrets provider info curl -X GET "http://localhost:8080/api/v1beta/secrets/default" # List secret keys (values not returned) curl -X GET "http://localhost:8080/api/v1beta/secrets/default/keys" # Create a secret curl -X POST "http://localhost:8080/api/v1beta/secrets/default/keys" \ -H "Content-Type: application/json" \ -d '{"key": "GITHUB_TOKEN", "value": "ghp_xxxxxxxxxxxx"}' # Update a secret curl -X PUT "http://localhost:8080/api/v1beta/secrets/default/keys/GITHUB_TOKEN" \ -H "Content-Type: application/json" \ -d '{"value": "ghp_new_token_value"}' # Delete a secret curl -X DELETE "http://localhost:8080/api/v1beta/secrets/default/keys/GITHUB_TOKEN" ``` ### Health and Version API Health check and version information endpoints for monitoring and diagnostics. ```bash # Health check curl -X GET "http://localhost:8080/health" # Response: {"status": "healthy", "container_runtime": "docker"} # Get API version curl -X GET "http://localhost:8080/api/v1beta/version" # Response: {"version": "0.9.2", "commit": "abc123", "build_date": "2025-01-15"} ``` ## Kubernetes Operator CRDs ### MCPServer The MCPServer CRD deploys containerized MCP servers in Kubernetes with full lifecycle management. ```yaml apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPServer metadata: name: fetch-server namespace: toolhive-system spec: # Container image for the MCP server image: ghcr.io/stackloklabs/gofetch/server # Transport mode: stdio, streamable-http, or sse transport: streamable-http # Proxy port exposed to clients proxyPort: 8080 # Internal MCP server port (for streamable-http/sse) mcpPort: 8080 # Resource limits and requests resources: limits: cpu: "100m" memory: "128Mi" requests: cpu: "50m" memory: "64Mi" # Optional: Group reference for VirtualMCPServer aggregation groupRef: my-services # Optional: Command arguments args: - "--verbose" - "--read-only" # Optional: Environment variables env: - name: LOG_LEVEL value: "debug" - name: API_KEY secretRef: name: mcp-secrets key: api-key # Optional: Volume mounts volumes: - name: data hostPath: /data containerPath: /mnt/data readOnly: true # Optional: OIDC authentication oidcConfig: type: inline inline: issuer: "https://auth.example.com" audience: "mcp-server" jwksURL: "https://auth.example.com/.well-known/jwks.json" # Optional: Custom service account serviceAccount: mcp-server-sa ``` ### MCPGroup The MCPGroup CRD organizes MCPServers into logical groups for VirtualMCPServer aggregation. ```yaml apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPGroup metadata: name: production-tools namespace: default spec: description: Production MCP servers for AI assistants --- # MCPServers reference groups via groupRef apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPServer metadata: name: filesystem namespace: default spec: groupRef: production-tools image: ghcr.io/stackloklabs/mcp-filesystem transport: stdio proxyPort: 8080 ``` ### VirtualMCPServer The VirtualMCPServer CRD creates a gateway that aggregates multiple MCPServers into a unified endpoint. ```yaml apiVersion: toolhive.stacklok.dev/v1alpha1 kind: VirtualMCPServer metadata: name: ai-gateway namespace: default spec: # Reference to MCPGroup containing backend servers config: groupRef: production-tools # Aggregation and conflict resolution aggregation: conflictResolution: prefix conflictResolutionConfig: prefixFormat: "{workload}_" # Health check settings operational: failureHandling: healthCheckInterval: 30s # Client authentication (incoming requests) incomingAuth: type: oidc oidcConfig: type: secretRef secretRef: name: vmcp-oidc-config key: config.json authzConfig: type: inline inline: policies: - 'permit(principal, action, resource) when { principal.groups.contains("developers") };' # Backend authentication (outgoing to MCPServers) outgoingAuth: source: discovered default: type: discovered # Kubernetes service configuration serviceType: ClusterIP --- # For anonymous access (development/testing) apiVersion: toolhive.stacklok.dev/v1alpha1 kind: VirtualMCPServer metadata: name: dev-gateway spec: config: groupRef: dev-tools aggregation: conflictResolution: prefix conflictResolutionConfig: prefixFormat: "{workload}_" incomingAuth: type: anonymous authzConfig: type: inline inline: policies: - 'permit(principal, action, resource);' outgoingAuth: source: discovered ``` ### MCPRegistry The MCPRegistry CRD configures server registries from various sources. ```yaml # Git-based registry apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPRegistry metadata: name: company-registry namespace: toolhive-system spec: source: type: git git: url: https://github.com/company/mcp-registry.git branch: main path: registry.json syncInterval: 1h --- # API-based registry apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPRegistry metadata: name: external-registry spec: source: type: api api: url: https://registry.example.com/api/v1 authSecretRef: name: registry-auth key: token --- # ConfigMap-based registry apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPRegistry metadata: name: local-registry spec: source: type: configmap configMap: name: mcp-registry-data key: registry.json ``` ### MCPRemoteProxy The MCPRemoteProxy CRD proxies requests to external MCP servers hosted outside the cluster. ```yaml apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPRemoteProxy metadata: name: external-ai-service namespace: default spec: # Remote MCP server URL url: https://api.external-mcp.example.com/mcp # Group for VirtualMCPServer aggregation groupRef: external-services # Authentication to remote server auth: type: bearer bearerToken: secretRef: name: external-api-secrets key: bearer-token # Optional: OIDC authentication oidcAuth: clientId: toolhive-proxy clientSecretRef: name: oidc-secrets key: client-secret tokenEndpoint: https://auth.external.com/oauth/token scopes: - mcp:read - mcp:write ``` ### MCPExternalAuthConfig The MCPExternalAuthConfig CRD defines reusable authentication configurations for backend MCPServers. ```yaml apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPExternalAuthConfig metadata: name: github-oauth namespace: default spec: # OAuth 2.0 configuration type: oauth2 oauth2: clientId: github-mcp-client clientSecretRef: name: github-oauth-secrets key: client-secret tokenEndpoint: https://github.com/login/oauth/access_token authorizationEndpoint: https://github.com/login/oauth/authorize scopes: - repo - read:user --- # Reference in MCPServer apiVersion: toolhive.stacklok.dev/v1alpha1 kind: MCPServer metadata: name: github-server spec: image: ghcr.io/github/github-mcp-server transport: stdio externalAuthConfigRef: name: github-oauth ``` ## Summary ToolHive serves as a comprehensive platform for organizations deploying MCP servers across development and production environments. The CLI provides quick local setup and testing, while the REST API enables integration with custom tooling, CI/CD pipelines, and internal platforms. The Kubernetes Operator delivers enterprise-grade deployments with native CRDs for MCPServer workloads, VirtualMCPServer gateways, and MCPRegistry management. Key integration patterns include: using the CLI for developer workflows with protocol schemes (uvx://, npx://, go://), leveraging the REST API for automation and UI integrations, deploying MCPGroups with VirtualMCPServers for unified gateway access with conflict resolution, implementing OIDC/OAuth authentication at both gateway and backend levels, and managing secrets through encrypted storage or 1Password integration. ToolHive's modular architecture supports gradual adoption from local development through enterprise deployment while maintaining consistent security controls and observability through OpenTelemetry integration.