Host · Chat
The Plugin Panel Inside Chat
Active plugins are surfaced in the sidebar. Each plugin exposes UI slots, instruction Skills, and callable Tools through one validated manifest. The host core never imports plugin-specific code directly.
Bundled Skills
A manifest
skills[] entry installs a verified SKILL.md instruction bundle. Natural-language text never invokes or preloads a Tool implicitly.ui[] slots
plugin.json's
ui[] declares slot (sidebar/chat/popover/embedded) · kind (embedded-module/url) · entry · exportName · window.Tools list
Tools are statically declared in the manifest's
tools[]. Handlers live in the RuntimePlugin.handlers map. Tool name regex: ^[a-zA-Z_][a-zA-Z0-9_]*$.Naming conventions — three namespaces
- LLM tool names:
^[a-zA-Z_][a-zA-Z0-9_]*$(src/plugins/runtime/manifest-validation.ts). No leading digits or dashes — a common vendor requirement (OpenAI / Gemini / Claude alike). - Skill / agent / session id: separate —
^[a-zA-Z0-9_-]+$(src/main/skill-store.ts). Dashes allowed. - Plugin id: typically kebab-case (e.g.
local-indexer,ms-graph). The manifest'sidfield.
Plugin tools come from the manifest
The host runs each plugin as an in-process MCP server and reads the tool list that server offers into the Tool Registry. The server is projected straight from the plugin manifest (
src/mcp/plugin-server-projection.ts), and the wiring happens during boot (src/mcp/plugin-loopback-manager.ts · src/boot/steps/plugin-runtime.ts).That list is fixed per server generation
A plugin's server does not advertise that it will announce list changes — it has no channel to send the notification on, so it reports
listChanged: false (src/mcp/plugin-server-projection.ts). Changing a plugin's tools means redeploying it and bringing its server up again.External MCP servers differ — an external server can send a list-changed notification, and on receiving one the host re-fetches the tool list (src/mcp/mcp-client.ts).