This file provides guidance to Claude Code when working with this repository.
ToolHive Studio is an Electron desktop application for managing MCP (Model Context Protocol) servers. Built with React, TypeScript, and Vite. The Electron app bundles the ToolHive CLI (thv) binary.
pnpm install # Install dependencies (runs rebuild for native modules)
pnpm run start # Start dev server with hot reload
pnpm run lint # Run ESLint
pnpm run type-check # TypeScript checking (both app and node configs)
pnpm run format # Format with Prettier
pnpm run test:nonInteractive # Run unit tests once
pnpm run test # Run unit tests in watch mode
pnpm run test:coverage # Unit tests with coverage
pnpm run e2e # Package + run Playwright e2e tests
pnpm run knip # Detect unused code
pnpm run generate-client # Fetch OpenAPI spec + regenerate API clientHusky/lint-staged automatically run lint + format on staged .ts/.tsx files. Run pnpm run type-check manually before committing — it is not covered by the hook.
- Node.js >=24 <25 (use
nvm use—.nvmrcis present) - pnpm package manager
- Docker daemon must be running (required by ToolHive)
- Docker must be running before
pnpm run start— ToolHive manages containers, so the daemon is required even in dev - Node version mismatch: native modules (
better-sqlite3) break on wrong Node version. Alwaysnvm usefirst - Stale generated types: if type errors reference API types, run
pnpm run generate-clientto refresh - Native module rebuild: after Node version change or fresh install issues, run
pnpm run rebuild - Electron test runner: unit tests run through Electron (
vitest:electron), not plain Node — required for native module compatibility - All commands from root: always run
pnpmcommands from the repository root, not from subdirectories
These files are generated and will be overwritten:
renderer/src/route-tree.gen.ts— Generated by TanStack Router plugin from route filescommon/api/generated/*— Generated bypnpm run generate-clientfrom OpenAPI spec
To update generated API client: edit the OpenAPI spec source, then run pnpm run generate-client.
To update routes: add/modify files in renderer/src/routes/, the route tree regenerates automatically.
main/— Main process: app lifecycle, IPC handlers, database (SQLite), auto-update, deep links, CLI integrationrenderer/— Renderer process: React UI, routing, API calls, state managementpreload/— Preload scripts: bridge between main and renderer viawindow.electronAPIcommon/— Shared code: generated API client, types, constants
- Routing: TanStack Router with file-based convention in
renderer/src/routes/__root.tsx— root layout- Route files use dot-notation for nesting (e.g.,
logs.$groupName.$serverName.tsx)
- State: TanStack React Query for server state, React Context for app state (theme, permissions)
- API: Generated client from OpenAPI spec in
common/api/generated/ - UI: Radix UI primitives + Tailwind CSS + CVA for component variants
- Forms: React Hook Form + Zod validation
- File naming: always kebab-case (e.g.,
card-mcp-server.tsx,use-auto-update.ts) - Components: PascalCase exports, functional components with hooks
- Path aliases:
@/*(renderer/src),@common/*(common),@utils/*(utils),@mocks/*(mocks) - Imports: use path aliases, not relative paths for cross-directory imports
- Exports: prefer named exports over default exports
- Unit tests: Vitest + Testing Library + MSW for API mocking
- Test location:
__tests__/directories colocated with source - API mocking: Auto-generated MSW fixtures from OpenAPI spec. See
docs/mocks.md- Fixtures in
renderer/src/common/mocks/fixtures/ - Use
.override()/.overrideHandler()for test-specific responses - Use
recordRequests()to assert on API calls
- Fixtures in
- E2E tests: Playwright in
e2e-tests/
pnpm run test run path/to/file.test.tsx- Follow Conventional Commits:
feat:,fix:,docs:,test:,chore:, etc. - PR titles must follow conventional commit format (validated by CI)
- Keep PRs small and focused (size/XS or size/S preferred)
- See
CONTRIBUTING.mdfor full guidelines
- Protocol:
toolhive-gui://v1/<intent>?<params> - Handled by main process, routed to TanStack Router
- See
.claude/skills/deep-links/for implementation guidance