Skip to content

ggui dev is the developer-facing inner loop. It loads ggui.ui.json blueprint manifests, serves the local registry + dev hub at 127.0.0.1:6780, and (with --agent <entry>) supervises a local agent runtime in the same shell. Distinct from ggui serve, the production-shaped self-host counterpart.

Terminal window
ggui dev

Binds 127.0.0.1:6780, indexes any ggui.ui.json blueprints declared in ggui.json#blueprints.include, and auto-opens the dev hub in your browser.

To iterate against a local agent runtime in the same shell:

Terminal window
ggui dev --agent ./agent.ts

Port 6780 hosts the local blueprint registry + dev hub. The dev server exposes:

PathWhat it serves
/hubThe dev dashboard (no auth — same-origin XHRs embed the bearer for everything else).
/hub/preview?ui=<id>Iframe-mountable preview shell for one indexed blueprint.
/healthLiveness probe (no auth).
/uis, /uis/:id, /uis/:id/bundleDiscovered ggui.ui.json blueprints (Bearer auth).
/eventsServer-sent events for live reload (Bearer auth).
/runtime/status, /runtime/eventsMounted when --agent <entry> is set (Bearer auth).

All non-/hub endpoints require Authorization: Bearer <token>. The token is taken from GGUI_DEV_TOKEN if set; otherwise a random one is generated and printed (with an export hint) on the boot banner.

ggui dev also sets GGUI_MODE=dev in the process env. The dev stack itself does not run an MCP server — that’s ggui serve’s job — but a supervised --agent that composes @ggui-ai/mcp-server inherits the env and mounts its own /devtools/* console namespace.

Concernggui devggui serve
AudienceDeveloper iterating on UIsOperator running a self-hosted instance
Default port67806781
Default modeGGUI_MODE=dev (mounts /devtools/*)Production-shaped (no devtools)
Agent supervisionOpt-in via --agent <entry>Default-on, sourced from ggui.json#agent.entry
TunnelOpt-in via --tunnel (provider seam; none bundled)Bring your own (cloudflared etc.) + set --public-base-url
Auth postureLoopback bind + single bearer token (GGUI_DEV_TOKEN)Strict-auth pairing by default; opt-down via --dev-allow-all / --public-demo

Both can run side-by-side without colliding (different ports).

ggui dev [options]
FlagDefaultPurpose
--port <n>6780Bind port. 0 = OS-assigned.
--host <addr>127.0.0.1Bind host. Loopback only by default.
--no-serveoffLoad + discover and exit without binding. Useful for one-shot manifest validation / discovery dry-run.
--no-openoffSkip auto-opening the browser at the hub URL. Implied by non-TTY stdout, BROWSER=none, or CI=1.
--agent <entry>noneSupervise a local agent runtime. See Agent supervision for extension routing.
--tunneloffOpt into managed mode — open a managed tunnel above the local stack and print the remote URL. See Managed mode.

--agent <entry> points at the agent file you’re iterating on. Extension routing decides how it’s spawned:

ExtensionSpawnNotes
.js, .mjs, .cjsnode <entry>Plain Node
.ts, .tsx, .mtsnode --import=tsx <entry>tsx must be resolvable in your project (pnpm add -D tsx)

The dev-stack picks the agent’s port and forwards it via PORT env unless --tunnel is also set, in which case the CLI pre-allocates a free port and hands it down so the tunnel can forward inbound traffic to it.

Bad --agent paths fail before the socket binds — the CLI validates the command mapping and exits 1 with a remediation hint.

With --tunnel, once the local stack is listening ggui dev asks a TunnelProvider to open a managed tunnel above the host and prints the remote URL beside the local hub URL. The dev loop runs unchanged whether the tunnel resolves or not.

Provider discovery reads GGUI_TUNNEL_PROVIDER — a module specifier exporting createTunnelProvider(). No provider is bundled; without the env var the banner prints tunnel skipped: no tunnel provider configured and local dev runs unchanged. Real providers (cloudflared bindings, ngrok) plug into this seam without changing the CLI surface.

For a known-working public URL today, run cloudflared tunnel --url http://localhost:6780 (or your provider of choice) in a sibling shell, then point claude.ai or your MCP client at the printed URL. For the production-shaped equivalent on ggui serve, see ggui serve → Recommended setups.

Iterate on a blueprint manifest:

Terminal window
ggui dev
# edit packages/<your-app>/ggui.ui.json
# refresh the hub — the registry re-indexes on every load

Iterate on an agent + blueprints together:

Terminal window
ggui dev --agent ./agent.ts
# edit agent.ts → the supervised runtime restarts on file change (when the runtime supports it)
# edit ggui.ui.json → the registry re-indexes

Run a second ggui dev alongside the first (6780 is taken):

Terminal window
ggui dev --port 0
# 0 = OS-assigned; the actual port prints in the boot banner.
# Pass `--port 6790` (or any free integer) if you need a stable URL.

Validate manifests without binding a socket:

Terminal window
ggui dev --no-serve
# loads + discovers + exits non-zero on any malformed ggui.ui.json
# good in CI for catching manifest regressions