
Persona.js
Add WebMCP-native AI chat to any Frontend
553 followers
Add WebMCP-native AI chat to any Frontend
553 followers
Persona is a lightweight, open-source AI chat UI library that embeds into any website, from modern apps to static HTML. Unlike React-based chat frameworks, Persona is framework-free, backend-agnostic, and WebMCP-native, so your assistant can discover and execute tools exposed by the parent page. Add streaming chat, voice, theming, and interactive copilot experiences without rebuilding your frontend or writing bespoke APIs.








Active-tools-reflecting-app-state is a cleaner answer than I expected, since the menu shrinks with the app instead of sitting wide open. The thing I'd watch from building agent loops: that same liveness means a tool the model planned to call two steps ago can quietly vanish when state changes under it, so a half-formed plan goes invalid mid-run. Do you surface that disappearance back to the model as a signal it can re-plan on, or does the call just fail when it reaches for the tool?
Persona.js
@dipankar_sarkar within a run, the model plans against a snapshot taken at dispatch, so there's no mid-run "tool vanished" notification, but if a tool unregisters before execution, the bridge re-reads the live registry and returns a structured isError result like:
Then the model can re-plan on in the same run without aborting.
Every client-side failure mode (unregistered, allowlist-excluded, user-declined, timeout) resolves this way, and the next turn re-snapshots the registry so the advertised toolset re-converges with app state within one turn.
The WebMCP bet makes sense and drop-in on existing sites looks like the unlock! One thing we keep hitting building agents - the token-efficiency win can flip once a page exposes 20+ tools, since every schema rides in context each turn. As far as I understand Persona could send the model the full tool list or filter to a relevant subset first to decide if the headless-browser comparison holds at scale. Anyways, congrats on the great product
Persona.js
@artstavenka1 Thanks! And yeah, since Persona picks up changes to WebMCP tools on the frontend, you can technically change what tools are registered based on the context you have in your FE. It's another way to optimize tokens over the wire.
What we've found is when you can interact with the existing app more, via the FE calls, it can cut down on what is necessary to send through the LLM as well. If you dive into the hooks.
For instance, you can have a tool call that is a lightweight "get_cart", then Persona calls that registered tool on the FE, however instead of passing it back to the LLM you decide to manually inject a new message with the API data via Persona's window API. It gives you a much faster experience while spending 0 tokens to render the result, since you created the response yourself.
The boundary I’d want to inspect in every WebMCP app is the receipt after a mutative step, not just the approval before it.
Tool name, page/app context, inputs used, approval, result, and whether it can be undone. That’s what makes the action feel debuggable instead of magical.
Persona.js
@blah_mad sounds like you've built something real before :)
So while Persona does have built-in event debugging in the UI you can optionally turn on (screenshots attached), there is also a deeper set of JS events you can listen to for messages, results, approvals etc in a lot more detail: https://github.com/runtypelabs/persona/blob/main/packages/widget/docs/PROGRAMMATIC-CONTROL.md?plain=1#L562
The messages in particular seem to be right up your alley for the deep debugging use case:
You'd get that info by hooking into Persona init and watching for the assistant messages:
Persona.js
@blah_mad your question made me realize we could have docs specifically related to tracking the mutations via these events, so I added it: https://github.com/runtypelabs/persona/blob/main/packages/widget/docs/PROGRAMMATIC-CONTROL.md?plain=1#L758
Thanks again!
WebMCP support out of the box is a massive selling point, the biggest headache right now is avoiding massive token usage for simple frontend states. congrats for shipping @runtypical👏 qq. does the built-in polyfill handle older browser fallbacks gracefully, or is there a performance hit we should watch out for?
Persona.js
@vikramp7470 great question - the polyfill is both lazy-loaded and defensive; it won't waste any resources at all if WebMCP is already discovered on the page, even if it's from another polyfill. In fact, the entire initial page weight of Persona is only about ~15kb, to minimize the performance hit when embedding.
@runtypical Great to know, appreciate the transparency on performance...
The framework-agnostic approach is what caught my attention - most chat UIs are React-first, which quietly locks your architecture. The WebMCP-native integration is the right bet as MCP becomes the standard interface layer for AI tools. Quick question: how does Persona handle auth context when the MCP server needs user-specific permissions? Does the host page manage that entirely, or is there a mechanism built into the library for passing tokens through?
Persona.js
@galdayan Great question! There are essentially two paths, which you can blend together based on where the auth checks already are.
1) Handling auth context on the API side. Usually you are already streaming LLM / AI framework calls through the backend so the state of the user is already available. Persona has examples of using a proxy to do this in the repo as well.
2) Using WebMCP to respect the auth context automatically. Since the tools are being called on the frontend when you use WebMCP, you can pass the signed in user's identity as part of the existing function calls. If your app's frontend works with signed in context today, you might not need additional backend work.
Lancepilot
Persona.js
@odeth_negapatan1 thanks! And yeah, we have tested on WordPress and Shopify. Persona drops in great there because you can use the script tag (CDN) deployment which doesn’t need a build step. All the init and theme configuration can be set in script tag data params.
We spent a lot of time determining the right loading methods for each type of site. Getting the different methods working in the same library while keeping the bundle size tiny, without regressions in functionality, was not easy.
This is great, just at the right time. This could make chat widgets as easy to add to existing websites as including a new Google Font or FontAwesome. And the WebMCP is great so other agents can use the site. Makes it extremely useful. Quick question, can you set up token limits, per visitor/user?
Persona.js
@jn263 thanks! The token limits could technically be set up by listening events Persona fires and preventing messages from being sent in a session past a certain amount.
That of course would need to be enforced in the backend as well if you wanted to really prevent it!
@_becomevocal_ That's one of the things I think can really make or break a product like this. Some sort of guardrail that will keep the conversation on topic and prevent skyrocketing API costs.