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
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
pluginIDand apluginToken. 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, apluginConnectionToken, and the per-tenant configuration an admin sets in the settings page. It represents the extension scoped to exactly one tenant.
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) |
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).
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. |
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.