Plugin system overview
New tools and project-specific behavior belong in plugins. A plugin is one directory whose package.json is the manifest. It has up to two sides, and either one is optional:
- The agent side is a standard Pi package: Pi extensions, Skills, MCP servers, and CLIs, loaded into the Pi process of each agent you grant. An existing Pi package installs unchanged.
- The platform side runs in one long-lived Node plugin host next to the server. It subscribes to platform events and calls the platform API with a scoped plugin token.
What the host provides
| The host provides | What it means for a plugin |
|---|---|
| Events | Every observation event in the catalog: runs, tasks, nodes, Inbox, questions, sleep, agents, Pi processes, folders, plugins. Events are persisted, acknowledged after the handler returns, retried, and replayed after a restart. Interception, modification, and claim hooks have their own timeouts and fallbacks. |
| State + secrets | Per-plugin persistent state, global or per project. x-secret configuration fields are write-only in the console and masked in plugin logs. |
| Configuration forms | loopNow.configSchema is plain JSON Schema; the console renders it. Fields marked x-scope: project can be overridden per project. |
| Reliable outbound HTTP | The SDK's delivery library keeps a persisted queue, retries with backoff, signs requests with HMAC-SHA256, and writes a delivery log that the plugin page displays. |
| Logs + isolation | Each plugin's output lands in its own log. A plugin that throws, times out, or fails to load affects only itself. |
The manifest is authoritative. Subscribing to an event, or calling an API scope, that the manifest does not declare fails, and install shows the user both sides, the events, and the permissions before anything runs.
Install once, enable per project, grant per agent
Install from the official plugins, a Git repository, an npm package, or a local directory, in the console or with loopctl plugin install. Next, enable the plugin in a project and fill in its configuration. Then grant it to the agents that should load its agent side.
Installing or enabling a plugin never authorizes an agent by itself. Versions are pinned: updating is an explicit action, and running tasks keep the files they started with.
Three official plugins ship with the platform:
- webhook POSTs
inbox.receivedevents to your URL with a signature, retries, and a delivery log. External identities use it instead of polling their Inbox. - playwright gives agents a dedicated, visible Chromium through the official Playwright MCP: open pages, read them, click, type, and take screenshots, without touching your everyday Chrome.
- hello is the smallest plugin with both sides, and the starting point for writing your own.
A platform side in a few lines
import { createDelivery, type PluginAPI } from '@loop-now/plugin-sdk'
export default function register(api: PluginAPI) {
const delivery = createDelivery(api)
api.on('task.completed', async (event) => {
const { url } = api.config.get<{ url?: string }>(event.projectId)
if (url) await delivery.deliver({ target: url, body: event, eventId: event.id, eventType: event.type })
})
}{
"name": "task-notifier",
"version": "1.0.0",
"keywords": ["loop-now-plugin"],
"peerDependencies": { "@loop-now/plugin-sdk": "*" },
"loopNow": {
"id": "task-notifier",
"platform": "./platform.ts",
"events": ["task.completed"],
"permissions": ["state"],
"configSchema": { "type": "object", "properties": { "url": { "type": "string", "x-scope": "project" } } }
}
}The host loads TypeScript directly, as Pi does, and provides @loop-now/plugin-sdk itself. Check a directory with node plugins/host/dist/main.js validate <dir> --load, which reports manifest errors and any subscriptions the code makes outside loopNow.events.
Trust model
There is no sandbox: plugins execute code, so install sources you trust. Trust comes from source grading (official → market-reviewed → arbitrary git/npm/local), the pre-install preview of both sides and permissions, and a one-click global disable.
Going deeper
- Specification — the full contract: package format, event catalog, hook kinds and timeouts, permissions, and installation.
- Publishing to the market — submit your plugin to the official market index.
- SDK reference and the official plugins in the repository.
- Plugin host protocol — the wire protocol between the server and the host.