-
-
Notifications
You must be signed in to change notification settings - Fork 119
Plugin System
CortexPrism supports plugins that extend its capabilities with new tools, UI panels, CLI commands, LLM providers, and middleware.

| Kind | Description | Best For |
|---|---|---|
| ESM | JavaScript/TypeScript modules loaded via import()
|
Most plugins — tools, UI, providers, middleware |
| MCP | Model Context Protocol servers (JSON-RPC) | Wrapping existing MCP servers as tools |
| WASM | WebAssembly modules (any language → WASM) | Performance-critical or multi-language plugins |
# Install from marketplace
cortex marketplace install plugins/slack-bot
# Install from URL
cortex plugins install https://example.com/my-plugin/manifest.json
# Install from local manifest
cortex plugins install ./my-plugin/manifest.json
# List installed plugins
cortex plugins list
# Manage plugins
cortex plugins enable my-plugin
cortex plugins disable my-plugin
cortex plugins update my-plugin
cortex plugins update --all
cortex plugins verify my-plugin
cortex plugins permissions my-plugin
cortex plugins remove my-pluginDISCOVERED → INSTALLED → LOADING → ACTIVE
↓
UNLOADING → REMOVED
Lifecycle hooks:
-
onInstall— plugin first installed -
onLoad— module imported into memory -
onActivate— tools registered, providers bound -
onDeactivate— plugin begins disabling -
onUnload— module unloaded from memory -
onUninstall— database row deleted, files cleaned
Every plugin requires a manifest.json:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "An example plugin",
"kind": "esm",
"entryPoint": "./mod.ts",
"runtime": "deno",
"capabilities": ["tools", "network:fetch"],
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"params": [
{ "name": "city", "type": "string", "description": "City name", "required": true }
]
}
]
}| Capability | Description |
|---|---|
tools |
Register tools in the global agent tool registry |
cli:commands |
Add cortex <name> subcommands |
ui:panel |
Add a Web UI panel/tab |
ui:widget |
Add a dashboard widget |
config:schema |
Extend config schema with new settings |
config:provider |
Register LLM provider factories |
memory:store |
Custom memory backend |
memory:embedder |
Custom embedding provider |
events:listener |
Subscribe to the event bus |
middleware:pre |
Pre-execution middleware |
middleware:post |
Post-execution middleware |
| Level | Sandbox | How assigned |
|---|---|---|
untrusted |
Deno Worker sandbox (minimal perms) | No verification, or blocked/suspicious supply-chain result |
signed |
Deno Worker sandbox | Supply-chain ran but no hash match (unverified) |
trusted |
In-process (full declared perms) | Supply-chain verification passes |
Every lifecycle hook and tool execute receives a PluginContext:
interface PluginContext {
pluginId: string; // Plugin name
pluginDir: string; // ~/.cortex/data/plugins/<name>/
state: PluginStateStore; // Persistent SQLite-backed key-value store
config: PluginConfigStore; // Typed access to ~/.cortex/config.json plugins.<name>
logger: PluginLogger; // Scoped logger — prefixes [plugin:<name>]
host: HostApi; // Register/unregister tools at runtime
}
interface PluginStateStore {
get(key: string): Promise<string | null>;
set(key: string, value: string): Promise<void>;
delete(key: string): Promise<void>;
list(): Promise<Record<string, string>>;
}
interface PluginConfigStore {
get<T = unknown>(key: string): Promise<T | null>;
set<T = unknown>(key: string, value: T): Promise<void>;
getAll(): Promise<Record<string, unknown>>;
}
interface PluginLogger {
info(msg: string): void;
warn(msg: string): void;
error(msg: string): void;
debug(msg: string): void;
}
interface HostApi {
registerTool(tool: Tool): void;
unregisterTool(name: string): void;
}Plugins can intercept the agent's 12-stage execution pipeline by exporting middlewarePre and/or
middlewarePost from their module and declaring middleware:pre / middleware:post in capabilities.
pre-assess → post-assess → pre-reason → post-reason
→ pre-tool (middlewarePre) → post-tool (middlewarePost)
→ pre-llm → post-llm → pre-reflect → post-reflect
→ pre-output → post-output
Hooks receive a PipelineContext and return a HookResult:
interface HookResult {
abort?: { reason: string; message: string }; // aborts the current turn
modifyInput?: string; // replaces user input
modifyLLMResponse?: string; // replaces raw LLM response
modifyOutput?: string; // replaces final output
injectMessages?: Message[]; // appends to conversation history
sideEffects?: SideEffect[]; // log | metric | store | notify
}- Sync hooks time out after 5 s
- Async hooks time out after 15 s
- Plugin middleware hooks run at
priority: 50
See Developing Plugins — Pipeline Hooks for full examples.
Declare events:listener capability and list event types in the manifest events field. Subscribe
via globalEventBus.on(type, handler) in onLoad.
| Event | Payload |
|---|---|
session:start |
{ sessionId: string } |
session:end |
{ sessionId: string } |
tool:pre-execute |
{ toolName: string, args: Record<string, unknown> } |
tool:post-execute |
{ toolName: string, result: unknown } |
llm:pre-call |
{ provider: string, model: string } |
llm:post-call |
{ provider: string, model: string, tokensIn: number, tokensOut: number } |
agent:turn-start |
{ sessionId: string, turnId: string } |
agent:turn-end |
{ sessionId: string, turnId: string, response: string } |
config:change |
{ key: string, value: unknown } |
daemon:status |
{ daemon: string, status: 'up' | 'down' } |
Plugin panels register into named UI slots:
UISlot |
Description |
|---|---|
sidebar |
Left sidebar item |
panel |
Full-page panel/tab |
modal |
Modal overlay |
timeline-item |
Timeline feed entry |
widget |
Dashboard widget |
Panel iframes receive the window.Cortex JavaScript API injected by the host, providing
authenticated fetch, config get/set, event subscription, and host notifications.
window.Cortex.fetch(path, init?) // Authenticated fetch (relative to /api/plugins/<name>/ or absolute)
window.Cortex.getConfig(key) // Promise<unknown>
window.Cortex.setConfig(key, value) // Promise<void>
window.Cortex.onEvent(event, handler) // Subscribe to host events
window.Cortex.emit(event, data) // Emit event to host
window.Cortex.notify(msg, type) // type: 'info' | 'warn' | 'error'Panels can issue structured commands to the host via postMessage:
Command type
|
Effect |
|---|---|
navigate |
Navigate host UI to a route (to: string) |
open-modal |
Open host modal (title: string, content: string) |
notification |
Show notification (text: string, level: string) |
config-get |
Read a config key |
config-set |
Write a config key |
query |
Execute a query |
untrusted and signed plugins run in a Deno Worker sandbox. The sandbox uses JSON-RPC over
postMessage:
- Host spawns
new Worker(entryPoint, { type: 'module', deno: { permissions: ... } }) - Worker must post
{ type: 'ready' }within 30 seconds - Host sends RPC:
{ id, method: 'getTools', params: {} }→ worker returns tool definitions - On tool call:
{ id, method: 'executeTool', params: { toolName, args } }→ worker returnsToolCallResult
Capability → Deno Worker permission mapping:
| Capability | Deno permission |
|---|---|
fs:read, fs:list
|
read: true |
fs:write, fs:edit, fs:delete
|
write: true |
shell:run |
run: true |
network:fetch, net:outbound, net:inbound
|
net: true |
WASM plugins received major upgrades in v0.52.0:
-
ABI versioning —
plugin_get_abi_version()/host_get_abi_version()for forward/backward compatibility -
Linear memory allocator — bump allocator with
host_alloc/host_freehost functions, bounds-checked with auto-grow -
Synchronous HTTP —
host_http_requestblocks via dedicated Worker + SharedArrayBuffer + Atomics.wait (30s timeout) -
Permission enforcement —
host_http_requestgates onnetwork:fetchornet:outboundcapability - Execution timeouts — 120-second maximum per tool execution
-
Tool parameter schemas —
params[]with name, type, description, and required fields - PluginContext integration — WASM plugins access logging, state persistence (SQLite-backed), and configuration
-
Supply-chain binary scanning —
scanWasmBinary()detects suspicious imports, excessive memory, and version mismatches -
C SDK — C-compatible header (
wasm-plugin.h) and TypeScript client library (client.ts)
Admins can grant or deny capabilities per-plugin beyond manifest declarations. Overrides are stored
in plugins.db and merged at load time:
effective = declared − denied + granted
REST: POST /api/plugins/:name/permissions with { permission_path, action: 'grant'|'deny', value }
| File | Purpose |
|---|---|
types.ts |
Core plugin types, capabilities, lifecycle interfaces |
manager.ts |
Plugin lifecycle manager (enable/disable/reload) |
registry.ts |
Plugin registry and database CRUD |
loader.ts |
ESM / MCP / WASM module loader |
install.ts |
Installation from marketplace/URL/local manifest |
update.ts |
Update checking, version enrichment from GitHub |
permissions.ts |
Permission resolution and Deno Worker perm derivation |
integrity.ts |
SHA-256 hash verification |
supply-chain.ts |
Full supply-chain: hash, signature, reputation, malware scan |
sandbox.ts |
Deno Worker sandbox with JSON-RPC bridge |
events.ts |
EventBus class + globalEventBus singleton |
deps.ts |
Semver dependency resolution, topological sort, circular detection |
context.ts |
createPluginContext() — builds the PluginContext for each plugin |
namespace.ts |
@author/name scoping, tool name resolution, alias management |
ui-slots.ts |
UI slot registration, window.Cortex API generation |
wasm-runtime.ts |
WebAssembly host functions, ABI versioning, linear allocator, sync HTTP via Worker, state persistence, permission enforcement, diagnostics |
wasm-worker-http.ts |
Dedicated Worker thread for synchronous WASM HTTP via SharedArrayBuffer + Atomics.wait |
sdk/wasm-plugin.h |
C-compatible header declaring all host functions, memory layout, required exports |
sdk/client.ts |
TypeScript helper library — defineTool(), definePlugin(), generateCapabilitiesJson(), generateWasmPluginModule() |
extensions/cli.ts |
Cliffy command builder for plugin CLI subcommands |
extensions/provider.ts |
LLM provider factory registry |
extensions/config.ts |
Config schema extension |
extensions/ui.ts |
CortexUiApi, panel JS/HTML generation |
dependency-guardian.ts |
Continuous CVE monitoring, remediation suggestions |
verifyPluginIntegrity() runs before every plugin install:
-
SHA-256 hash check against known-good hashes per
package@version - Blocked hash list — known-malicious hashes are rejected outright
- Digital signature verification — optional GPG signature validation
- Author reputation scoring — 0–100 score; configurable blocked/allowed author lists
-
Malware pattern scanning — 6 default patterns:
eval,child_process,rm -rf /,curl|sh,wget|sh
blockSuspicious mode rejects suspicious plugins. requireKnownHash defaults to false for
community marketplace compatibility.
src/plugins/deps.ts provides:
- Semver constraint satisfaction (
^,~,>=,*operators) - Topological sort for install ordering
- Circular dependency detection
- Transitive dependency traversal
installPlugin() validates dependencies before install and returns missing dependency and warning lists.
POST /api/plugins/:name/verification — re-runs supply-chain check, persists the report
GET /api/plugins/:name/verification — retrieves stored report with color-coded trust badges
- Developing Plugins — Full development guide (tools, hooks, pipeline, sandbox, UI API)
- Manifest Reference — Complete manifest schema with all field types
- Plugin Best Practices — Design principles and what to avoid
- Publishing Plugins — Submit to the marketplace
- Pipeline Hooks — Full agent pipeline hook reference
CortexPrism — Open-source AI agent operating system · Discord · Apache 2.0 License · Built with Deno 2.x + TypeScript
- Agent Loop
- Built-in Agents
- Metacognition
- Memory System
- Skills System
- Sub-Agents
- Built-in Tools
- Code Intelligence
- Code Sandbox
- Cross-Agent Context Protocol
- Prompt Lab
- PKM Assistant
- Voice Pipeline
- Computer Use
- Browser Tool
- Git & GitHub
- Scheduler & Jobs
- Dashboard
- Observability
- A2A Protocol
- MCP Gateway
- Distributed Nodes
- Memori Checkpoints
- Eval System
- Workflow Engine
- Triggers
- Projects
- TUI
- Glossary
- Update System
- Chrome Bridge
- Swarm
- AgentLint
- Model Benchmarking
- Smart Context
- Cost Optimizer