Skip to content

Full application build: landing page, auth, chat with MCP tool use, harness management, and OAuth#8

Open
DIodide wants to merge 78 commits intomainfrom
staging
Open

Full application build: landing page, auth, chat with MCP tool use, harness management, and OAuth#8
DIodide wants to merge 78 commits intomainfrom
staging

Conversation

@DIodide
Copy link
Owner

@DIodide DIodide commented Mar 11, 2026

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:

  • Landing page — Animated landing page with floating dots background, feature highlights, and call-to-action
  • Authentication & onboarding — Clerk-based sign-in page, onboarding flow with API key setup and initial harness
    creation, TanStack Router auth guards for protected routes
  • Chat interface — Full streaming chat UI with markdown rendering, reasoning/thinking display, tool call
    visualization, chat interrupts, auto-scroll, and per-conversation state management
  • Harness management — Create, configure, and manage harnesses (model + MCP server bundles), harness detail pages,
    decoupled harnesses from conversations with last-used tracking
  • MCP integration — Dynamic HTTP-streamable MCP server connectivity, parallel tool call execution, MCP server health
    checks with UI status indicators, and error surfacing to frontend
  • OAuth for MCP servers — Full OAuth 2.0 flow for MCP servers requiring authentication (GitHub OAuth App support),
    token storage and refresh via Convex
  • FastAPI backend — Chat streaming endpoint via OpenRouter, MCP client service, OAuth routes, Convex persistence
    service, structured logging, config validation, connection pooling via httpx.AsyncClient
  • Convex backend — Schema for harnesses, conversations, messages (with parts, tool calls, usage/cost tracking), MCP
    OAuth tokens, and user settings; seed data; composite indexes for recency queries
  • UI/UX — shadcn/ui component library, display modes (zen/standard/developer), user settings with profile
    management, Geist font, toast notifications, dark theme with Clerk appearance customization
  • Model support — GPT-4o, GPT-4.1, Claude Sonnet/Opus 4, Gemini 2.5 Pro/Flash, DeepSeek R1/V3, Grok 3/3 Mini;
    thinking model variants with reasoning parameter support

Changes

  • 81 files changed, ~12,000 insertions, ~670 deletions
  • Removed deprecated packages/backend in favor of packages/convex-backend
  • Removed old Header component and Clerk integration files, replaced with route-level auth guards and chromeless route
    support

PRs included

DIodide and others added 30 commits February 26, 2026 12:23
@DIodide
Copy link
Owner Author

DIodide commented Mar 11, 2026

@jon3350 figure out how to get a codex review on this pr and make it do one

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +44 to +52
# 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
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Copy link

Copilot AI commented Mar 11, 2026

@DIodide I've opened a new pull request, #9, to work on those changes. Once the pull request is ready, I'll request review from you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants