Skip to content

Use case

Embedded Portal With Page Tools ​

Embed a Console portal as a chat bubble in your product, sign visitors in with your own identity token, and let the agent act on the page.

  • Stack Console (Enterprise) + your web app
  • Pattern Chat · Widget
  • Read ~6 min

Overview ​

Your product already knows who the user is. An embedded portal lets that identity flow into a Console agent without a second login, and lets the agent call page tools: functions your page exposes, such as reading the cart or opening a ticket.

Enterprise module

Portals and embedding are part of the enterprise edition and need an enterprise licence. On SaaS the host page must be served over https; http://localhost works as an allowed site only on development and self-hosted installations.

Run the example ​

Runnable code for this pattern is public on GitHub:

Architecture ​

Your server signs a short-lived identity token (HS256) for the signed-in user. The claims are iss (exactly the Issuer set on the portal's Embed tab), aud = cognipeer-portal:<portal key>, sub, iat, exp, a fresh jti (a token works once), and optional email, email_verified, name, groups and ctx. The signing secret never leaves the server.

The widget (/api/embed/portal.v1.js on your Console) is mounted in the browser with a getToken callback and the page tools.

Console checks the allowed sites, verifies the token, maps the person to a member, and runs the portal's agent. Page tools run in the visitor's browser and are only offered to agents that have May use the page's tools switched on in the portal.

1. Mint The Token On Your Server ​

typescript
import { SignJWT } from "jose";

export async function mintToken(user: { id: string; email: string; name: string }) {
  return new SignJWT({ email: user.email, email_verified: true, name: user.name })
    .setProtectedHeader({ alg: "HS256", kid: process.env.EMBED_KEY_ID! })
    .setIssuer(process.env.EMBED_ISSUER!)
    .setAudience(`cognipeer-portal:${process.env.COGNIPEER_PORTAL}`)
    .setSubject(user.id)
    .setIssuedAt()
    .setExpirationTime("120s")
    .setJti(crypto.randomUUID())
    .sign(new TextEncoder().encode(process.env.EMBED_SECRET!));
}

Return a new token on every request to your token route. Do not cache it, or Console rejects the second exchange as replayed.

2. Declare The Page Tools In Console ​

On the portal's Embed tab, add each tool under Tools in your page with a description, an input schema, Wait for the page, and Ask the person first. Use Ask the person first for any tool that changes the page. Then turn on May use the page's tools for the agent in the portal's Chat features tab, and give the agent instructions that say when to use each tool.

3. Mount The Widget ​

The example mounts CognipeerPortal in bubble mode with getToken, the tool handlers, optional context, event listeners, and a logout() call when the user signs out. Handlers should validate their arguments before touching the page.

Security Notes ​

A page tool result is typed in the person's browser, so the agent treats it as untrusted. Never return an authorization decision from a tool. Put trusted facts in the signed ctx claim and enforce permissions on your server. The context passed to mount is unsigned page information, not identity.

Result ​

An in-product assistant that knows the signed-in user and can act on the current page, with approvals where it matters.

See every pattern on the use case index, or browse all Cognipeer libraries.

Studio · Pulse · Console · Agent SDK and more — the Cognipeer documentation hub