ToolHive Cloud UI
A Next.js application for visualizing MCP (Model Context Protocol) servers running in user infrastructure with easy URL copying for integration with AI agents.
Frontend: toolhive-cloud-ui (this repository)
Backend API: toolhive-registry-server - implements the official MCP Registry API
[!NOTE] This is an experimental project that is under active development and testing. Features may change without notice.
Quickstart
Prerequisites
- Node.js 20+ and pnpm 10+
- For Kubernetes deployment: Docker, Kind, Helm, kubectl
Developer guide
Local development
This section covers all available commands and development workflows.
# Install dependencies
pnpm install
# Copy environment variables template (optional for development)
cp .env.example .env.local
# Start full dev environment (Next.js + OIDC mock + MSW mock server)
pnpm dev
# Application will be available at http://localhost:3000
Authentication: the dev stack also starts a local OIDC provider (on :4000) and MSW mock API (on :9090). The /signin page initiates the OIDC flow and redirects back to /catalog on success.
Available commands
Development commands (pnpm)
# Full development environment (recommended)
pnpm dev # Starts Next.js + OIDC mock + MSW mock server
# - Next.js: http://localhost:3000
# - OIDC Mock: http://localhost:3001
# - MSW Mock API: http://localhost:9090
# Individual services
pnpm dev:next # Start only Next.js dev server
pnpm dev:mock-server # Start Next.js + MSW mock (requires real OIDC provider configured)
pnpm dev:mock-oidc # Start Next.js + OIDC mock (requires real backend API configured)
pnpm oidc # Start only OIDC mock provider
pnpm mock:server # Start only MSW standalone mock server
# Production build
pnpm build # Build optimized production bundle
pnpm start # Start production server (after build)
# Code quality
pnpm lint # Run Biome linter
pnpm format # Auto-format code with Biome
pnpm test # Run Vitest tests
pnpm type-check # TypeScript compilation check
# API client generation
pnpm generate-client # Fetch swagger.json and regenerate client
pnpm generate-client:nofetch # Regenerate client without fetching
Make commands
For convenience, common pnpm commands are also available as Make targets:
# Development
make install # Install dependencies
make dev # Run dev server (pnpm dev)
make dev-next # Run only Next.js (pnpm dev:next)
make dev-mock-server # Run with MSW only (pnpm dev:mock-server)
make lint # Run linter
make format # Format code
make test # Run tests
make type-check # Type checking
make generate-client # Generate API client
# Docker (see Docker section below)
make build # Build Docker image
make start # Start container
# ... (see Docker section)
# Kubernetes (see Kubernetes section below)
make kind-setup # Setup Kind cluster
make kind-deploy # Deploy to Kind
# ... (see Kubernetes section)
Development workflow
1. Initial setup
# Clone repository
git clone https://github.com/stacklok/toolhive-cloud-ui.git
cd toolhive-cloud-ui
# Install dependencies
pnpm install
# Copy environment variables (optional for dev)
cp .env.example .env.local
2. Start development server
# Full environment (recommended)
pnpm dev
This starts:
- Next.js on
http://localhost:3000- Main application - OIDC Mock on
http://localhost:3001- Mock authentication provider - MSW Mock Server on
http://localhost:9090- Mock backend API
Note: For other development modes (different combinations of mock/real services), see the Development Modes section below.
3. Code quality checks
Before committing:
# Run all checks
pnpm lint # Check code style
pnpm format # Auto-fix formatting
pnpm type-check # Verify TypeScript
pnpm test # Run test suite
Git hooks (via Husky) automatically run linting on staged files.
4. API client updates
When the backend API changes:
# Fetch latest swagger.json and regenerate client
pnpm generate-client
# Files updated:
# - swagger.json
# - src/generated/**
Note: Never edit files in src/generated/ manually - they are auto-generated.
Development modes
Choose the mode that best fits your development needs:
Mode 1: Full stack development (default - recommended)
pnpm dev
What runs:
- ✅ Mock OIDC authentication (
localhost:3001) - ✅ Mock backend API via MSW (
localhost:9090) - ✅ Next.js dev server (
localhost:3000)
Best for: Frontend development without external dependencies
Mode 2: Mock OIDC + real backend API
pnpm dev:mock-oidc
What runs:
- ✅ Mock OIDC authentication (
localhost:3001) - ❌ No API mock - requires real backend API configured
- ✅ Next.js dev server (
localhost:3000)
Best for: Backend integration testing with mock authentication
Required configuration in .env.local:
API_BASE_URL=https://your-backend-api.com # Real backend API URL
Mode 3: Mock backend API + real OIDC
pnpm dev:mock-server
What runs:
- ❌ No OIDC mock - requires real OIDC provider configured
- ✅ Mock backend API via MSW (
localhost:9090) - ✅ Next.js dev server (
localhost:3000)
Best for: Authentication integration testing with mock backend
Required configuration in .env.local:
OIDC_ISSUER_URL=https://your-oidc-provider.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_PROVIDER_ID=okta # or your provider
BETTER_AUTH_SECRET=your-secret
BETTER_AUTH_URL=http://localhost:3000
Mode 4: Real services only
pnpm dev:next
What runs:
- ❌ No OIDC mock
- ❌ No API mock
- ✅ Next.js dev server only (
localhost:3000)
Best for: Full production-like testing with real services
Required configuration in .env.local:
# Real OIDC provider
OIDC_ISSUER_URL=https://your-oidc-provider.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_PROVIDER_ID=okta
# Real backend API
API_BASE_URL=https://your-backend-api.com
# Auth configuration
BETTER_AUTH_SECRET=your-secret
BETTER_AUTH_URL=http://localhost:3000
Testing
Unit/component tests
pnpm test # Run all tests
pnpm test --watch # Watch mode
pnpm test --coverage # With coverage
Uses Vitest + Testing Library + MSW.
E2E tests (Playwright)
pnpm exec playwright install # One-time browser install
pnpm test:e2e # Run tests (auto-starts dev server if needed)
pnpm test:e2e:ui # Playwright UI mode
pnpm test:e2e:debug # With Playwright Inspector
Tests automatically start the dev stack if it's not already running. If you prefer to start it manually first, run pnpm dev before the tests.
Mock server
The project includes a standalone MSW mock server for development:
# Start standalone mock server
pnpm mock:server
# Available at http://localhost:9090
Features:
- Auto-generates mocks from OpenAPI schema
- Customizable fixtures in
src/mocks/fixtures/ - Custom handlers in
src/mocks/customHandlers/
See docs/mocks.md for details.
Environment variables
Required for production
| Variable | Description | Example |
|---|---|---|
OIDC_ISSUER_URL | OIDC provider's issuer URL | https://auth.example.com |
OIDC_CLIENT_ID | OAuth2 client ID | your-client-id |
OIDC_CLIENT_SECRET | OAuth2 client secret | your-client-secret |
OIDC_PROVIDER_ID | Provider identifier | okta, auth0, oidc |
BETTER_AUTH_SECRET | Secret for token encryption | Generate with openssl rand -base64 32 |
BETTER_AUTH_URL | Application base URL | https://your-app.example.com |
API_BASE_URL | Backend API URL | https://api.example.com |
Optional
| Variable | Description | Default |
|---|---|---|
TRUSTED_ORIGINS | Comma-separated list of trusted origins | BASE_URL,http://localhost:3002,http://localhost:3003 |
OPENROUTER_API_KEY | OpenRouter API key for AI Assistant | None (assistant disabled without it) |
Note: The AI Assistant feature requires an OpenRouter API key. See the Assistant documentation for setup instructions.
Development (auto-configured)
When running pnpm dev, these are automatically configured:
NODE_ENV=development
OIDC_ISSUER_URL=http://localhost:3001
OIDC_CLIENT_ID=web-client
OIDC_CLIENT_SECRET=web-secret
OIDC_PROVIDER_ID=oidc
BETTER_AUTH_URL=http://localhost:3000
API_BASE_URL=http://localhost:9090
Configuration file
Copy .env.example to .env.local and fill in your values:
cp .env.example .env.local
Note: .env.local is git-ignored and should never be committed.
Docker
This project includes Docker support for containerized deployments.
Using Makefile (recommended)
# Show all available commands
make help
# Build Docker image
make build
# Start container
make start
# View logs
make logs
# Stop container
make stop
# Clean up (remove container and image)
make clean
# Rebuild from scratch
make rebuild
The application will be available at http://localhost:3000.
Docker Compose (full stack)
Run the complete stack (UI + Registry Server + PostgreSQL) with Docker Compose.
Prerequisites
Clone the registry-server repo in the same parent directory:
git clone https://github.com/stacklok/toolhive-registry-server.git ../toolhive-registry-server
With Okta authentication
-
Create a
.envfile with your Okta credentials:OIDC_ISSUER_URL=https://your-org.okta.com OIDC_CLIENT_ID=your-client-id OIDC_CLIENT_SECRET=your-client-secret -
Start the stack:
make compose-up
With mock OIDC (development)
No .env file needed:
make compose-up-mock
Access
- UI:
http://localhost:3000 - API:
http://localhost:8080 - OIDC Mock (if using mock):
http://localhost:4000
Commands
make compose-up # Start with Okta (requires .env)
make compose-up-mock # Start with mock OIDC
make compose-down # Stop all services
make compose-logs # View logs
make compose-build # Rebuild images
Kubernetes / Kind deployment
This project includes a complete Helm chart for deploying to Kubernetes (optimized for Kind).
Quick start with kind
# Create cluster and deploy (first time)
make kind-setup
# Or step by step:
# 1. Create Kind cluster
make kind-create
# 2. Deploy application
make kind-deploy
# 3. Access the application
make kind-port-forward
# Then open: http://localhost:8080
# View logs
make kind-logs
# Uninstall
make kind-uninstall
# Delete cluster
make kind-delete
Helm chart
The Helm chart is located in the helm/ directory and includes:
- Deployment with configurable replicas
- Service (ClusterIP/NodePort/LoadBalancer)
- Horizontal Pod Autoscaler (optional)
- Configurable resource limits
- Health checks (startup, liveness and readiness probes)
- Security contexts following Pod Security Standards
CI/CD
The chart is automatically tested on every push using GitHub Actions with Kind:
- Helm Lint: Validates chart syntax and best practices
- Integration Test: Deploys to Kind cluster and verifies the app responds
Project documentation
For detailed information about the project:
- AGENTS.md - Project overview, architecture, and key patterns
- CLAUDE.md - Detailed development guidelines
- docs/mocks.md - MSW mock server documentation
- AI Assistant - AI Assistant feature documentation (requires OpenRouter API key)
- CONTRIBUTING.md - How to contribute
Technology stack
- Framework: Next.js 16 (App Router)
- Language: TypeScript (strict mode)
- UI: React 19 + shadcn/ui + Tailwind CSS 4
- Auth: Better Auth (OIDC)
- API client: hey-api
- Testing: Vitest + Testing Library
- Linting: Biome
Related projects
- toolhive-registry-server - Backend API implementing the official MCP Registry API
- ToolHive Desktop UI - Desktop application for running and managing MCP servers locally
External resources
- Next.js Documentation
- Better Auth Documentation
- hey-api Documentation
- shadcn/ui Components
- MCP Registry Official
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
Contributing
We welcome contributions! Please see our Contributing Guide for details on how to get started.
License
This project is licensed under the Apache License 2.0. See the LICENSE file for details.