Home / Docs / Support Agent

Support AgentCopy link to this section

Most support tools send users a help article and hope they figure it out. Floe does the opposite. When a user asks for help, the in-product agent can navigate to the right screen, show them exactly how it works, and offer to do it for them.

How it worksCopy link to this section

The same in-product agent that handles onboarding also handles support. When a user gets stuck:

  1. They ask the agent (voice or text)
  2. The agent understands what they're trying to do
  3. It navigates to the relevant screen in the user's browser
  4. It shows the user what to do, step by step
  5. If the user says "just do it," the agent executes the task

The user stays in your product instead of switching to a help center.

SetupCopy link to this section

The support agent is the in-product overlay running in on-demand mode. It uses neither demoMode nor websiteAgent; activation: "on_demand" gives the host-page agent its support posture.

Load the SDK once, then initialize it from a script served by your own application:

<!-- Add these before the closing </body> tag. -->
<script src="https://cdn.floe.so/floe-sdk.iife.js" defer></script>
<script src="/floe-init.js" defer></script>
// floe-init.js — served from your own origin
const floe = Floe({
  clientKey: "YOUR_CLIENT_KEY",
  activation: "on_demand",
  userInfo: {
    externalId: "YOUR_AUTHENTICATED_USER_ID",
    email: "[email protected]",
    name: "Ada Lovelace",
    company: "Analytical Engines",
    designation: "Workspace admin",
  },
  nudge: {
    text: "Need a hand?",
    autoShow: false,
    autoHideDelay: 10000,
  },
  launcher: { position: "bottom-right", inset: 24 },
  enableAudio: true,
  enableScreenCapture: true,
});

floe.ready.catch((error) => {
  console.error("Floe failed to initialize", error);
});

// Keep the instance in your app integration. On logout or teardown:
// await floe.disconnect();

Both in-product variants start as a collapsed launcher and connect a session only after the user clicks. activation: "on_demand" changes how that launcher behaves and how the conversation opens:

  • No nudge bubble by default. The launcher sits quietly. (Set nudge: { autoShow: true } if you do want it to reach out.)
  • No session until the user asks. Nothing is spawned — and nothing is billed — for a user who never opens it.
  • A reactive opening. When they click, the agent asks what they need instead of proposing a setup walkthrough.

Everything else is unchanged. Ask it to create a report and it runs the same guided workflow the onboarding agent would; on-demand governs whether the launcher reaches out and how the conversation starts, not what the agent can do once it has started.

Pass userInfo when the agent needs non-secret name, company, role, or account context during this support session. It is unsigned browser input, even on a page behind login, so Floe does not treat it as authentication or use it to unlock the person's history from another browser. MCP authorization remains separate and comes only from the scoped bearer token your callback provides.

Live account data with MCPCopy link to this section

Support mode can connect one authenticated, remote Model Context Protocol (MCP) server for the lifetime of a support session. This lets the agent answer account-specific questions such as “What is the current account summary?” without adding that data to userInfo or Floe's knowledge base. Any customer can add a compatible public HTTPS endpoint in the widget configuration; no customer-specific Floe deployment is required.

const floe = Floe({
  clientKey: "YOUR_CLIENT_KEY",
  activation: "on_demand",
  userInfo: {
    externalId: currentUser.id,
    email: currentUser.email,
  },
  mcp: {
    serverUrl: "https://mcp.example.com/mcp",
    // Ask your authentication client for the freshest user token.
    getBearerToken: () => auth.getAccessToken(),
    // Replace this example with exact, read-only tool names from your server.
    allowedTools: ["get_account_summary"],
  },
});

The SDK calls getBearerToken once when the user opens the support launcher. Floe's API relays it in the encrypted session-start request to the Pipecat runtime, which reuses it as the MCP server's Authorization: Bearer credential for that MCP session. Give the token enough remaining TTL for the expected conversation. The SDK does not inspect localStorage itself and clears its request copy after startup. If the callback returns no token, throws, times out, or the remote server is unavailable, the ordinary support session continues without MCP tools. Disconnecting and starting a new support session calls the provider again.

To keep live account data out of retained artifacts, MCP-enabled support sessions do not create Floe session recordings or run long-history context summarization. If you need an audit trail for live-data access, record it at the MCP server under your own authorization and retention policy.

