The <char-agent> custom element accepts the following attributes and provides an imperative API for secure authentication.
Attributes
| Attribute | Type | Default | Description |
|---|
open | boolean | false | Controls the open/closed state of the agent overlay |
dev-mode | JSON string | — | Development overrides including API keys (localhost only) |
enable-debug-tools | boolean | false | Exposes debug tools in the agent UI |
Imperative API
The recommended way to authenticate is via the connect() method, which keeps tokens out of the DOM.
connect(options)
Connect to the Char agent with authentication. Returns true if connection was initiated.
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
const agent = document.querySelector('char-agent') as WebMCPAgentElement;
agent.connect({ idToken: session.idToken, clientId: 'your-oidc-client-id' });
Options:
| Option | Type | Description |
|---|
idToken | string | IDP token for authentication (SPA) |
clientId | string | OIDC client ID for audience validation (required with idToken) |
ticketAuth | TicketAuth | Pre-fetched ticket for SSR authentication |
Either idToken or ticketAuth must be provided, but not both.
disconnect()
Disconnect from the agent and clear authentication. Returns true if disconnection succeeded.
Authentication Methods
SPA: Using idToken (Recommended)
For single-page applications where users authenticate client-side:
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
const agent = document.querySelector('char-agent') as WebMCPAgentElement;
agent.connect({ idToken: session.idToken, clientId: 'your-oidc-client-id' });
Benefits:
- Token never exposed in DOM attributes
- Protected from session replay tools (FullStory, LogRocket)
- Not captured by error monitoring (Sentry, DataDog)
- Hidden from DOM inspection and browser extensions
SSR: Using ticketAuth
For server-side rendered applications where your server exchanges the IDP token for a ticket:
import type { WebMCPAgentElement, TicketAuth } from '@mcp-b/char/web-component';
// Server obtains ticket, passes to client
const ticketAuth: TicketAuth = { /* from server */ };
const agent = document.querySelector('char-agent') as WebMCPAgentElement;
agent.connect({ ticketAuth });
Benefits:
- IDP token never exposed to browser
- No JWKS fetch on every connection (validation done once server-side)
- Ticket is short-lived (60s default) and single-use
Related: Embedding Guide - SSR Authentication
open
Controls the visibility of the agent overlay.
const agent = document.querySelector("char-agent");
agent?.setAttribute("open", "true"); // shows agent
agent?.setAttribute("open", "false"); // hides agent
// Property access also works
agent.open = true;
React example:
import { useRef, useEffect, useState } from 'react';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
function App({ idToken }: { idToken: string }) {
const [isOpen, setIsOpen] = useState(false);
const agentRef = useRef<WebMCPAgentElement>(null);
useEffect(() => {
agentRef.current?.connect({ idToken, clientId: 'your-oidc-client-id' });
}, [idToken]);
return <char-agent ref={agentRef} open={isOpen} />;
}
dev-mode
JSON string containing development overrides for local testing. This is the primary way to use the agent during development without SSO.
<char-agent dev-mode='{"anthropicApiKey":"sk-ant-..."}'></char-agent>
| Property | Type | Description |
|---|
anthropicApiKey | string | Your Anthropic API key for chat (required for anonymous mode) |
openaiApiKey | string | OpenAI API key for voice mode (optional) |
useLocalApi | boolean | Point to local development API server (internal use) |
Anonymous mode (with dev-mode) provides:
- Full Durable Object persistence (messages survive page refresh)
- Local WebMCP tools on the current page
- Same streaming and tool calling as authenticated mode
Restrictions:
- Localhost only. Requests from non-localhost origins are rejected.
- No cross-app tools. Only tools on the current page are available.
- No organizational features. No user tracking, audit logs, or governance.
Never embed API keys in production code—they’re visible to users in the HTML source. Use connect() with proper authentication for production.
Exposes debugging controls in the agent UI for inspecting state and troubleshooting.
<char-agent enable-debug-tools="true"></char-agent>
Intended for development environments.
TypeScript Declarations
The package exports TypeScript types for the web component:
import type { WebMCPAgentElement, ConnectOptions, TicketAuth } from '@mcp-b/char/web-component';
React Usage
JSX types are automatically available when you import the web component. Use refs for the imperative API:
import { useRef, useEffect } from 'react';
import '@mcp-b/char/web-component';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
function App({ idToken }: { idToken: string }) {
const agentRef = useRef<WebMCPAgentElement>(null);
useEffect(() => {
agentRef.current?.connect({ idToken, clientId: 'your-oidc-client-id' });
}, [idToken]);
return <char-agent ref={agentRef} />;
}
Vanilla TypeScript
import '@mcp-b/char/web-component';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
const agent = document.querySelector('char-agent') as WebMCPAgentElement;
agent.connect({ idToken: session.idToken, clientId: 'your-oidc-client-id' });