Skip to content

MCP Protocol

The ggui API uses the Model Context Protocol (MCP) over HTTP with JSON-RPC 2.0.

🟣 Hosted Guuey:

POST https://api.guuey.com/mcp

🟢 OSS / self-hosted (ggui serve):

POST http://127.0.0.1:6781/mcp

🟣 Hosted Guuey — include your API key and app ID in every request:

Authorization: Bearer ggui_sk_...
X-Ggui-App-Id: app_...
Content-Type: application/json

🟢 OSS / self-hosted — dev mode accepts any non-empty bearer token as the builder identity. Swap in a real AuthAdapter via createGguiServer({ auth }) before exposing beyond 127.0.0.1:

Authorization: Bearer dev
Content-Type: application/json
1. initialize → Handshake (automatic, done once per connection)
2. ggui_push → Create session + resolve rendering
3. ggui_commit → Accept the decision and provide props
4. ggui_consume → Poll for user events (repeat as needed)
5. ggui_push/pop → Navigate the UI stack
6. ggui_close → Clean up when done

ggui_push resolves the best rendering path in this order:

  1. Blueprint match — curated/heuristic/llm-authored screens indexed by sourceTools. Instant, deterministic, zero-LLM.
  2. Deterministic derivation — single-tool outputSchema → contract → pool.
  3. Intent fast-path — prior contract-hash lookup.
  4. Full negotiation — RAG + LLM (fallback).

Pass sourceTools (which tools produced the data) and wiredTools (which tools are available for actions). The handler picks the best path and returns a decision. ggui_commit accepts and sends props.


Create a new UI or push a card onto an existing session’s stack. V4 uses nested input groups.

Input: { story, session?, rendering?, infra?, shortcuts? }

story (required):

FieldTypeRequiredDescription
intentstringYesConcise purpose — same intent = cached component reused.
dataobjectNoStructured data to display.
sourceToolsstring[]NoMCP tools that produced this data. Primary key for blueprint matching.
wiredToolsstring[]NoMCP tools available as user actions.
promptstringNoAdditional instructions beyond the intent.
contextstring | objectNoAgent reasoning, user situation.

Other groups: session.{id, message}, rendering.{shellType, interfaceContext}, infra.{ttl, model}, shortcuts.{templateId, props, autoCommit}.

Returns a decision: { sessionId, pageId, decision, renderUrl, shortCode }. Call ggui_commit with props to accept (or override to request something different).

Accept or override the decision returned by ggui_push. Required to complete rendering (unless shortcuts.autoCommit was set on push).

FieldTypeRequiredDescription
sessionIdstringYesSession ID from the push response.
pageIdstringYesPage ID from the push response.
acceptbooleanNoAccept the decision.
propsobjectNoData matching the decision’s contract.
alternativeIdstringNoPick a different alternative (suggestive modes).
overrideobjectNo{ action, contract, instructions, prompt } override.

Remove the top UI card from the session stack.

FieldTypeRequiredDescription
sessionIdstringYesSession to pop from

Returns: { poppedId, stackSize }

Poll for buffered user events. Events are cleared after being returned (consume-once semantics).

FieldTypeRequiredDescription
sessionIdstringYesSession to consume from

Returns: { events: ActionEnvelope[], status: "active" | "completed" }

Get the full state of a session, including the UI stack and event sequence.

FieldTypeRequiredDescription
sessionIdstringYesSession to inspect

Returns: { sessionId, appId, stack, currentStackIndex, adapterPermissions, eventSequence, status }

Get the current UI stack: what pages are displayed, their prompts, and their contracts (stream spec for ggui_stream, actions for ggui_consume).

FieldTypeRequiredDescription
sessionIdstringYesSession to inspect

Returns: { stack: StackItem[], currentStackIndex, contracts }

Close and delete a session.

FieldTypeRequiredDescription
sessionIdstringYesSession to close

Returns: { success: boolean }


User actions flow from browser to agent as canonical flat ActionEnvelope records. Each envelope has this structure:

interface ActionEnvelope<TPayload = JsonValue> {
sessionId: string;
type: EventType;
payload?: TPayload; // For `data:submit`: { action, data?, tool? }
stackIndex?: number;
pageId?: string;
clientSeq?: number; // client-monotonic, for at-least-once dedup
}

The envelope is flat — no nested event / context / meta blocks. Diagnostic session metadata (device info, interface context) lives on the session at subscribe time, not per-delivery.

TypeCategoryDescription
data:submitDataUser submitted a form
data:changeDataA field value changed
lifecycle:session_startLifecycleSession created
lifecycle:session_endLifecycleSession ended
lifecycle:stack_pushLifecycleCard pushed to stack
lifecycle:stack_popLifecycleCard popped from stack
interaction:clickInteractionUser clicked a component
interaction:hoverInteractionUser hovered
interaction:scrollInteractionUser scrolled
error:validationErrorForm validation failed
error:connectionErrorWebSocket connection issue

Default subscription (when omitted): ["data:submit", "lifecycle:session_end"]


CodeNameDescription
-32700Parse ErrorInvalid JSON in request
-32600Invalid RequestNot a valid JSON-RPC object
-32601Method Not FoundUnknown method name
-32602Invalid ParamsMissing or invalid tool arguments
-32603Internal ErrorServer-side failure
-32001UnauthorizedInvalid API key or app ID
-32002Session Not FoundSession expired or deleted
-32003App Not FoundApp ID does not exist
-32004Generation FailedUI generation failed

Model IDProviderTierDescription
anthropic/claude-haiku-4-5AnthropicFastDefault model. Fast, cost-effective
anthropic/claude-sonnet-4-5AnthropicBalancedHigher quality output
anthropic/claude-opus-4-5AnthropicPremiumHighest quality
gemini/gemini-3-flashGoogleFastVery fast, large context
openai/gpt-5.2OpenAIPremiumHigh quality
openai/gpt-5.1-codex-miniOpenAIFastFast code generation

Terminal window
# 1. Initialize
curl -X POST https://api.guuey.com/mcp \
-H "Authorization: Bearer ggui_sk_..." \
-H "X-Ggui-App-Id: app_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","clientInfo":{"name":"curl","version":"1.0"},"capabilities":{}}}'
# 2. Push a UI
curl -X POST https://api.guuey.com/mcp \
-H "Authorization: Bearer ggui_sk_..." \
-H "X-Ggui-App-Id: app_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"ggui_push","arguments":{"story":{"intent":"Contact form"}}}}'
# 3. Poll for events
curl -X POST https://api.guuey.com/mcp \
-H "Authorization: Bearer ggui_sk_..." \
-H "X-Ggui-App-Id: app_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"ggui_consume","arguments":{"sessionId":"ses_..."}}}'
# 4. Close session
curl -X POST https://api.guuey.com/mcp \
-H "Authorization: Bearer ggui_sk_..." \
-H "X-Ggui-App-Id: app_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"ggui_close","arguments":{"sessionId":"ses_..."}}}'