Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when embedding, deploying, configuring, styling, or debugging Runtype Persona chat widgets, fullscreen AI assistant layouts, chat surfaces, client-token installs, theme tokens, artifacts, tool/reasoning visibility, programmatic widget access, WebMCP page tools, or browser-side local tools. Prefer generate_persona_embed_code and get_persona_theme_reference over hand-written snippets.
.claude/skills/hashgraph-online-runtype-persona/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 44% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 41% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 36% | 0% |
Persona (@runtypelabs/persona) is an open-source, backend-agnostic chat widget: a themeable, zero-framework chat UI that streams from any SSE-capable backend. It ships first-party Runtype support, so the easiest production path is a Runtype chat surface with a browser-safe clientToken. Use this skill for website widgets, assistant layouts, deployment snippets, theming, artifacts, WebMCP page tools, and local browser tools.
Default to Runtype. Embed against a Runtype chat surface with a browser-safe clientToken and the widget talks to api.runtype.com directly — no proxy and no server code. This is the recommended path and what generate_persona_embed_code produces. If MCP is unavailable and the user wants a starter deploy, runtype persona init creates a simple agent, origin-scoped client token, and paste-ready snippet.
Persona also runs on any other streaming backend via the Persona SSE protocol, with adapter examples for the Vercel AI SDK, OpenAI Agents, LangGraph, and the Anthropic Claude Agent SDK, among others. Reach for a self-hosted backend or @runtypelabs/persona-proxy only when you must hide a secret API key or front a non-Runtype agent — otherwise the hosted clientToken embed is simpler and has fewer moving parts.
When MCP is available:
get_platform_documentation(topic="persona-embed") for current embed docs.get_platform_documentation(topic="persona-fullscreen-assistant") for fullscreensplit-pane assistant layouts.
get_persona_theme_reference before custom themes.generate_persona_embed_code for final snippets whenever possible.runtype://types/surface-configs directly when surface behavior config detailsmatter.
Do not hand-write embed code unless the MCP tools are unavailable. If the task needs details not listed here, fetch persona-embed, persona-fullscreen-assistant, or types-surface-configs rather than adding more embed prose to this skill.
@runtypelabs/persona.https://cdn.runtype.com/persona/latest forordinary embeds. Use cdn.runtype.com everywhere — it is required on pages deployed through Runtype (a static app or any Runtype-hosted page): their strict CSP only allows scripts/styles from the page origin and https://cdn.runtype.com, so third-party CDNs (jsdelivr, unpkg, esm.sh) are blocked and fail silently. On a Runtype-deployed page, replace latest with a pinned version (e.g. /persona/4.6.0/) so a new release can't shift the widget code under your immutable app bundle.
https://cdn.runtype.com/persona/latest/install.global.js.https://cdn.runtype.com/persona/latest/index.js.@runtypelabs/persona/widget.css (or https://cdn.runtype.com/persona/latest/widget.css for CDN/ESM installs).initAgentWidget().onScriptLoad, onLauncherShown,onChatReady(handle), and onError.
persona:chat-ready; do not use the removed persona:ready event.initAgentWidget() returns the handle; its onChatReady option is a fire-onlycallback, not the primary way to get the handle.
user:message and assistant:complete.Common wrong answers: @runtype/persona, Persona.mount(), window.Persona, index.umd.js, missing widget.css, persona:ready, onReady, widget:ready, message:sent, or message:received.
chat surface.create_client_token.generate_persona_embed_code.launcher, user message, primary button, tool call, and reasoning bubble contrast.
trusted.
features.askUserQuestion.expose: true or features.suggestReplies.expose: true in the widget config instead of hand-writing duplicate local tools.
For ChatGPT/Claude-style layouts, read the fullscreen assistant resource first. The default launcher embed is not enough. Fullscreen layouts usually need full-height mode, panel chrome changes, a persistent shell, an artifact pane, composer customization, and layout-specific token choices.
Use browser-side local tools when the assistant needs to read page state or trigger UI actions that are only available in the front end. For Persona widgets these are WebMCP page tools registered on document.modelContext and admitted by the chat surface's behavior.webmcp policy. Pair local tools with hidden parameters when authenticated context should not enter model context.
Good local tool examples:
Required WebMCP setup:
document.modelContext (e.g. registerTool(...)) in the hostpage. Persona snapshots them per turn into clientTools[] and runs returned webmcp:<name> calls back in the browser.
allowedOrigins includes the embedding page origin.webmcp: { enabled: true }.Persona shows native approval bubbles by default; use webmcp.autoApprove = (info) => ... only for safe reads and webmcp.onConfirm only when the host page needs custom confirmation UI. Widget-side webmcp.allowlist is a convenience filter, not a security boundary.
chat surface behavior.webmcp.enabled to true.behavior.webmcp.allowlist rules for page tools that should becallable, e.g. { origin: "https://store.example.com", tools: ["search_*"] }. Use behavior.webmcp.requireConfirmFor (a Persona-side UX hint, e.g. ["checkout_*"]) to force per-call confirmation; server-side enforcement is enabled + allowlist.
real traffic. Discovery records the offered page tools before allow-list filtering.
mcp surface. WebMCP runs inside thebrowser page; an mcp surface exposes Runtype capabilities to external AI clients.
local tools directly to API-key /v1/dispatch as top-level clientTools[], then resume via /v1/dispatch/resume. This is not the default browser embed path and must run from a trusted server or SDK process because it requires a secret API key. Raw dispatch uses optional clientToolsPolicy.allowlist; it does not use behavior.webmcp, client-token allowedOrigins, or dashboard discovery telemetry. Custom public-token browser UIs should use /v1/client/chat plus /v1/client/resume instead; that path follows the same surface behavior.webmcp policy as Persona.
If the umbrella runtype skill is installed alongside this focused skill, its durable references provide fallback snippets and working-mode tradeoffs. This skill must still work when installed by itself; prefer live MCP docs over local sibling files.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→fail | 66,172 | 11,828 | -82% | 1 | 1 | 0% | 1,211 | 2,327 | +92% | 0 | 0 | — |
case-01 | fail→fail | 19,549 | 18,061 | -8% | 1 | 1 | 0% | 2,948 | 2,478 | -16% | 0 | 0 | — |
case-03 | fail→fail | 42,360 | 11,492 | -73% | 1 | 1 | 0% | 8,244 | 2,388 | -71% | 0 | 0 | — |
case-04 | fail→pass | 17,678 | 10,875 | -38% | 1 | 1 | 0% | 2,089 | 3,014 | +44% | 0 | 0 | — |
case-05 | pass→fail | 16,878 | 16,461 | -2% | 1 | 1 | 0% | 1,880 | 2,357 | +25% | 0 | 0 | — |
case-06 | fail→pass | 13,999 | 8,484 | -39% | 1 | 1 | 0% | 1,551 | 2,493 | +61% | 0 | 0 | — |
case-07 | fail→pass | 27,666 | 8,272 | -70% | 1 | 1 | 0% | 1,785 | 2,512 | +41% | 0 | 0 | — |
case-08 | fail→pass | 12,017 | 7,436 | -38% | 1 | 1 | 0% | 1,609 | 2,386 | +48% | 0 | 0 | — |
case-09 | fail→pass | 18,252 | 3,681 | -80% | 1 | 1 | 0% | 1,950 | 2,645 | +36% | 0 | 0 | — |
case-10 | fail→pass | 16,674 | 8,251 | -51% | 1 | 1 | 0% | 1,794 | 2,479 | +38% | 0 | 0 | — |
case-11 | fail→pass | 12,987 | 15,469 | +19% | 1 | 1 | 0% | 2,054 | 2,883 | +40% | 0 | 0 | — |
case-12 | pass→pass | 12,026 | 5,929 | -51% | 1 | 1 | 0% | 1,211 | 2,927 | +142% | 0 | 0 | — |
case-13 | pass→pass | 23,864 | 3,844 | -84% | 1 | 1 | 0% | 3,904 | 2,652 | -32% | 0 | 0 | — |
case-14 | fail→pass | 35,583 | 5,527 | -84% | 1 | 1 | 0% | 5,297 | 2,903 | -45% | 0 | 0 | — |
case-15 | fail→pass | 11,185 | 7,937 | -29% | 1 | 1 | 0% | 1,756 | 2,479 | +41% | 0 | 0 | — |
case-16 | fail→pass | 18,642 | 2,436 | -87% | 1 | 1 | 0% | 1,704 | 2,336 | +37% | 0 | 0 | — |
case-17 | fail→pass | 16,833 | 10,317 | -39% | 1 | 1 | 0% | 2,629 | 3,510 | +34% | 0 | 0 | — |
case-18 | fail→pass | 36,071 | 9,117 | -75% | 1 | 1 | 0% | 2,220 | 2,295 | +3% | 0 | 0 | — |
case-19 | fail→pass | 48,693 | 7,846 | -84% | 1 | 1 | 0% | 2,534 | 2,357 | -7% | 0 | 0 | — |
case-20 | pass→pass | 12,279 | 11,530 | -6% | 1 | 1 | 0% | 769 | 3,025 | +293% | 0 | 0 | — |
case-21 | pass→pass | 9,415 | 9,639 | +2% | 1 | 1 | 0% | 835 | 2,731 | +227% | 0 | 0 | — |
case-22 | pass→pass | 12,156 | 5,598 | -54% | 1 | 1 | 0% | 1,225 | 2,879 | +135% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +55 percentage points is the difference between those two pass rates over the 16 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.