Architecture
read as.md This page is the protocol’s architecture — what every ggui implementation must do, independent of how it’s deployed. For deployment shapes, see Self-Hosted and Reference deploys.
Three actors
Section titled “Three actors”Agent (LLM-driven) │ │ MCP ▼Server ◀───── WebSocket (live) ──────▶ Renderer (iframe / standalone page) │ │ │ bootstrap (bundle fetch) │ └────────────────────────────────────────────┘- Agent — your code with an LLM in the loop. Speaks to the server over MCP.
- Server — speaks MCP outward, orchestrates generation, routes events. Hosts the artifact registry the renderer pulls from. Runs at your URL via
ggui serve(hostedmcp.ggui.aicoming soon). - Renderer — an iframe (or standalone page) hosting the generated component. Sends user actions back to the server through the host’s
tools/callrelay.
Three channels
Section titled “Three channels”ggui’s wire is split across three orthogonal channels. Each has one job.
| Channel | Direction | Purpose |
|---|---|---|
| Bootstrap | Server → Renderer | One-shot fetch of the compiled component bundle when the iframe first loads. Any gadgets bound to the session load behind a <link rel="modulepreload" integrity> SRI gate. |
| MCP | Agent ↔ Server | Control plane. ggui_handshake, ggui_render, ggui_update, ggui_consume, ggui_emit, ggui_get_session. |
| Live | Renderer ↔ Server | WebSocket at ws://127.0.0.1:6781/ws (self-hosted default; hosted wss://mcp.ggui.ai/ws coming soon). Server deliveries outbound (StreamEnvelope, props updates, drain acks); contract violations on an inbound action are answered with a typed error frame (CONTRACT_VIOLATION, code -32020) on this channel — nothing lands on the consume buffer. |
The rendered view’s user actions reach the server through the host’s MCP-Apps tools/call relay to ggui_runtime_submit_action — the spec-canonical dispatch path; the server appends the gesture to the pipe ggui_consume drains. The live WebSocket’s job is server → renderer delivery (stream emits, props updates, drain acks).
The channels are independent. The renderer can drop and reconnect the live channel without disturbing an agent’s MCP turn; the agent can ggui_render repeatedly without ever touching the live channel.
→ See Protocol overview for the formal three-channel spec.
Capability model
Section titled “Capability model”ggui has two symmetric capability surfaces — one for what the agent can do, one for what the renderer can render. Both are operator-bounded and declared per-app.
| Renderer side | Agent side | |
|---|---|---|
| Unit | gadget | tool |
| Catalog | clientCapabilities.gadgets | agentCapabilities.tools |
| Role | Wraps a 3rd-party browser library (Leaflet, Mapbox, Chart.js) into an LLM-callable hook | Gives the agent a function to invoke (e.g. searchContacts, createInvoice) |
| Authored as | ggui.gadget.json manifest | MCP tool code |
| Bound at | iframe boot (SRI-verified) | session start |
Plus a third primitive — blueprints — which aren’t capabilities but cached recipes (pre-composed UIs). A blueprint hit short-circuits fresh generation.
→ See Gadgets SDK, MCP Protocol, Marketplace.
Generation pipeline
Section titled “Generation pipeline”Rendering is a two-call flow — ggui_handshake negotiates, ggui_render commits:
0. NEGOTIATE ggui_handshake({intent, blueprintDraft}) searches the blueprint cache by contract shape (exact contractHash hit short-circuits; semantic similarity otherwise) and returns a suggestion1. COMMIT ggui_render({handshakeId, props}) consumes the handshake; a cache hit reuses the stored blueprint (~100ms)2. GENERATE Otherwise, run the server's UI generator (@ggui-ai/ui-gen): workflow → impl → check → derive3. COMPILE TSX → JS via esbuild (~20-50ms)4. DELIVER Renderer fetches the compiled bundle on the bootstrap channelPublished artifacts (gadgets, blueprints) on the marketplace registry pick up an author signature at publish time — Ed25519 (publisher keypair) for private artifacts, sigstore keyless (OIDC) for public ones — see Marketplace. Fresh generations are session-scoped and skip that step.
The generator (step 2) is a bounded harness: pick a workflow (single_pass, staged, staged-concurrent), run the LLM-driven impl phase, run a check leg (typecheck, render-smoke, per-axis assertions), and on failure derive a revised harness and retry up to maxIterations. Output: a TypeScript-typed contract plus a compiled component module.
→ See UI Generator for the harness internals.
Artifact registry
Section titled “Artifact registry”Gadgets and blueprints resolve through a four-tier waterfall on every push:
1. App-local ggui.json#app.gadgets, ggui.json#blueprints.include (plus installed artifacts under .ggui/installed-blueprints/)2. Per-org private operator's private registry (artifacts with visibility:"private")3. Public registry.ggui.ai (marketplace)4. Fall back fresh generationA blueprint is keyed by a stable blueprintId; its contractHash — the RFC 8785 canonical-JSON hash of its DataContract, scoped per (appId, contractHash) — groups variants and is the cache lookup key. An exact contractHash hit short-circuits to score 1.0; otherwise a multi-axis semantic search (contract embedding, structural fingerprint, variance tags, intent) ranks candidates. Install the same (scope, name, version) on two different servers and the matcher returns the byte-identical UI on both.
→ See Marketplace, Self-Hosted Registry.
Deployment shapes
Section titled “Deployment shapes”The same protocol runs in two shapes:
| Self-hosted | Hosted (coming soon) | |
|---|---|---|
| MCP endpoint | your URL via ggui serve | mcp.ggui.ai |
| WS endpoint | ws://127.0.0.1:6781/ws (or your URL) | wss://mcp.ggui.ai/ws |
| Auth | pluggable AuthAdapter + optional OAuth 2.1 (ggui serve --oauth) | OAuth |
| Registry | your registry (or none) | registry.ggui.ai |
| Generation | in-process | managed |
| Pick if | ”I need data residency, custom auth, or air-gapped" | "I just want to ship an agent UI” |
Both speak the same wire. Switching between them is configuration, not code.
→ See OSS Quick Start to run it yourself. A managed hosted path at mcp.ggui.ai is coming soon.
Where to next
Section titled “Where to next”- Protocol overview — formal spec
- How ggui works — narrative walk-through of the four moments
- Event System — live-channel event flow in detail
- UI Generator — the generator harness