Plugins

Architecture

Updated on August 1, 2026

The anatomy of a plugin

A plugin is best understood as a combination of up to three independently deployable elements — a backend and two embedded front-ends — bound together by a shared identity and a shared configuration record. This page describes that anatomy, the identities involved, and the plugin-connection model that scopes a plugin to a tenant. If you have not read the Plugins overview yet, start there.

Plugins are commonly organized as a monorepo so that the elements a plugin does include share tooling, types, and release automation while remaining independently buildable and deployable:

your-plugin/
├── apps/
│   ├── api/        # Backend — REST and/or MCP server (+ optional RTM bridge)   [optional]
│   ├── widget/     # Operator UI embedded in the conversation sidebar (iframe)  [optional]
│   └── settings/   # Tenant-admin configuration page (iframe)                   [optional]
├── packages/       # Shared configs / vendored utilities
└── turbo.json      # Monorepo task pipelines
No single element is mandatory — pick the ones your use case needs. A tools-only plugin ships just a backend (the virtual agent calls it; there is no UI). A conversation-context plugin ships a widget (and often a settings page) and may not need a backend of its own at all. Add the backend when you must read or act on your systems (or expose MCP tools); add the widget when an operator benefits from external data/actions beside the chat; add the settings page when a tenant admin must configure behavior. Every combination is a valid plugin.

The three elements, side by side

Concern Backend (api) Widget Settings
Primary consumer Virtual agent (MCP) + any REST client Human operator, mid-conversation Tenant admin, at install/config time
Runtime Node.js service you host Vue SPA in an iframe Vue SPA in an iframe
Where it renders — (headless) Conversation right sidebar Plugin configuration screen
Talqui contract MCP tools/list/tools/call, REST, RTM postMessage (widget:*, modal:*) postMessage (plugin:*)
Identity used Plugin / PluginConnection token Operator token passed in by the host Operator token + plugin connection
Deep dive Backend Widget Settings

The two front-ends are thin: they hold almost no business logic. They exist to (a) obtain context from the host over the iframe boundary, and (b) call the backend, which owns all integration logic. This keeps the security-sensitive work — credentials to external systems, data transformation, rate limiting — on a server you control, never in a browser.


Plugin identity vs. plugin connection

Two identities exist for every plugin, and understanding the difference is essential before reading the backend and settings pages.

  • Plugin identity — assigned once when your plugin is registered with Talqui: a pluginID and a pluginToken. It represents the extension itself, across all tenants that have installed it. Use it for cross-tenant operations, such as listing installations.
  • Plugin connection — created automatically each time a tenant installs the plugin. It is a first-class record holding a pluginConnectionID, a pluginConnectionToken, and the per-tenant configuration an admin sets in the settings page. It represents the extension scoped to exactly one tenant.
Plugin Architecture

The practical consequence is a clean data-scoping rule, enforced by the authentication scheme (see Authentication):

Question Use this identity Header
"Which tenants installed my plugin?" Plugin Authorization: Plugin base64(pluginID:pluginToken)
"Act within one specific tenant" Plugin connection Authorization: PluginConnection base64(pluginConnectionID:pluginConnectionToken)
A request made with plugin connection credentials returns data only for the tenant that connection belongs to. This isolation is what makes it safe to host many tenants behind one plugin.

The installation lifecycle

A plugin moves through a well-defined lifecycle. The developer owns the left half (build + host + register); the tenant admin and platform own the right half (install + configure + run).

Plugin Install Lifecycle

Each step maps onto later pages: registering and homologation are covered in Getting Started; the install-time configuration screen is covered in Settings; the runtime behavior of the tools and UIs is covered in Backend and Widget.


Deployment topology

A plugin is fully independent infrastructure: you decide where and how each element runs, on any stack, at any scale. Talqui does not host your plugin and imposes no framework, language, or platform on it — it only needs to know where to reach the parts you built.

What Talqui actually requires

The integration contract is deliberately minimal. To register a plugin, you submit a small set of public URLs — nothing else about your hosting matters:

You provide When What Talqui does with it
Backend / API address If your plugin has a backend The base public HTTPS URL of your service. Talqui's virtual agent reaches your MCP endpoint there, and Core reaches your REST routes there. The URL can be anything — any domain, path, or port — as long as it is publicly reachable over HTTPS.
Settings address Only if your plugin ships a settings page The public URL of the settings SPA. Talqui loads it as an iframe inside the plugin configuration screen.
Widget address Only if your plugin ships a widget The public URL of the widget SPA. Talqui loads it as an iframe in the conversation sidebar.
You submit only the addresses for the elements your plugin includes. A backend-only plugin provides just the API address; a UI-only plugin provides just the widget and/or settings address; a full plugin provides all three. There is nothing else to hand over — no build artifacts, no container images, no access to your servers.

Requirements for each element

  • Backend — any runtime that can serve a public HTTPS endpoint works (container host, VPS, serverless-container service, or PaaS). The reference boilerplate targets Node >= 22, but the language and framework are entirely your choice; Talqui only speaks to it over HTTP (MCP + REST) and, optionally, the RTM channel. Keep it reachable and keep your credentials in your host's secret store.
  • Widget / Settings — plain static SPAs, typically served from a CDN or static host. They are loaded as iframes by the Talqui Web App and exchange context over postMessage, so they do not need to be on the same origin as the platform. They must be served over HTTPS so the browser will embed them.

Because every element is reached purely by a URL, you can host them separately (e.g. the API on your cloud, the SPAs on a static host), deploy and roll them back on your own cadence, and scale each independently — all without any coordination with a Talqui release.