Skip to content
Sneak peek — you found hosted ggui early · official launch soon

ggui deploy

read as .md

ggui deploy provisions and wires a hosted ggui app for the current project in one pass: sign in, create the cloud app, mint a connector key, upload your local blueprint pool and app config, and write the endpoint into .env.local. It is the command form of everything the dev-loop crossover does by hand.

The command is idempotent. Each step is skipped when its gate is already satisfied, so re-running after a partial failure resumes from the first unsatisfied step instead of duplicating work.

From a directory containing (or under) a ggui.json:

Terminal window
ggui deploy

On completion it prints the app’s MCP endpoint and where the bearer landed:

ggui deploy complete.
App MCP endpoint: https://mcp.ggui.ai/apps/<appId>
Bearer key: in .env.local (GGUI_MCP_BEARER)

Your agent picks up the hosted endpoint on its next start — .env.local now carries both GGUI_MCP_URL and GGUI_MCP_BEARER, the same two variables the local ↔ hosted swap is built on.

Without a ggui.json anywhere up the directory tree, the command exits 1 before doing anything — it needs the manifest both to persist the appId and to know what to push.

Steps run in this order. The first three are gated on current state; the rest always run:

Step Runs when What it does
login no valid session in ~/.ggui/auth.json Device-flow sign-in to api.ggui.ai — same flow as ggui login.
create-app ggui.json has no appId POST /v1/apps, then persists the new appId into ggui.json. If the app was created but ggui.json could not be written, the command stops loudly with the id to add by hand — re-running without it would create a duplicate app.
mint-key .env.local has no GGUI_MCP_BEARER Creates a connector key (named ggui deploy) and writes its one-time-reveal secret into .env.local. The secret is shown once; only the prefix is retrievable later on the connector keys page.
push always Compiles the local blueprint pool and uploads it to the app — the same operation as ggui push --app <appId>. Artifact ids are deterministic (contractHash-variantKey), so re-pushing the same pool is a no-op server-side.
push-config always Pushes the app config declared in ggui.json: the gadget catalog, app.publicEnv (keys must match GGUI_PUBLIC_APP_<NAME>), and the generation block (model, keySource). Loopback bundle URLs are rejected — a hosted app cannot fetch from 127.0.0.1.
push-keys only with --push-keys Pushes your LLM provider API key to the app — see Provider keys below.
wire-env always Writes GGUI_MCP_URL into .env.local — unless one is already set, which is never clobbered.

.env.local lives next to ggui.json (not necessarily the invocation directory). Both files are edited in place; other keys and comments are preserved.

The per-app hosted endpoint is the bare per-app URL:

https://mcp.ggui.ai/apps/<appId>

There is no /mcp suffix — that suffix is the local ggui serve convention, and appending it to a hosted app URL produces a 404. Writing the correct shape automatically is the practical reason to prefer ggui deploy over hand-editing .env.local; the trap is documented in the dev loop.

Two details of wire-env:

  • First deploy — the URL comes verbatim from the connectUrl the backend returned at create-app, so it is correct for whichever environment GGUI_API_URL pointed at.
  • Re-deploys — an existing GGUI_MCP_URL is left untouched, whatever it points at. Delete the line and re-run if you want it rewritten.

Apps with generation.keySource: "own" render on your model account instead of drawing down ggui credits — but only once the app actually holds your provider key. --push-keys adds that step to the deploy:

Terminal window
ggui deploy --push-keys

The provider is derived from ggui.json#generation.model, and the key is read from that provider’s environment variable:

Provider Environment variable
anthropic ANTHROPIC_API_KEY
openai OPENAI_API_KEY
google GOOGLE_API_KEY (falls back to GEMINI_API_KEY)
openrouter OPENROUTER_API_KEY

bedrock routes are rejected — IAM-only, no plaintext key to push. To name the provider explicitly instead of deriving it from the model string, call the underlying command directly: ggui provider-key set --app <appId> --provider <name>.

If ggui.json declares keySource: "own" and you deploy without --push-keys, the command still succeeds but ends with a warning: cloud renders will reject until a key is pushed. See Credits, billing & BYOK for how the two key sources are charged.

ggui deploy provisions the ggui side only — the interface layer. Hosting the agent itself (the process that talks to your users and calls ggui) is a separate concern: run it yourself, or use a hosting platform such as guuey. Nothing in this command deploys, restarts, or configures an agent runtime.

ggui deploy [--push-keys]
Flag Purpose
--push-keys Insert the push-keys step: push the provider API key from your environment to the cloud app.

GGUI_API_URL (see CLI configuration) controls which backend the deploy targets; the default is production api.ggui.ai.

  • ggui CLI overview — the full command surface, including standalone ggui push and ggui provider-key.
  • The dev loop — iterate locally, then cross over to hosted with the two-variable swap this command writes.
  • ggui login — the device-flow sign-in deploy runs when needed.
  • Connector keys — what the minted ggui_user_* key is and how to revoke it.
  • Blueprints & the cache — why uploading a matured local pool makes a fresh hosted app fast on day one.