The plugin.json is the complete descriptor of a Chattree plugin.
Chattree reads it before executing any WASM code.
{
"schemaVersion": 1,
"id": "com.example.my-plugin",
"version": "1.2.0",
"minAppVersion": "1.0.0",
"name": "My Plugin",
"description": "Short description shown in the plugin list.",
"author": "Your Name",
"authorEmail": "you@example.com",
"homepageUrl": "https://github.com/you/my-plugin",
"primaryCommand": "myplugin",
"aliases": ["mp", "myplugin"],
"type": "imported",
"capabilities": ["network.http", "storage.private"],
"optionalCapabilities": ["notifications.send"],
"tags": ["utility", "network"],
"changelog": "1.2.0: Added optional notification support.",
"runtime": "wasm",
"entrypoint": "run",
"wasmPath": "plugin.wasm",
"wasmSha256": "a1b2c3d4e5f6...",
"runtimeApiVersion": "1.0.0",
"maxMemoryPages": 4,
"timeoutMs": 5000,
"fuelLimit": 50000000,
"tools": [
{
"id": "com.example.my-plugin.run",
"command": "myplugin",
"displayName": "My Plugin",
"description": "Does something useful: /myplugin <input>",
"capabilities": ["network.http"]
}
],
"settings": [
{
"key": "api_endpoint",
"label": "API Endpoint",
"type": "string",
"defaultValue": "https://api.example.com",
"description": "The remote API to call."
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion | integer | ✅ | Manifest schema version (1 for standard plugins, or 2 when declaring inboundWebhooks / eventConsumers). |
id | string | ✅ | Reverse-domain unique ID. E.g. "com.example.my-plugin". Must be globally unique and not match a reserved internal ID. |
version | string | ✅ | Semantic version: "MAJOR.MINOR.PATCH". E.g. "1.0.0". |
minAppVersion | string | ❌ | Minimum Chattree version required. Omit if unknown. |
id constraints:
com.you.plugin).com.chattree.note, com.chattree.reminder, com.chattree.visual, com.chattree.weather, com.chattree.translate, com.chattree.calendar, com.chattree.internal).| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Human-readable plugin name shown in settings. |
description | string | ✅ | One-line description for the plugin list. |
author | string | ✅ | Author name. |
authorEmail | string | ❌ | Contact email. |
homepageUrl | string | ❌ | Plugin homepage or repository URL. |
tags | string[] | ❌ | Keywords used for discovery metadata. |
changelog | string | ❌ | Human-readable release notes. |
| Field | Type | Required | Description |
|---|---|---|---|
primaryCommand | string | ✅ | Main slash-command (without /). E.g. "hello" → /hello. |
aliases | string[] | ❌ | Additional command aliases. E.g. ["h", "hi"]. |
type | string | ✅ | Must be "imported" for third-party plugins. |
primaryCommand constraints:
| Field | Type | Required | Description |
|---|---|---|---|
capabilities | string[] | ❌ | Capability IDs required by this plugin. See capabilities.md. |
optionalCapabilities | string[] | ❌ | Capabilities the plugin can use if available, but does not strictly require. |
allowedNotificationPackages | string[] | ❌ | Whitelist of application package IDs permitted for notification access (e.g. ["com.whatsapp", "com.google.android.gm"] or ["*"]). Enforced strictly across Push, EventBus, and Host APIs whenever notifications.read, notifications.query, notifications.reply, or notifications.action is requested. If omitted, access is denied by default ([]). |
Examples:
"capabilities": ["notifications.read", "notifications.reply", "notifications.action"],
"allowedNotificationPackages": ["com.whatsapp", "org.telegram.messenger"]
Do NOT list capabilities or packages you do not use. Users see every item in the permission dialog.
Each entry in tools declares one slash-command exposed by the plugin.
| Field | Type | Required | Description |
|---|---|---|---|
tools[].id | string | ✅ | Unique tool ID. Convention: "<pluginId>.<command>". |
tools[].command | string | ✅ | Slash-command keyword (without /). |
tools[].entrypoint | string | ❌ | Optional per-tool WASM exported function name. Overrides the top-level entrypoint for this specific tool. |
tools[].displayName | string | ✅ | Label in the slash-menu. |
tools[].description | string | ✅ | One-line description in the slash-menu. |
tools[].capabilities | string[] | ❌ | Per-tool capability subset (merged with top-level). |
tools[].intentContract | object | ❌ | Declarative intent schema for conversational AI invocation without typing /. |
intentContract)Plugins can declare an optional intentContract inside any tool definition. When declared, Chattree's intent resolution engine allows the model to automatically invoke the tool in conversational natural language without requiring the user to type the explicit / slash command:
"intentContract": {
"intent": "check_status",
"description": "Triggered when the user asks to check cluster, service, or server health",
"fields": [
{
"name": "target",
"type": "string",
"description": "Cluster, service name, or endpoint (e.g. 'prod', 'auth')",
"required": false
}
],
"maxResponseTokens": 100
}
| Field | Type | Required | Description |
|---|---|---|---|
runtime | string | ✅ | Must be "wasm" for WebAssembly plugins. |
entrypoint | string | ✅ | Exported WASM function name Chattree will call. |
wasmPath | string | ✅ | Path to the WASM binary inside the archive. Always "plugin.wasm". |
wasmSha256 | string | ✅ | SHA-256 hex digest of plugin.wasm (64 hex chars). |
runtimeApiVersion | string | ✅ | Must be "1.0.0". |
maxMemoryPages | integer | ❌ | WASM memory ceiling in 64 KiB pages. Runtime default: 512 pages (32 MiB); accepts up to 1024 pages (64 MiB). |
maxPayloadSizeBytes | integer | ❌ | Maximum request/response payload size in bytes (ABI v2). Default: 12 MiB (12582912 bytes); maximum: 16 MiB. |
outputOffset | integer | ❌ | Static output memory offset in bytes for legacy ABI v1 plugins. Default: 1024. Increase this (e.g. 32768) to expand ABI v1 input capacity. |
inputOffset | integer | ❌ | Static input memory offset in bytes for legacy ABI v1 plugins. Default: 0. |
timeoutMs | integer | ❌ | Per-call timeout in milliseconds. Runtime default: 5000; current validators accept up to 60000. Keep calls short and test on device. |
fuelLimit | integer | ❌ | Instruction fuel budget. Default: 50 000 000. |
Memory sizing guide:
| Use case | Recommended maxMemoryPages |
|---|---|
| Text-only processing | 2 (128 KB) |
| Moderate JSON parsing | 4–16 (256 KB – 1 MB) |
| Image processing / large responses | 64–256 (4 MB – 16 MB) |
Chattree will reject modules that exceed
maxMemoryPagesat load time. When authoring WAT directly, always specify both initial and maximum page bounds (e.g.,(memory (export "memory") 8 8)). Chattree's Wasmtime engine uses dynamic memory sizing (staticMemoryMaximumSize: 0) and immediately disposes eachWasmInstanceafter execution so virtual address space is never retained across calls.
schemaVersion: 2, optional)Plugins that react to device notifications (device.notification.received, device.notification.updated), scheduled tasks (scheduler.trigger), or inbound webhooks declare eventConsumers:
| Field | Type | Required | Description |
|---|---|---|---|
eventConsumers[].id | string | ✅ | Unique consumer identifier within the plugin. |
eventConsumers[].eventTypes | string[] | ✅ | Explicit event types to subscribe to (wildcards * are rejected). |
eventConsumers[].targetAction | string | ✅ | Exact tools[].id invoked when a matching event is dispatched. |
eventConsumers[].filter | object | ❌ | Declarative pre-filter evaluated by EventFilterMatcher before instantiating WASM. Supports scalar equality, arrays, boolean guards (excludeOngoing, excludeFromMe, excludeGroupSummary), and operator objects (in, notIn, contains, containsAny, regex, not). |
eventConsumers[].requiredPermissions | string[] | ❌ | Capabilities required before the event delivery is dispatched. |
The manifest parser accepts an optional settings array with declarative field metadata (key, label, type, defaultValue, description, options, isSecret) rendered in Settings → Plugins → [Plugin] when configured.
| Field | Type | Required | Description |
|---|---|---|---|
settings[].key | string | ✅ | Storage key. |
settings[].label | string | ✅ | UI label. |
settings[].type | string | ✅ | "string", "boolean", "number", or "select". |
settings[].defaultValue | string | ❌ | Default value string. |
settings[].description | string | ❌ | Help text shown under the field. |
settings[].options | string[] | ❌ | Required when type == "select". |
settings[].isSecret | boolean | ❌ | Masks the input in the UI and encrypts the stored value at rest in FlutterSecureStorage (EncryptedSharedPreferences / Keychain), writing only a __SECURE_STORED__ sentinel in SharedPreferences. |
When you import a plugin, Chattree validates:
schemaVersion is 1 or 2id matches ^[a-z0-9][a-z0-9._-]*[a-z0-9]$ with at least one dot and is not a reserved internal IDversion is valid semver (MAJOR.MINOR.PATCH)primaryCommand matches ^[a-z0-9-]+$capabilities exist in the capability registrywasmSha256 is present and 64 hex charsruntime == "wasm" and entrypoint is non-emptyIf any validation fails, Chattree shows the specific error and refuses to install.