Embed an agent in a custom UI
Sometimes the right place to talk to an agent isn’t the auxilia chat app — it’s inside the tool where the work is already happening. A customer-support agent in your Zendesk console. A data assistant in a Google Sheet. A back-office helper in your admin dashboard.
This tutorial walks through the patterns for doing that. The specifics vary by host system, but the overall shape is the same every time.
The basic idea
auxilia exposes an HTTP endpoint that streams an agent’s response as the LLM generates it. Your custom UI:
- Captures what the user typed
- Sends it to the auxilia streaming endpoint (authenticated with a personal access token)
- Reads the streamed chunks as they arrive and renders them in your UI
The agent itself — its instructions, its tools, its MCP server bindings — lives in auxilia. Your custom UI is just a thin chat surface on top.
When this pattern makes sense
- Customer support consoles — the agent drafts replies using the same data the support rep is looking at, without forcing them to switch tabs
- Back-office dashboards — operations or finance team tools embed a “ask a question about this customer” panel
- Google Sheets / Excel add-ons — users select a range, ask the agent a question about it, and the answer streams back into the sidebar
- Internal wikis or docs sites — a floating “ask an expert” widget answers questions about a specific page’s topic
- Product-specific help widgets — when the question is narrow and the agent’s knowledge is tailored, a widget beats a generic chatbot
What you’ll need
- An auxilia deployment reachable from your embedding site (see Deploy & Configure)
- A personal access token (see User Management)
- A host UI where you can add a chat input and display streamed text — could be React, a WebView in a native app, a Slack canvas, a Google Apps Script sidebar, etc.
The streaming endpoints
auxilia speaks the Agent Streaming Protocol — the same delta-based protocol the @langchain/react / @langchain/langgraph-sdk clients consume, so a React host can reuse those packages as-is (point apiUrl at your auxilia deployment’s /api/backend).
First create the thread, once per conversation — the same call as in Trigger agents over HTTP:
POST /api/backend/threads/
{ "agent_id": "…", "model_id": "claude-haiku-4-5" }Then two calls per thread drive the conversation:
POST /api/backend/threads/{thread_id}/commands
POST /api/backend/threads/{thread_id}/stream/eventsThe first starts a turn:
{ "id": 1, "method": "run.start", "params": { "input": { "messages": [{ "type": "human", "content": "What did this customer last ask us about?" }] } } }The second opens a Server-Sent Events session on the thread. Its body is the subscription filter — {"channels": ["messages", "tools", "lifecycle", "values", "input"]} — and every frame is one protocol event: messages events carry message-start / content-block-delta (the text tokens) / message-finish, tools events the tool calls and their results, and a root lifecycle event with completed, failed or interrupted ends the turn. Your UI appends the text deltas to the message being rendered, exactly the way the auxilia chat app does.
For one-shot, non-streaming calls (useful for slower-moving surfaces like spreadsheet cells), use POST /api/backend/threads/{thread_id}/runs/invoke, which blocks and returns the final answer — see Trigger agents over HTTP.
A typical integration plan
A solid implementation usually covers these steps:
- Add a chat widget to your host UI (textarea + message list + submit button)
- Store the PAT on your backend, not in the browser — otherwise anyone with devtools can extract it
- Proxy requests through your own server — the user hits your API, your server adds the PAT and forwards to auxilia
- Stream the response back to the browser using the same SSE shape
- Track the thread ID per user per session so follow-up messages keep context
- Handle approvals — if the agent calls a tool that needs approval, decide how (or whether) to surface that in your UI
The last step is worth thinking through early. Options:
- Route approvals back to the web app or Slack — users get notified and approve elsewhere
- Only expose agents with
always allowtools — no approvals possible, simpler UX - Build approval UI into your custom app — more work, but keeps users in one place
Example setups
Rather than prescribe code, here’s the shape of a few concrete integrations teams have built:
- Google Sheets add-on — an Apps Script sidebar with a text input. User selects a range, types a question, the add-on serializes the range as CSV, calls auxilia via Apps Script’s URL fetch, streams the answer into the sidebar. Good for ad-hoc analysis.
- Zendesk side panel — a Zendesk app that, for the currently open ticket, posts the ticket context + the rep’s question to the auxilia agent and displays the streamed response. The agent has HubSpot and product-docs MCP servers so it can speak to the customer in context.
- Internal React dashboard — a floating chat widget that talks to a “data assistant” agent with BigQuery access. The widget remembers the thread ID in
localStorageso the user can keep a single conversation across sessions.
When you build one of these, consider sharing it in Case Studies — it helps other teams figure out the right shape for their own integration.