Generic MCP / Raw HTTP
Use ggui from any language or framework — through the TypeScript SDK, the low-level MCP transport, or raw HTTP with JSON-RPC.
Using the SDK (Recommended)
Section titled “Using the SDK (Recommended)”import { GguiClient } from "@ggui-ai/mcp-client";
const ggui = new GguiClient({ apiKey: process.env.GGUI_API_KEY!, appId: process.env.GGUI_APP_ID!,});
// Simple: push a UI and wait for the responseconst { sessionId, url, events } = await ggui.pushAndWait({ story: { intent: "Product satisfaction survey", prompt: "Show a survey with 3 multiple-choice questions about product satisfaction", },});
console.log("Survey URL:", url);console.log( "Responses:", events.filter((e) => e.event.type === "data:submit"));Using the MCP Transport Directly
Section titled “Using the MCP Transport Directly”For advanced use cases, use McpHttpTransport to call MCP tools directly.
import { McpHttpTransport } from "@ggui-ai/mcp-client";
const transport = new McpHttpTransport({ url: "https://api.guuey.com/mcp", apiKey: process.env.GGUI_API_KEY!, appId: process.env.GGUI_APP_ID!,});
// List available toolsconst tools = await transport.listTools();console.log( "Available tools:", tools.map((t) => t.name));// → ['ggui_push', 'ggui_pop', 'ggui_consume', 'ggui_get_session', 'ggui_close']
// Call a toolconst result = await transport.callTool<{ sessionId: string; url: string }>("ggui_push", { story: { intent: "Login form", prompt: "Show a login form" },});console.log("Session:", result.sessionId);Using Raw HTTP (No SDK)
Section titled “Using Raw HTTP (No SDK)”Call the MCP API directly via HTTP from any language.
Hosted vs OSS — what to swap
Section titled “Hosted vs OSS — what to swap”Every curl below is written against hosted Guuey. To drive a local OSS ggui serve instead, make these two substitutions globally:
| What | 🟣 Hosted Guuey | 🟢 OSS ggui serve |
|---|---|---|
| Endpoint URL | https://api.guuey.com/mcp | http://127.0.0.1:6781/mcp |
Authorization | Bearer ggui_sk_... | Bearer dev (dev-mode only) |
X-Ggui-App-Id | required (app_...) | omit |
OSS dev-mode auth is 127.0.0.1-only. Swap in a real AuthAdapter before exposing the server.
Step 1: Initialize
Section titled “Step 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": "my-agent", "version": "1.0" }, "capabilities": {} } }'Step 2: Push a UI
Section titled “Step 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", "prompt": "Show a contact form with name, email, and message" } } } }'Step 3: Poll for Events
Section titled “Step 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_..." } } }'Step 4: Close
Section titled “Step 4: Close”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_..." } } }'Python Example
Section titled “Python Example”import requestsimport jsonimport osimport time
API_URL = "https://api.guuey.com/mcp"HEADERS = { "Authorization": f"Bearer {os.environ['GGUI_API_KEY']}", "X-Ggui-App-Id": os.environ["GGUI_APP_ID"], "Content-Type": "application/json",}
request_id = 0
def mcp_request(method: str, params: dict = None) -> dict: global request_id request_id += 1 payload = {"jsonrpc": "2.0", "id": request_id, "method": method} if params: payload["params"] = params response = requests.post(API_URL, headers=HEADERS, json=payload) return response.json()
def call_tool(name: str, arguments: dict) -> dict: result = mcp_request("tools/call", {"name": name, "arguments": arguments}) if "error" in result: raise Exception(f"MCP Error: {result['error']}") content = result["result"]["content"][0]["text"] return json.loads(content)
# Initializemcp_request("initialize", { "protocolVersion": "2025-11-25", "clientInfo": {"name": "python-agent", "version": "1.0"}, "capabilities": {},})mcp_request("notifications/initialized")
# Push a UIresult = call_tool("ggui_push", { "story": { "intent": "Product feedback form", "prompt": "Show a feedback form with rating (1-5) and comments", }})print(f"UI URL: {result['url']}")
# Poll for eventssession_id = result["sessionId"]while True: consume = call_tool("ggui_consume", {"sessionId": session_id}) for event in consume["events"]: if event["event"]["type"] == "data:submit": print(f"User submitted: {event['event']['value']}") if consume["status"] == "completed": break time.sleep(2)
# Clean upcall_tool("ggui_close", {"sessionId": session_id})See Also
Section titled “See Also”- MCP Protocol Reference — Complete wire protocol documentation
- MCP Client SDK — Full SDK API docs
- Quick Start — 5-minute getting started guide