Agent DocsArtifacts Platform
Platform Architecture
System architecture, implementation status, and data flow for the Artifacts platform
Artifacts Platform Architecture
Platform Overview
Artifacts is a platform for LLM-generated, schema-driven documents with rich interactive rendering across multiple surfaces.
Core Concept: Artifacts are created and edited conversationally by LLM agents, not manually by users (see .agents/docs/artifacts/design-philosophy.md for rationale).
Platform Components:
- Schema validation (Zod-based artifact structure)
- Storage layer (Supabase with user isolation via RLS)
- Rendering system (React components for artifact nodes)
- Multiple surfaces for creation, editing, and viewing
Implementation Status
Core Platform
| Component | Status | Location |
|---|---|---|
| Schema & Components | ✅ ACTIVE | packages/artifact-kit/ |
| UI Components (shadcn/ui) | ✅ ACTIVE | packages/ui/ |
| Storage Service | ✅ ACTIVE | packages/artifact-service/ |
| Database | ✅ ACTIVE | infra/supabase/ |
Surfaces (Creation & Viewing)
| Surface | Status | Purpose | Location |
|---|---|---|---|
| ChatGPT Integration | ✅ PRIMARY | LLM-driven creation/editing | apps/chatgpt-app/ |
| Universal App | ✅ ACTIVE | Mobile & Web viewing | apps/expo-app/ |
| Claude Integration | 🔮 PLANNED | LLM creation (when MCP widgets supported) | - |
| Gemini Integration | 🔮 PLANNED | LLM creation (when MCP widgets supported) | - |
Development & Reference
| Component | Status | Location |
|---|---|---|
| Storybook (ChatGPT) | ✅ ACTIVE | apps/storybook-chatgpt/ |
| Artifact Kit Stories | ✅ ACTIVE | packages/artifact-kit/src/components/*.stories.tsx |
| OpenAI Examples | 📚 REFERENCE | examples/openai-apps-sdk-examples/ |
Implemented Features
Node Types (3 total)
vstack(layout) - Vertical flex containermarkdown(content) - GFM renderingline-chart(content) - Recharts line chart
MCP Tools (3 total)
artifact.list- Paginated artifact listingartifact.view- Render artifact in widgetartifact.create- Create new artifact
Authentication
- Clerk OAuth 2.1 with dynamic per-tool authentication
- JWT tokens with
subclaim for user identification - Supabase RLS policies enforce user isolation
Storage
- Supabase Postgres with JSONB artifact storage
- RLS policies using Clerk JWT
subclaim - Automatic timestamp tracking (created_at, updated_at)
Platform Architecture Layers
Core Platform (Shared)
┌─────────────────────────────────────────┐
│ Artifact Schema & Validation │
│ (packages/artifact-kit) │
│ - Zod schemas for nodes │
│ - Artifact-specific components │
│ - Uses UI primitives from packages/ui │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ UI Component Library │
│ (packages/ui) │
│ - shadcn/ui components (Button, Card) │
│ - Shared across all surfaces │
│ - Add via shadcn CLI only │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Storage Service Layer │
│ (packages/artifact-service) │
│ - Framework-agnostic CRUD │
│ - Validation before persistence │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Supabase Database │
│ (infra/supabase) │
│ - JSONB artifact storage │
│ - RLS policies for user isolation │
└─────────────────────────────────────────┘ChatGPT Surface Runtime (Primary Creation)
Next.js Application (apps/chatgpt-app/):
ChatGPT Client
↓
MCP Request → app/mcp/route.ts (Route Handler)
↓
Dynamic Auth Router (checks protectedTools)
↓
Tool Handler (app/mcp/tools/*.ts)
↓
Supabase via artifact-service
↓
Tool Response with structuredContent + widget metadata
↓
ChatGPT renders iframe: /artifact page
↓
Next.js SSR → Hydration with window.openaiAuthentication Flow
User → ChatGPT
↓
ChatGPT discovers OAuth via /.well-known/oauth-protected-resource/mcp
↓
ChatGPT initiates Clerk OAuth flow
↓
User authenticates → Clerk issues JWT
↓
ChatGPT calls MCP tool with Authorization: Bearer <jwt>
↓
withMcpAuth() validates via verifyClerkToken()
↓
Tool extracts userId from authInfo.extra.userId
↓
Tool calls Supabase with JWT
↓
Supabase RLS validates JWT.sub matches artifact.user_idData Flow Example: Creating an Artifact via ChatGPT
User in ChatGPT: "Create a dashboard with sales chart"
↓
ChatGPT (LLM) → artifact.create tool call { title, nodes }
↓
resolveAuthContext(authInfo) → userId
↓
createArtifactStore(supabase).create({ title, nodes, userId })
↓
artifactStructureSchema.parse() validates structure
↓
Supabase INSERT with RLS check (stores in shared DB)
↓
Return { structuredContent, _meta } to ChatGPT
↓
ChatGPT renders widget with artifact data
↓
Artifact now available in:
- ChatGPT (inline widget)
- Universal App (via artifact.list query to same Supabase DB)
- Future: Other surfacesKey insight: Artifacts are stored centrally in Supabase. All surfaces (ChatGPT, Universal App) read from the same database.
Multi-Surface Design
The platform is designed for artifacts to be accessible across multiple surfaces:
Surface Independence
- Each surface (ChatGPT, Universal App) implements its own UI and interaction patterns
- All surfaces share the same core platform (artifact-kit, artifact-service, Supabase)
- User authentication via Clerk allows same user to access artifacts across surfaces
Current Surfaces
-
ChatGPT (apps/chatgpt-app/)
- LLM-driven creation and editing via MCP tools
- Widget rendering via Apps SDK
- Deployed to Vercel
- See
apps/chatgpt-app/.agents/docs/for implementation details
-
Universal App (apps/expo-app/)
- Mobile and Web browsing and viewing
- Built with Expo (React Native)
- See
apps/expo-app/for implementation details
Future Surfaces
- Claude: MCP integration when Claude supports widget rendering
- Gemini: MCP integration when Gemini supports widget rendering