---
title: Self-hosted quickstart
description: Start from the ggui samples and run an agentic app locally — no account, no cloud, no ggui API key.
---

Run the entire protocol yourself — no account, no cloud. This is the same protocol the hosted quickstarts use — nothing about your agent changes between them — see [Portability](/hosted/portability/).

Assemble a complete ggui agentic app from the canonical samples and run it locally — your agent, the ggui MCP server, a sample MCP server, and a web client.

```
agent ── MCP ──→ ggui serve ──→ MCP-Apps resource ui://ggui/render/<id>
```

Two ways in — same protocol either way, in the same order as the [repo README](https://github.com/ggui-ai/ggui#quick-start--pick-your-path):

1. **Composed golden path — platform-composed (guuey-sdk):** published SDKs end-to-end — guuey's dev tooling runs the agent, ggui renders the UI.
2. **Bring your own framework:** compose the framework-native samples (Claude Agent SDK / OpenAI Agents SDK / Google ADK) into one workspace — no guuey dependency.

## Path 1: composed golden path — platform-composed (guuey-sdk)

One flow from a `guuey.json` to a rendered, interactive todo UI — every piece a published SDK. [guuey](https://guuey.com)'s dev tooling runs the agent (`@guuey/cli` + `@guuey/worker`), the ggui runtime is the dev router's injected MCP default, and the web client talks to the router with `@guuey/agent-client`.

Prerequisites: **Node.js 22+**, **pnpm**, and an **`ANTHROPIC_API_KEY`** (one key drives both the agent and ggui's UI generation).

```bash
git clone https://github.com/ggui-ai/ggui && cd ggui
pnpm install                        # workspace deps — `guuey dev` spawns the colocated
                                    # todo MCP from samples/mcp-servers/todo
export ANTHROPIC_API_KEY=sk-ant-…   # in every terminal below

# terminal 1 — the ggui runtime MCP (guuey's dev router injects ggui → this port)
npx -y @ggui-ai/cli serve --mcp-only --dev-allow-all   # http://127.0.0.1:6781/mcp

# terminal 2 — the agent half: guuey.json + a Claude agent worker
cd samples/agents/with-guuey
npm install
npm run dev                              # guuey dev --serve → http://localhost:6790

# terminal 3 — the web half: chat + rendered ggui cards
cd samples/apps/with-guuey-web
npm install
npm run dev                              # http://127.0.0.1:6890
```

`--dev-allow-all` is what makes terminal 1 usable here: `/mcp` is bearer-gated by default, and both callers in this path arrive anonymous — the dev router's own ggui connection (it carries no dev token; only colocated servers get one) and the web half's browser relay. Without the flag, the first `ggui_render` returns `401`. It is a loopback convenience — never put it on a public URL.

Open **`http://127.0.0.1:6890`** and ask for your todos: the agent calls the todo MCP, renders an interactive todo UI through ggui, and your clicks flow back to the agent. Prefer a scaffolded start? `npx @guuey/create-agentic-app` scaffolds a guuey agentic app of the same shape (agent + MCP + ggui + web) in one command.

**Before / after.** This is the composed path's headline. The framework-native web client (`samples/apps/ggui-basic-web`) hand-rolls its agent loop in a 702-line `Chat.tsx` — SSE parsing, the per-turn status machine, the transcript fold, resource narrowing, and generative-UI recognition. The composed web half replaces all of that with `useAgentInvoke` from `@guuey/agent-client/react` plus `@guuey/mcp-apps-host`'s view-mount dispatcher (`toolResultViewMount` — inline mcp-ui resources first, ggui renders second, bare `ui://` locators last); what remains in `samples/apps/with-guuey-web` is rendering — an `App.tsx` that is mostly JSX.

Two per-path notes, stated where you hit them (full detail in the sample READMEs — [`samples/agents/with-guuey`](https://github.com/ggui-ai/ggui/tree/main/samples/agents/with-guuey) · [`samples/apps/with-guuey-web`](https://github.com/ggui-ai/ggui/tree/main/samples/apps/with-guuey-web)):

- **Dev-server trust:** `guuey dev` runs your agent unjailed with your environment — standard dev-server trust; run it in a container if that posture doesn't fit.
- **Fresh sessions only:** `guuey dev --serve` keeps sessions in memory and serves no history endpoint — every page load starts a fresh thread. Durable state belongs in your MCP servers (the todo list survives reloads); reload-repaint of chat history is a hosted-platform feature.

This path is **platform-composed**: it drives the ggui protocol through guuey's published SDKs. The protocol itself has no guuey dependency — path 2 below (and the self-host and hosted paths in the repo README) runs without it, and the framework-native samples stay first-class.

## Path 2: bring your own framework — framework-native samples

Compose the framework-native samples into one workspace — no guuey dependency. Composing is a real step, not a figure of speech; once the tree exists, a single `pnpm dev` runs all four services.

### Prerequisites

- **Node.js** 22+ — the repo declares `engines.node >= 22`.
- **pnpm** 11+ — required, not a preference. The workspace carries pnpm-only settings (`nodeLinker: hoisted`, `autoInstallPeers`, `allowBuilds`) that npm and bun do not read.
- An MCP-capable agent runtime (Claude Desktop, Claude Code, Cursor, or anything that reads `.mcp.json`).
- No account, no ggui API key. Everything is local (generation runs on your own LLM key — Step 2).

### Step 1: Clone the samples

```bash
git clone https://github.com/ggui-ai/ggui && cd ggui
pnpm install
```

The clone gives you the pieces, not a preassembled app. Four canonical samples compose into one small monorepo: `samples/agents/<sdk>/` → `servers/agent/` (your agent — `claude-agent-sdk` / `openai-agents-sdk` / `google-adk`), `samples/gguis/default/` → `servers/ggui/` (the ggui MCP server config), `samples/mcp-servers/todo/` → `servers/mcps/todo/` (a sample MCP server), and `samples/apps/ggui-basic-web/` → `apps/web/` (a web client).

### Step 1.5: Compose them into one app

Composing is a manual step today — the repo root has no `dev` script and no `servers/` directory until you make one. Two references ship in the repo, and they are the exact ones the project's own end-to-end suite uses:

- **`e2e/samples-render/app-shell/`** — the root wrapper: the `package.json` that carries `dev` plus the granular `dev:ggui` / `dev:agent` / `dev:mcps` / `dev:web` / `dev:stop` scripts, the `pnpm-workspace.yaml` describing the composed layout, and the `pnpm dev` orchestrator itself.
- **`e2e/samples-render/scripts/compose-app.mjs`** — the copy plan, including the `workspace:*` → published-version rewrite each sample's dependencies need once they live outside this repo's workspace.

Copy the wrapper to an empty directory, copy the four samples to the target paths above, and you have the tree the rest of this path describes. See the [samples quickstart in the repo README](https://github.com/ggui-ai/ggui#quick-start--pick-your-path) for the same layout in the repo's own words.

### Step 2: Boot the composed app

Set an LLM key in `.env.local` at the composed app's root (any one — the boot probe walks `anthropic` → `openai` → `google` → `openrouter`):

```bash
# .env.local
ANTHROPIC_API_KEY=sk-ant-...
```

```bash
pnpm dev
```

From the composed root, `pnpm dev` boots the whole app together — the ggui MCP server (`ggui serve` from [`@ggui-ai/cli`](https://www.npmjs.com/package/@ggui-ai/cli), embedding `@ggui-ai/mcp-server`), your agent, the sample MCP server, and the web client. The ggui server (`servers/ggui`) defaults to `http://127.0.0.1:6781`:

- **MCP endpoint:** `http://127.0.0.1:6781/mcp`
- **WebSocket (live channel):** `ws://127.0.0.1:6781/ws`
- **Operator console:** `http://127.0.0.1:6781/`

Granular scripts (`dev:ggui`, `dev:agent`, `dev:mcps`, `dev:web`, `dev:stop`) run the pieces individually — they are declared in the wrapper's `package.json`.

:::tip[Local dev auth]
The composed `servers/ggui` start script passes `--dev-allow-all`, so any non-empty bearer (the `"Bearer dev"` in Step 3 below) resolves as `builder`. Bare `ggui serve` does **not** — its default is pair-minted bearers, and a `Bearer dev` config gets a `401` against it. `--dev-allow-all` is fine on `127.0.0.1` and **must never reach the open internet**; switch to [pairing](/self-hosted/pairing/) when you tunnel out.
:::

:::tip[WebSocket URL differs by deployment]

- **Self-hosted / OSS (this guide):** `ws://127.0.0.1:6781/ws` — or `wss://<your-server>/ws` once you put TLS in front.
- **Hosted ggui:** `wss://mcp.ggui.ai/ws` — handled for you. See [Build an agent on hosted ggui](/quickstart/hosted-agent/).
  :::

### Step 3: Point an agent runtime at the local MCP

Create `.mcp.json` at your project root with:

```json
{
  "mcpServers": {
    "ggui": {
      "url": "http://127.0.0.1:6781/mcp",
      "headers": { "Authorization": "Bearer dev" }
    }
  }
}
```

Claude Desktop, Claude Code, Cursor, and any runtime that reads `.mcp.json` will discover the agent-facing tool catalogue — `ggui_handshake` / `ggui_render` / `ggui_update` / `ggui_amend` / `ggui_emit` / `ggui_consume`, plus discovery tools (`ggui_get_session`, `ggui_list_sessions`, `ggui_list_gadgets`, `ggui_list_themes`, blueprint search/render).

The flow is **`handshake` → `render`**, with `ggui_amend` to repaint props on the mounted card in place and `ggui_update` to mint a new history card when a change is worth its own transcript entry. Write a system prompt that tells the LLM when to render UIs — the [Examples](/examples/claude-agent/) section has working recipes per framework.

## What works today

- ✅ **Local server + wsToken-gated WebSocket subscribe → ack** work end-to-end — the iframe receives `wsUrl`/`wsToken` on the `ai.ggui/render` slice. Render plumbing is production-shaped, not a mock.
- ✅ **`handshake` → `render`** delivers an MCP-Apps resource (`ui://ggui/render/<id>`) that an MCP-Apps host mounts.
- ✅ **Component generation is wired via BYOK.** Export `ANTHROPIC_API_KEY` (or `OPENAI_API_KEY` / `GOOGLE_API_KEY` / `OPENROUTER_API_KEY`) before `ggui serve` and `ggui_render` runs the real `@ggui-ai/ui-gen` pipeline (blueprint match → synth). Without any key, `ggui_render` returns a "Connect Claude" card pointing at the local `/settings` page rather than failing.
- ✅ **Per-app theming.** Your `servers/ggui/ggui.json` sets `theme: {preset: 'indigo', mode: 'dark'}`; agents can list presets via `ggui_list_themes` and override per render with `ggui_render({themeId})`.
- 🔒 **Default auth is pair-minted.** `/mcp` rejects bearers that weren't issued by the pairing flow. Pass `--dev-allow-all` to accept any non-empty bearer as `builder` (safe only on `127.0.0.1`), or swap in a real `AuthAdapter` via `createGguiServer({ auth })` before exposing the server beyond localhost.

## What this is not

- **Not a hosted service.** No ggui cloud account, no billing, no managed dashboards. For those, see [Build an agent on hosted ggui](/quickstart/hosted-agent/).
- **Not a managed billing surface.** Generation runs on YOUR provider key (BYOK) — every `ggui_render` bills the provider directly. The hosted ggui cloud bundles credit-metered billing and managed keys; this OSS path runs on your own provider key today.

## Vocabulary

- **Tool** — an agent-side action exposed over MCP (`ggui_render`, `ggui_handshake`, …).
- **Gadget** — a renderer-side capability surfaced inside the viewer (formerly `clientLibraries`).
- **Blueprint** — a cached component recipe matched before generation runs.

Full definitions: [Glossary](/glossary/).

## Just the bare MCP server

The composed app orchestrates everything through `pnpm dev`. If you only want the OSS MCP server — no agent or web supervision — run [`ggui serve`](/cli/serve/) against a `ggui.json` directly (the same `ggui serve` the composed samples' `servers/ggui` runs):

```bash
# = ggui serve --mcp-only --dev-allow-all --port 6781
pnpm --filter ./servers/ggui start
```

Working from a monorepo clone rather than the published packages? Build the workspace copies first:

```bash
pnpm --filter @ggui-ai/cli build
node packages/ggui-cli/dist/cli.js serve --mcp-only
```

## What's next

- **[MCP Protocol Reference](/api/mcp-protocol/)** — wire format and tool catalogue (same on OSS and hosted).
- **[WebSocket Protocol](/api/websocket-protocol/)** — live-channel envelopes (`ActionEnvelope`, `StreamEnvelope`).
- **[Examples](/examples/claude-agent/)** — MCP-config-only integrations with system-prompt recipes (Claude, OpenAI, Gemini, OpenClaw, generic MCP).
- **[Build an agent on hosted ggui](/quickstart/hosted-agent/)** — managed generation and dashboards on ggui cloud.
- **[GitHub repo](https://github.com/ggui-ai/ggui)** — source, issue tracker, full monorepo walkthrough.