This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is the Pomerium MCP Chat Demo - a minimal chat application showcasing remote Model Context Protocol (MCP) servers secured with Pomerium. The application demonstrates how to build internal applications that use agentic frameworks and LLM APIs with MCP server integration.
- Frontend: React 19 with TypeScript in strict mode
- Framework: TanStack Start (SSR routing with file-based patterns)
- Styling: Tailwind CSS 4.0 + Shadcn/ui components
- Validation: Zod for runtime validation and TypeScript integration
- State Management: React Query (TanStack Query) for server state, React Context for global state
- Build Tool: Vite 6.3
- Testing: Vitest with jsdom environment
- Documentation: Storybook for component documentation
# Development server with hot reloading
npm run dev
# Production build
npm run build
# Start production server
npm run start
# Testing
npm run test # Run tests once
npm run test:ci # Run tests with coverage
# Code quality
npm run lint # ESLint check
npm run format # Prettier format
npm run format:check # Check formatting and linting
# Storybook
npm run storybook # Development Storybook server
npm run build-storybook # Build Storybook for production- File-based routing in
src/routes/ - Client routes:
.tsxfiles withcreateFileRoute() - Server routes:
.tsfiles insrc/routes/api/withcreateServerFileRoute() - All routes must include
errorBoundaryandpendingBoundaryfor proper error/loading handling
- Route Loaders: For initial page data, SSR requirements, and critical path data
- React Query: For dynamic/optional data, mutations, and client-side updates
- React Context: For global application state (user, theme, etc.)
- UI Components: Primarily Shadcn/ui components in
src/components/ui/ - Custom Components: Application-specific components in
src/components/ - Storybook Stories: Every component must have a colocated
.stories.tsxfile - Tests: Components should have
.test.tsxfiles using Vitest + Testing Library
- Zod schemas defined in
src/lib/schemas.ts - Validate all external data: API responses, user input, environment variables
- Use
.safeParse()for robust error handling
This app runs as an MCP client behind Pomerium with mcp.client: {} configuration. Key patterns:
- Server Discovery: Use
/.pomerium/mcp/routesendpoint to get available MCP servers - Authentication Flow: Direct users to
/.pomerium/mcp/connectfor upstream OAuth when needed - Tool Calls: Pass the external token to LLM APIs for MCP server access
- User Identity: Read
X-Pomerium-Assertionheader for user claims
- Chat Interface: AI-powered chat using OpenAI with tool calling capabilities
- Server Management: Dynamic server selection and connection status
- Tool Toggles: Enable/disable specific tools (code interpreter, web search, etc.)
- Model Selection: Support for different OpenAI models
Always use @/ alias for internal imports:
// ✅ Good
import { Button } from '@/components/ui/button'
import { userSchema } from '@/lib/schemas'
// ❌ Bad
import { Button } from '../components/ui/button'src/
├── components/ # Shared UI components
│ └── ui/ # Shadcn/ui components
├── contexts/ # React Context providers
├── hooks/ # Custom React hooks
├── lib/ # Utilities and schemas
├── mcp/ # MCP client integration
├── routes/ # TanStack Start routes
│ └── api/ # Server routes (.ts files)
└── styles.css # Global Tailwind styles
- Strict mode enabled - never use
anytype - Use proper generics and type inference
- Validate external data with Zod schemas
- Function components only with proper TypeScript interfaces
- Accessibility first - include ARIA attributes and semantic HTML
- Error boundaries and loading states in all routes
- Mobile-first responsive design with Tailwind
- Component tests using Vitest + Testing Library
- Storybook stories for all custom components
- Focus on user interactions and accessibility
- Shadcn Components: Add new components with
npx shadcn@latest add <component-name> - Environment: Uses Docker Compose setup with Pomerium for full MCP functionality
- Authentication: Integrated with Pomerium OAuth2 flows
- Audit Logging: MCP tool calls are logged for monitoring and compliance
The application expects specific Pomerium route configuration:
# Client route (this app)
- from: https://mcp-app-demo.your-domain.com
to: http://mcp-app-demo:3000
mcp:
client: {}
# Server routes (MCP servers)
- from: https://mcp-server.your-domain.com
to: http://mcp-server:8080/mcp
name: 'Server Name'
mcp:
server: {}This configuration enables the app to discover MCP servers and handle authentication flows seamlessly.