Full application build: landing page, auth, chat with MCP tool use, harness management, and OAuth#8
Conversation
… Header component
…ing - should've been in the staging already
…ng related deps to apps/web
…d per conversation, add usersettings logic
Feat/landing page
Feat/login and onboarding
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…Harness into feat/mcp-implementation
Feat/mcp implementation
|
@jon3350 figure out how to get a codex review on this pr and make it do one |
There was a problem hiding this comment.
Pull request overview
This PR delivers an end-to-end initial build of Harness: a TanStack Start + Clerk + Convex web app paired with a FastAPI backend that supports streaming chat, MCP tool execution, MCP server health checks, and MCP OAuth flows.
Changes:
- Added FastAPI streaming chat endpoint (OpenRouter) plus MCP client integration, health checks, and MCP OAuth routes.
- Introduced Convex schema + queries/mutations for harnesses, conversations, messages (parts/tool calls/usage), OAuth token storage, and user settings.
- Implemented core web UI routes and components for sign-in, harness management/editing, chat streaming UI, and supporting design system components.
Reviewed changes
Copilot reviewed 66 out of 81 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/fastapi/requirements.txt | Adds FastAPI backend dependencies for SSE + JWT verification/crypto. |
| packages/fastapi/app/services/openrouter.py | Implements OpenRouter streaming + non-streaming chat helpers. |
| packages/fastapi/app/services/mcp_client.py | Adds MCP JSON-RPC client with tool listing/calling + session/tool caching. |
| packages/fastapi/app/services/convex.py | Adds Convex HTTP API helpers for saving assistant messages and patching usage. |
| packages/fastapi/app/routes/mcp_oauth.py | Adds MCP OAuth start/callback/status/revoke endpoints. |
| packages/fastapi/app/routes/mcp_health.py | Adds MCP server health checks and prompt generation endpoint. |
| packages/fastapi/app/routes/chat.py | Adds SSE chat streaming route with tool-call loop and Convex persistence. |
| packages/fastapi/app/models.py | Adds Pydantic request models for chat + harness/MCP server config. |
| packages/fastapi/app/main.py | Adds app lifespan, shared httpx client, CORS, and route wiring. |
| packages/fastapi/app/dependencies.py | Adds FastAPI dependencies for shared http client + current user. |
| packages/fastapi/app/config.py | Adds settings validation and model mapping/thinking configuration. |
| packages/fastapi/app/auth.py | Adds Clerk JWT verification via JWKS. |
| packages/convex-backend/convex/userSettings.ts | Adds user settings query/mutation with defaults. |
| packages/convex-backend/convex/seed.ts | Adds seed/clear utilities for dev data. |
| packages/convex-backend/convex/schema.ts | Defines Convex schema (harnesses/conversations/messages/OAuth tokens/settings). |
| packages/convex-backend/convex/migrations.ts | Placeholder for future Convex migrations. |
| packages/convex-backend/convex/messages.ts | Adds message CRUD + internal assistant saves + usage patching. |
| packages/convex-backend/convex/mcpOAuthTokens.ts | Adds OAuth token storage/status APIs (public + internal). |
| packages/convex-backend/convex/harnesses.ts | Adds harness CRUD and suggested prompts persistence. |
| packages/convex-backend/convex/conversations.ts | Adds conversation CRUD and recency listing. |
| packages/convex-backend/convex/_generated/dataModel.d.ts | Updates generated Convex types to use schema-aware DataModel. |
| packages/convex-backend/convex/_generated/api.d.ts | Updates generated API typings for all Convex modules. |
| packages/backend/convex/_generated/server.js | Removes deprecated generated Convex backend artifacts. |
| packages/backend/convex/_generated/server.d.ts | Removes deprecated generated Convex backend artifacts. |
| packages/backend/convex/_generated/dataModel.d.ts | Removes deprecated generated Convex backend artifacts. |
| packages/backend/convex/_generated/api.js | Removes deprecated generated Convex backend artifacts. |
| packages/backend/convex/_generated/api.d.ts | Removes deprecated generated Convex backend artifacts. |
| apps/web/vite.config.ts | Updates Vite config (deps optimization, host allowances). |
| apps/web/tsconfig.json | Adds path alias for the Convex backend workspace package. |
| apps/web/src/styles.css | Adds Geist fonts, markdown/code highlighting styles, and theme tweaks. |
| apps/web/src/routes/sign-in.tsx | Adds a dedicated Clerk sign-in page. |
| apps/web/src/routes/harnesses/index.tsx | Adds harness listing UI with controls (start/stop/edit/delete). |
| apps/web/src/routes/harnesses/$harnessId.tsx | Adds harness editor UI including MCP server config and OAuth connect UX. |
| apps/web/src/routes/__root.tsx | Adds chromeless routes, Clerk appearance, tooltips, and toaster wiring. |
| apps/web/src/routeTree.gen.ts | Updates generated TanStack Router route tree for new routes. |
| apps/web/src/lib/use-chat-stream.ts | Adds client-side SSE streaming hook with events for tools/thinking/usage. |
| apps/web/src/lib/models.ts | Adds model selection list used by harness editor. |
| apps/web/src/lib/floating-dots.ts | Adds deterministic floating-dot background generator for landing UI. |
| apps/web/src/lib/floating-dots.test.ts | Adds vitest coverage for floating-dot generator determinism/ranges. |
| apps/web/src/integrations/clerk/provider.tsx | Removes prior Clerk provider wrapper (replaced by root route config). |
| apps/web/src/integrations/clerk/header-user.tsx | Removes prior header user widget (replaced by new chrome/UX). |
| apps/web/src/env.ts | Adds VITE_FASTAPI_URL env var. |
| apps/web/src/components/ui/tooltip.tsx | Adds tooltip primitives wrapper. |
| apps/web/src/components/ui/textarea.tsx | Adds textarea component. |
| apps/web/src/components/ui/skeleton.tsx | Adds skeleton loading component. |
| apps/web/src/components/ui/sheet.tsx | Adds sheet (dialog) component. |
| apps/web/src/components/ui/separator.tsx | Adds separator component. |
| apps/web/src/components/ui/select.tsx | Adds select component. |
| apps/web/src/components/ui/scroll-area.tsx | Adds scroll-area component. |
| apps/web/src/components/ui/input.tsx | Adds input component. |
| apps/web/src/components/ui/dropdown-menu.tsx | Adds dropdown menu component. |
| apps/web/src/components/ui/dialog.tsx | Adds dialog component. |
| apps/web/src/components/ui/checkbox.tsx | Adds checkbox component. |
| apps/web/src/components/ui/card.tsx | Adds card component. |
| apps/web/src/components/ui/button.tsx | Updates button styling variants/sizes. |
| apps/web/src/components/ui/badge.tsx | Adds badge component. |
| apps/web/src/components/ui/avatar.tsx | Adds avatar component. |
| apps/web/src/components/message-actions.tsx | Adds copy/regenerate/usage UI actions (display-mode aware). |
| apps/web/src/components/mcp-server-status.tsx | Adds MCP server status UI and OAuth reconnect UX. |
| apps/web/src/components/markdown-message.tsx | Adds markdown rendering with highlighting and copyable code blocks. |
| apps/web/src/components/harness-mark.tsx | Adds Harness SVG mark component. |
| apps/web/src/components/Header.tsx | Removes legacy header/nav component. |
| apps/web/public/favicon.svg | Adds Harness favicon. |
| apps/web/package.json | Adds dependencies for markdown/highlighting/fonts/motion/convex workspace. |
| apps/web/biome.json | Tweaks Biome lint config. |
| apps/web/.env.example | Adds example FastAPI backend URL env var. |
| .cursor/rules/tanstack-auth-guards.mdc | Documents TanStack Router auth-guard conventions. |
| .cursor/rules/convex-id-types.mdc | Documents Convex branded Id type conventions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| # Get issuer from unverified claims to fetch JWKS | ||
| unverified_claims = jwt.decode(token, options={"verify_signature": False}) | ||
| issuer = unverified_claims.get("iss", "") | ||
| if not issuer: | ||
| raise HTTPException(status_code=401, detail="Token missing issuer") | ||
|
|
||
| # Fetch JWKS and find matching key | ||
| jwks = await _get_jwks(http_client, issuer) | ||
| key = None |
There was a problem hiding this comment.
JWT verification currently trusts the iss claim from unverified token payload to decide where to fetch JWKS. A malicious client can mint their own RS256 JWT, set iss to an attacker-controlled domain with a matching JWKS, and have it validate successfully. Pin the expected Clerk issuer(s) in configuration (e.g., CLERK_ISSUER / JWKS URL) and reject tokens whose iss doesn't match, instead of discovering JWKS based on the token itself.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Summary
This PR represents the full initial build of Harness, bringing the application from skeleton to a functional AI chat
platform with MCP (Model Context Protocol) integration. Key additions include:
creation, TanStack Router auth guards for protected routes
visualization, chat interrupts, auto-scroll, and per-conversation state management
decoupled harnesses from conversations with last-used tracking
checks with UI status indicators, and error surfacing to frontend
token storage and refresh via Convex
service, structured logging, config validation, connection pooling via
httpx.AsyncClientOAuth tokens, and user settings; seed data; composite indexes for recency queries
management, Geist font, toast notifications, dark theme with Clerk appearance customization
thinking model variants with reasoning parameter support
Changes
packages/backendin favor ofpackages/convex-backendHeadercomponent and Clerk integration files, replaced with route-level auth guards and chromeless routesupport
PRs included