-
-
Notifications
You must be signed in to change notification settings - Fork 119
Manifest Reference
Complete schema reference for manifest.json. All types match the PluginManifest interface in
src/plugins/types.ts.
{
"name": "my-plugin", // required — kebab-case, unique across marketplace
"version": "1.0.0", // required — semver (MAJOR.MINOR.PATCH)
"description": "Short description", // required
"kind": "esm", // required — "esm" | "mcp" | "wasm"
"entryPoint": "./mod.ts", // required — relative path, absolute path, or URL
"runtime": "deno", // required — "deno" | "wasm"
"capabilities": ["tools", "network:fetch"], // required — see Capabilities below
"author": "acme", // optional
"homepage": "https://example.com",
"license": "MIT", // SPDX identifier recommended
"repository": "https://github.com/acme/my-plugin",
"hash": "sha256:<hex>", // SHA-256 of plugin files for supply-chain verification
"signature": "<base64>", // Digital signature (optional, GPG)
"dependencies": { "other-plugin": "^1.0.0" }, // semver constraints
"peerDependencies": { "auth-plugin": ">=2.0.0" },
"events": ["session:start", "llm:post-call"], // event types to subscribe to
"tools": [ /* ToolDeclaration[] */ ],
"cliCommands": [ /* CliCommandDeclaration[] */ ],
"ui": { /* UiContribution */ },
"config": { /* ConfigContribution */ }
}| Field | Type | Rules |
|---|---|---|
name |
string |
kebab-case, unique across marketplace |
version |
string |
Valid semver, e.g. 1.2.3
|
description |
string |
Short one-line description |
kind |
"esm" | "mcp" | "wasm"
|
Plugin runtime kind |
entryPoint |
string |
Relative path (resolved to absolute on install), absolute path, or URL (file://, https://, jsr:, npm:) |
runtime |
"deno" | "wasm"
|
Execution target |
capabilities |
PluginCapability[] |
Declared permissions and extension points |
| Field | Type | Description |
|---|---|---|
author |
string |
Author username (forms the @author/ namespace) |
homepage |
string |
Plugin homepage URL |
license |
string |
SPDX license identifier (e.g. MIT, Apache-2.0) |
repository |
string |
Source repository URL |
hash |
string |
SHA-256 hash of plugin files (sha256:<hex>) — used for supply-chain verification |
signature |
string |
Base64-encoded digital signature |
dependencies |
Record<string, string> |
Required plugin names → semver constraints (^1.0, >=2.0, *) |
peerDependencies |
Record<string, string> |
Compatible peer plugin names → constraints |
events |
string[] |
Event type names to subscribe to — requires events:listener capability |
tools |
ToolDeclaration[] |
Tool declarations (informational; actual tools come from mod.ts exports) |
cliCommands |
CliCommandDeclaration[] |
CLI subcommand declarations |
ui |
UiContribution |
UI panels, widgets, settings fields |
config |
ConfigContribution |
LLM provider registrations and config defaults |
interface ToolDeclaration {
name: string;
description: string;
params: {
name: string;
type: string; // 'string' | 'number' | 'boolean' | 'object' | 'array'
description: string;
required?: boolean;
enum?: string[]; // restrict string params to allowed values
}[];
}interface CliCommandDeclaration {
name: string; // becomes 'cortex <name>'
description: string;
args?: { // positional arguments
name: string;
type: string; // 'string' | 'number' | 'boolean'
description: string;
required?: boolean;
}[];
options?: { // named flags
name: string; // --<name>
type: string; // 'string' | 'number' | 'boolean'
description: string;
flag: string; // short flag, e.g. '-v'
}[];
}The handler is the default export or a named export matching decl.name (camelCase) from
the plugin module. It receives args: Record<string, unknown> where keys are option/arg names.
interface UiContribution {
panels?: {
id: string; // unique within plugin, used in URL: /api/plugins/<name>/panel/<id>
title: string; // tab/nav label
icon?: string; // icon name (Lucide icon or emoji)
htmlPath: string; // path relative to manifest to the panel HTML file
}[];
widgets?: {
id: string;
title: string;
type: 'html' | 'chart' | 'table';
config: Record<string, unknown>;
}[];
settings?: {
section: string; // settings section heading
fields: UiSettingField[];
}[];
}interface UiSettingField {
key: string; // read via ctx.config.get(key)
label: string; // display label in settings UI
type: 'text' | 'number' | 'boolean' | 'select' | 'secret';
defaultValue: unknown;
options?: { label: string; value: string }[]; // for type: 'select'
description?: string; // optional help text shown below the field
}Setting type reference:
type |
Input | Notes |
|---|---|---|
text |
Text input | Free-form string |
number |
Number input | Stored as number |
boolean |
Toggle/checkbox | Stored as boolean |
select |
Dropdown | Requires options array |
secret |
Password input | Stored encrypted, masked in UI |
interface ConfigContribution {
providers?: {
kind: string; // provider identifier, matches key in module 'providers' export
label: string; // display name in provider selection UI
defaultModel: string; // default model name
}[];
settings?: Record<string, unknown>; // default config values
}| Capability | Module export required | Description |
|---|---|---|
tools |
tools: Tool[] |
Register tools in the agent tool registry |
cli:commands |
cliCommands or named handler |
Add cortex <name> subcommands |
ui:panel |
— (manifest ui.panels) |
Add a Web UI panel/tab |
ui:widget |
— (manifest ui.widgets) |
Add a dashboard widget |
config:schema |
— | Extend config schema with new settings |
config:provider |
providers: Record<string, ProviderFactory> |
Register LLM provider factories |
memory:store |
— | Custom memory backend (reserved for future use) |
memory:embedder |
— | Custom embedding provider (reserved) |
events:listener |
globalEventBus.on(...) in onLoad
|
Subscribe to the event bus |
middleware:pre |
middlewarePre export |
Hook into pre-tool pipeline stage |
middleware:post |
middlewarePost export |
Hook into post-tool pipeline stage |
| Capability | Deno Worker permission | What it grants |
|---|---|---|
fs:read |
read: true |
Read files from the filesystem |
fs:list |
read: true |
List directory contents |
fs:write |
write: true |
Write files |
fs:edit |
write: true |
Edit existing files |
fs:delete |
write: true |
Delete files |
fs:search |
— | Search file contents (policy-gated) |
shell:run |
run: true |
Execute shell commands |
network:fetch |
net: true |
Make outbound HTTP/HTTPS requests |
net:outbound |
net: true |
General outbound network access |
net:inbound |
net: true |
Accept inbound connections |
db:read |
— | Read from internal databases (policy-gated) |
db:write |
— | Write to internal databases (policy-gated) |
Declare only the capabilities your plugin actually uses. The effective permissions at runtime are
declared − admin_denied + admin_granted.
TypeScript/JavaScript module loaded via Deno's import(). Entry point must be an absolute path
or a URL (file://, https://, jsr:, npm:). Relative paths in the manifest are resolved
to absolute during installation.
Exports: tools, providers, cliCommands, onLoad, onUnload, onInstall, onActivate,
onDeactivate, onUninstall, onConfigChange, middlewarePre, middlewarePost
Wraps an external JSON-RPC 2.0 server. entryPoint must be an https:// URL pointing to the
server. CortexPrism creates a synthetic tool named mcp_<name> that proxies calls:
POST <entryPoint>
{ "jsonrpc": "2.0", "id": 1, "method": "<tool.name>", "params": { ... } }
The server must respond with { "jsonrpc": "2.0", "id": 1, "result": { ... } }.
WebAssembly binary. entryPoint can be a relative path to a .wasm file or an https:// URL.
Memory: initial: 256 pages (16 MiB), maximum: 512 pages (32 MiB). Tools execute in a dedicated
Worker with 120 s timeout. HTTP requests have 30 s individual timeout and are gated on
network:fetch/net:outbound capability.
ABI Version 1. Plugin must export plugin_get_abi_version() returning 1. Host rejects
incompatible versions on load.
Memory layout:
[0x000000 - 0x00FFFF] Host scratch area (64 KB)
[0x010000 - 0x01FFFF] Host allocator metadata (64 KB)
[0x020000 - 0x0FFFFF] Host-managed heap (896 KB) — host_alloc/host_free
[0x100000 - ...] Plugin memory (__heap_base = 0x100000)
Required WASM exports:
| Export | Signature | Required | Purpose |
|---|---|---|---|
plugin_get_abi_version |
() → i32 |
Yes | Return supported ABI version (must match host) |
plugin_init |
() → void |
No | Called once on load |
plugin_destroy |
() → void |
No | Called on unload — cleanup |
plugin_get_capabilities |
(outPtr: i32, outLenPtr: i32) → i32 |
Yes | Return JSON capabilities with param schemas |
plugin_execute_tool |
(namePtr, nameLen, argsPtr, argsLen, outPtr, outLenPtr) → i32 |
Yes | Execute a tool |
memory |
WebAssembly.Memory |
Yes | Shared linear memory |
Capabilities JSON must include full parameter schemas so LLMs understand tool signatures:
{
"abi_version": 1,
"tools": [{
"name": "my_tool",
"description": "Does something",
"params": [
{ "name": "input", "type": "string", "description": "Input", "required": true },
{ "name": "limit", "type": "number", "description": "Max results", "required": false }
]
}]
}Host import functions (available as env.*):
| Function | Signature | Description |
|---|---|---|
host_alloc |
(size: i32) → i32 |
Allocate from host-managed heap |
host_free |
(ptr: i32) → void |
Free allocation |
host_log |
(ptr: i32, len: i32) → void |
Log message to CortexPrism |
host_get_config |
(keyPtr, keyLen, outPtr, outLenPtr) → i32 |
Read CORTEX_PLUGIN_{NAME}_{KEY} or CORTEX_WASM_{KEY} env var |
host_set_state |
(keyPtr, keyLen, valPtr, valLen) → void |
Persist state (in-memory + SQLite) |
host_get_state |
(keyPtr, keyLen, outPtr, outLenPtr) → i32 |
Read persisted state |
host_http_request |
(methodPtr, methodLen, urlPtr, urlLen, bodyPtr, bodyLen, headersPtr, headersLen, outStatusPtr, outBodyPtr, outBodyLenPtr) → i32 |
Synchronous HTTP (Worker + Atomics.wait, 30 s timeout, gated on network:fetch) |
host_get_abi_version |
() → i32 |
Returns host ABI version |
host_get_time_ms |
() → i64 |
Current time in ms |
host_random |
(outPtr: i32, len: i32) → void |
Cryptographically random bytes |
All strings are UTF-8 in linear memory. Return 0 on success, non-zero on error. Output is written
to outPtr/outLenPtr.
| Export name | Type | Capability required |
|---|---|---|
tools |
Tool[] |
tools |
providers |
Record<string, ProviderFactory> |
config:provider |
cliCommands |
CliCommandDeclaration[] |
cli:commands |
onInstall |
(ctx) => Promise<void> |
— |
onLoad |
(ctx) => Promise<void> |
— |
onActivate |
(ctx) => Promise<void> |
— |
onDeactivate |
(ctx) => Promise<void> |
— |
onUnload |
(ctx) => Promise<void> |
— |
onUninstall |
(ctx) => Promise<void> |
— |
onConfigChange |
(key, value, ctx) => Promise<void> |
— |
middlewarePre |
(ctx: unknown) => Promise<HookResult> |
middleware:pre |
middlewarePost |
(ctx: unknown) => Promise<HookResult> |
middleware:post |
| Event | Payload | Notes |
|---|---|---|
session:start |
{ sessionId: string } |
New chat session |
session:end |
{ sessionId: string } |
Session ended |
tool:pre-execute |
{ toolName: string, args: Record<string, unknown> } |
Before any tool |
tool:post-execute |
{ toolName: string, result: unknown } |
After any tool |
llm:pre-call |
{ provider: string, model: string } |
Before LLM API call |
llm:post-call |
{ provider: string, model: string, tokensIn: number, tokensOut: number } |
After LLM API call |
agent:turn-start |
{ sessionId: string, turnId: string } |
Start of agent turn |
agent:turn-end |
{ sessionId: string, turnId: string, response: string } |
End of agent turn |
config:change |
{ key: string, value: unknown } |
Config key changed |
daemon:status |
{ daemon: string, status: 'up' | 'down' } |
Daemon started/stopped |
Requires events:listener capability. Must also list subscribed types in manifest events field.
interface ToolCallResult {
toolName: string; // must match tool definition name
success: boolean;
output: string; // serialize objects with JSON.stringify
error?: string; // human-readable error message when success is false
durationMs: number; // wall-clock execution time in milliseconds
}- Developing Plugins — Full development guide with examples
- Plugin System — Architecture, trust levels, sandbox, permission overrides
- Plugin Best Practices — Design principles and what to avoid
- Publishing Plugins — Marketplace submission
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