serverUrl can point to any public HTTPS Streamable HTTP endpoint. Floe validates it at session start, rejects credentials, query strings, fragments, non-standard ports, IP-literal URLs, redirects, and destinations that resolve to private, loopback, link-local, or reserved networks. The validated public address is pinned for the connection to protect against DNS rebinding. You do not need to register the hostname with Floe or wait for a deployment.

To connect a server, provide only these three values:

  • serverUrl: your public Streamable HTTP endpoint on HTTPS port 443.
  • getBearerToken: a function that returns the current user's short-lived token, synchronously or as a promise. Your server receives it as Authorization: Bearer <token>.
  • allowedTools: the exact MCP tool names Floe may discover and call for this integration.

Server compatibilityCopy link to this section

Floe connects to bearer-authenticated MCP servers over Streamable HTTP. allowedTools accepts exact, case-sensitive names made of 1–128 ASCII letters, digits, underscores, dots, or dashes. Floe creates provider-safe aliases internally when needed, while calls sent to your MCP server still use the exact remote names.

Each tool input schema must have an object root, and parameter keys must match [A-Za-z_][A-Za-z0-9_]{0,63}. Floe safely normalizes common string enums, local top-level $defs/definitions references, nullable and multi-type unions, anyOf, oneOf, and compatible object allOf composition. A tool with an unsupported or unsafe schema is omitted; if no configured tools are usable, the session continues as ordinary support without MCP. Custom authentication headers and non-Streamable-HTTP transports are not currently supported.

Treat the browser token as a user credential:

  • Mint a short-lived, MCP-audience token with only the scopes that user needs. Do not send an admin token or a refresh token.
  • Keep allowedTools narrow and read-only. The remote MCP server must still authorize every tool call from the token; this client-side list is an additional exposure control, not an authorization boundary.
  • Keep your existing Content Security Policy and XSS protections in place. Do not embed a long-lived secret in the JavaScript bundle.
  • Do not place the token in userInfo, metadata, the MCP URL, or a query string.

MCP is available only with activation: "on_demand". It is ignored for proactive onboarding, demo mode, and the website agent.

Dashboard configurationCopy link to this section

Support shares the Onboarding Agent configuration in the dashboard; there is no separate Support Agent configuration to maintain. Enable and configure the Onboarding Agent for the site, then use activation: "on_demand" in the embed. The runtime consumes its avatar configuration when avatar support is enabled for the deployment; otherwise, sessions use voice and text without a presenter.

Persona and tone values can currently be saved on that dashboard configuration, but the onboarding/support runtime does not consume them yet. Do not rely on those values to change the live support personality until runtime support lands.

Configuration referenceCopy link to this section

  • clientKey (string, required): the public browser key from the Onboarding Agent home or site settings. It is safe to expose in browser code; never expose the site's secret API key. Authorize each production app origin in the site's allowed domains.
  • activation ("on_demand"): required for the support posture. It is ignored if demoMode or websiteAgent is set.
  • userInfo (object, optional): supplies current-session context. Supported fields are externalId, email, name, company, designation, and metadata. It is not an authentication assertion and does not unlock cross-browser history. Never put access tokens or other secrets in metadata; MCP authorization belongs only in getBearerToken.
  • mcp (object, support only): authenticated remote data tools: { serverUrl, getBearerToken, allowedTools }. serverUrl accepts a compatible public HTTPS endpoint without prior registration; getBearerToken is called at support-session start; allowedTools must contain exact tool names.
  • nudge (object): accepts text, autoShow, and autoHideDelay. autoShow defaults to false under on_demand. autoHideDelay is milliseconds; 0 keeps the nudge open. Set both values explicitly when opting into a contextual nudge.
  • launcher (object): { position: "bottom-right" | "bottom-left", inset: number }. It defaults to bottom-right with a 24-pixel inset. Move it when another support widget occupies that corner.
  • enableAudio (boolean, default true): sets the initial microphone preference. Text remains available, and a user's remembered microphone preference can override the initial value.
  • enableScreenCapture (boolean, default true): makes screen sharing and screenshot context available. The browser still requires a user gesture and permission before sharing a screen.
  • debug (boolean, default false): enables verbose SDK logs while diagnosing an integration.
  • apiUrl (string, advanced): overrides the Floe API endpoint. Leave it unset with the production CDN build.

Integrate with a coding agentCopy link to this section

