This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
bun run dev # Start API server + web build (watch mode) concurrently
bun run dev:api # API server only (port 3001, hot reload)
bun run dev:web # Web build only (watch mode)
bun run build # Full production build (web + server)
bun run check # TypeScript type checking (tsc --noEmit)
bun run ci:check # Biome lint + format check (CI mode, no auto-fix)
bun run fmt # Auto-format with Biome
bun run lint # Auto-fix lint issues with Biome
bun test # Run tests (Bun test runner)
bun test <file> # Run a single test fileThis is an MCP App template — it builds interactive UIs for MCP (Model Context Protocol) tools. A single unified HTML bundle is built and served as an MCP resource, with runtime routing to the correct tool UI based on the toolName from the MCP host context.
API Server (api/) — Bun HTTP server using @decocms/runtime. Defines MCP tools and resources, exposes them at /api/mcp via SSE.
React UI (web/) — React 19 app using @modelcontextprotocol/ext-apps SDK. Connects to the MCP host, receives tool input/results, and renders interactive UI.
All tool UIs live in web/tools/<name>/. Vite builds a single unified HTML file at dist/client/index.html (all CSS/JS inlined via vite-plugin-singlefile). At runtime, the ToolRouter component in web/router.tsx reads toolName from the MCP host context and renders the matching tool page from the TOOL_PAGES registry.
- Create
api/tools/<name>.ts— tool definition with Zod input/output schemas,_meta.ui.resourceUrilinking to the resource - Register in
api/tools/index.ts - Create
web/tools/<name>/with the tool's page component - Register the page component in
TOOL_PAGESinweb/router.tsx(key must match the tool'sid) - Create
api/resources/<name>.ts— servesdist/client/index.htmlwith MIME typetext/html;profile=mcp-app
The UI renders based on McpStatus: initializing → connected → tool-input → tool-result (or error / tool-cancelled). See web/types.ts and web/context.tsx.
@/*→web/*(components, hooks, lib)
- Runtime: Bun (not Node)
- Formatter: Biome with tab indentation, double quotes
- Imports: Must include
.ts/.tsxextensions (useImportExtensions: error) - UI components: shadcn/ui in
web/components/ui/(do not lint these for a11y) - Styling: Tailwind CSS v4, use
cn()from@/lib/utils.tsfor conditional classes - Validation: Zod v4 for all schemas (tool input/output, state)