Copy this prompt into your coding agent from the root of your application repository:

Integrate Floe's in-product support agent into this application. Find the client-only root that mounts once after authentication resolves. Load https://cdn.floe.so/floe-sdk.iife.js exactly once and initialize it from /floe-init.js (or the framework's equivalent client-only lifecycle). Call Floe() exactly once with the public client key and activation: "on_demand". If current-session personalization is useful, map only non-secret display context into userInfo; do not treat it as an identity or authorization assertion. Do not set demoMode, websiteAgent, or demoSiteId. Keep the launcher quiet unless the product has a deliberate contextual-help route; if you add a nudge, set autoShow and autoHideDelay explicitly. Store the returned instance, handle instance.ready, and call instance.disconnect() on logout or component teardown. Do not call init() yourself or call a destroy() method. Prevent duplicate initialization under React Strict Mode. Keep the client key in a public environment variable, never expose Floe's secret API key, and never put access tokens in userInfo.metadata. Preserve the application's existing authentication and client-side routing behavior.

Running onboarding and support togetherCopy link to this section

They are the same agent on the same surface, differing in whether the launcher reaches out and how the opening is framed. One embed can serve both after your own signup state has resolved:

const activation = user.onboardingCompletedAt ? "on_demand" : "proactive";

const floe = Floe({
  clientKey: "YOUR_CLIENT_KEY",
  activation,
  userInfo: {
    externalId: user.id,
    email: user.email,
    name: user.name,
  },
  nudge: {
    text: "Need a hand?",
    autoShow: activation === "proactive",
    autoHideDelay: 10000,
  },
});

floe.ready.catch((error) => {
  console.error("Floe failed to initialize", error);
});

// Keep the instance in your app integration. On logout or teardown:
// await floe.disconnect();

New accounts get an onboarding nudge and setup-oriented opening after they click. Everyone else gets a quiet help launcher that waits to be asked.

Action, not documentationCopy link to this section

Traditional support chatbots search your knowledge base and paste an article. The user reads it, tries to follow the steps, gets confused at step 3, and files a ticket anyway.

Floe skips the article entirely. The agent has product knowledge from ingestion and uses its configured capabilities to navigate your product. It resolves by doing.

Deciding when the agent reaches outCopy link to this section

You control how forward the agent is, per user, with two settings.

activation decides whether the collapsed launcher reaches out and which opening the agent uses after a click. on_demand (above) keeps it quiet until clicked — the right default for a support surface, where an agent that interrupts is worse than no agent. proactive auto-shows an onboarding nudge and uses a setup-oriented opening for brand-new accounts.

nudge decides whether the collapsed launcher slides out a message while it waits:

const floe = Floe({
  clientKey: "YOUR_CLIENT_KEY",
  activation: "on_demand",
  nudge: {
    text: "Stuck on something? Ask me.",
    autoShow: true,
    autoHideDelay: 10000,
  },
});

floe.ready.catch((error) => {
  console.error("Floe failed to initialize", error);
});

// Keep the instance in your app integration. On logout or teardown:
// await floe.disconnect();

Under on_demand the nudge is off unless you ask for it, as above. Under proactive it is on by default. It is capped at three impressions with a seven-day cooldown after a dismissal, and it stops appearing once the user has engaged, so opting in doesn't turn into pestering.

Scope it: a nudge on a complex setup screen earns its keep in a way that a nudge on every page does not.

Reviewing support sessionsCopy link to this section

Open Onboarding Agent → Recordings to review the sessions shared by onboarding and support. Each recording can include current-session context supplied by your embed, start time, duration, voice-or-text mode, transcript, captured frames, and event details when that data is available. Browser-supplied userInfo is shown as context, not verified identity.

Floe only acts through the browser workflows and optional API execution you have configured. Keep your existing human-support path available for billing changes, refunds, or other work outside that scope; the SDK does not create a support ticket automatically.

FAQCopy link to this section

Does the support agent replace my support team? No. It handles the repetitive "how do I do X" questions to reduce customer effort score so your team can focus on complex issues that need a human.

Can the agent handle billing or account questions? It can navigate to billing screens and explain what the user sees. It can make changes that require API access only when you explicitly configure API execution; otherwise, keep your existing human-support path available.

How does it know the answer? From your ingested content. The more thorough your docs and knowledge base, the better the agent handles support questions.