Extensions
Aleph's Plugin extension kind: Claude Code-compatible manifests, static components, MCP-backed plugins, WASM plugins, hooks, and lifecycle management.
This page documents the Plugin kind in Aleph's unified Extension model. A plugin can package skills, agents, commands, hooks, MCP server configurations, WASM capabilities, and background services. Skill and Mcp are sibling kinds; the Extensions Store presents all three through one catalog.
The plugin host is src/extension/. It is not the Hub catalog and it is not a model-provider registry.
Plugin layout
Aleph prefers the Claude Code-compatible manifest at .claude-plugin/plugin.toml:
my-plugin/
├── .claude-plugin/
│ └── plugin.toml
├── skills/
│ └── code-review/SKILL.md
├── agents/
│ └── reviewer.md
├── commands/
│ └── check.md
├── hooks/
│ └── hooks.json
└── .mcp.jsonThe component paths may be overridden in the manifest; the defaults above are used when they are omitted. A plugin without a manifest can be auto-discovered when it contains recognized component directories or files.
Manifest format
.claude-plugin/plugin.toml uses flat Claude Code fields and an optional [aleph] extension section:
name = "diagnostics"
version = "1.0.0"
description = "System diagnostics"
repository = "https://example.com/diagnostics"
skills = "./skills"
agents = "./agents"
commands = "./commands"
hooks = "./hooks/hooks.json"
mcp-servers = "./.mcp.json"
[author]
name = "Example"
[aleph]
runtime = "mcp"
entry = ".mcp.json"
[aleph.permissions]
network = true
filesystem = "read"
env = true
shell = false
background = false
[[aleph.services]]
name = "metrics"
start_handler = "start_metrics"
stop_handler = "stop_metrics"
auto_start = trueThe manifest resolution order is:
.claude-plugin/plugin.toml.claude-plugin/plugin.jsonaleph.plugin.toml, accepted only as a deprecated compatibility format with a warning- Compatibility adapters and auto-discovery for recognized component layouts
The current manifest does not use a plugin-provider section. AI model providers remain part of Aleph's core provider configuration rather than a plugin capability declaration.
Runtime kinds
| Runtime kind | Loading path | Use |
|---|---|---|
static | Markdown components, no executable runtime | Skills, agents, and commands |
mcp | .mcp.json through McpManager | Node.js, Python, and other external processes using MCP |
wasm | Extism WASM runtime | Sandboxed computation and declared WASM capabilities |
There is no separate direct Node.js plugin runtime in the current host. A Node.js plugin is normally an MCP server whose process is started by the MCP subsystem.
ExtensionManager flow
scope discovery
↓
manifest adapter and validation
↓
origin conflict resolution
↓
PluginRegistry registration
├── tools
├── hooks
├── services
├── skills and commands
└── agents
↓
PluginLoader
├── Static
├── MCP
└── WASMThe manager also shares the process-wide SkillSystem, publishes plugin skill roots, refreshes the agent catalog, and synchronizes enabled MCP-kind plugins with the live MCP manager.
Discovery and precedence
Plugin scopes are resolved in this order when an agent and project are present:
- agent-level:
~/.aleph/agents/<id>/plugins/ - local:
<project>/.aleph/plugins.local/ - project:
<project>/.aleph/plugins/ - user:
~/.aleph/plugins/installed/
Plugin origins resolve duplicate IDs as Config > Workspace > Global > Bundled. A higher-priority candidate becomes active and lower-priority candidates are retained as overridden records. A .disabled marker skips a plugin directory.
Names and registration
Plugin components use plugin:component qualified names. Built-ins keep short names. The registry also keeps short-name compatibility keys; a conflicting short name does not remove either qualified component, and the first registered owner wins the short key.
CapabilityDeclaration is the common registration model for:
ToolHookServiceSkillAgentMcpServer
Plugin commands/ Markdown is represented in the skill registration store as a command-type skill, rather than a separate capability enum.
MCP plugin wiring
For an MCP-kind plugin, the loader reads .mcp.json, substitutes ${CLAUDE_PLUGIN_ROOT} and ${ALEPH_PLUGIN_ROOT}, and namespaces each server as plugin:<plugin-id>/<server-name>.
Enabled plugin servers are registered with McpManager::add_transient_server. They are runtime-only: plugin lifecycle owns them, they are not written into the user's persistent MCP configuration, and unloading a plugin removes its transient servers and tool registrations.
Hooks
The hook system has two execution kinds:
| Kind | Execution | Effect |
|---|---|---|
interceptor | Sequential and awaited | May update input, ask, block, deny, or update output |
observer | Parallel and non-blocking | Records or reacts without changing the protected operation |
A third resolver/first-wins kind is not part of the current production system. Event seams decide which kinds are reachable. Matchers test tool_name only, so a matcher on an event without a tool name never fires; runtime inventory reports such configurations as reachable: false with an issue.
Command and HTTP hook output is capped at 64 KiB. Hook timeouts are capped at 300 seconds. Command and HTTP actions use the operator consent path when required.
WASM and permissions
WASM is loaded by Extism and uses declared capabilities for workspace, HTTP, credentials, rate limits, tool invocation, and secrets. Plugin permission declarations cover network, filesystem, environment, shell, and background service access. A service declaration requires the background permission.
These declarations describe what a plugin may register or request. Tool execution still passes through the shared scoped-tool, approval, and sandbox enforcement points.
Hot reload and lifecycle
The watcher reacts to manifest and component changes. reload is serialized under the manager load guard, so concurrent reloads cannot overwrite one another's registry state. Plugin unload stops its services, removes runtime registrations, and cleans up transient MCP servers before the plugin is reloaded or deleted.
Gateway and CLI surfaces
The canonical Claude Code-compatible gateway namespace is singular:
| Method family | Purpose |
|---|---|
plugin.list | List plugins |
plugin.install | Unified installation source classification |
plugin.update | Atomic update with version comparison |
plugin.enable / plugin.disable | Toggle a plugin |
plugin.reload | Reload a plugin |
plugin.uninstall | Remove a plugin |
plugin.marketplace.* | Manage the plugin marketplace backend |
The plural plugins.* methods remain compatibility aliases. Marketplace installation stages a copy, verifies an optional SHA-256, and performs an atomic rename; the persistent plugin data directory is outside the install tree.
Code locations
src/extension/mod.rs—ExtensionManagersrc/extension/manifest/— manifest adapters and parserssrc/extension/discovery/— scanning and conflict resolutionsrc/extension/registry/— plugin component registrysrc/extension/loader.rs— Static, MCP, and WASM loadingsrc/extension/mcp_config.rs—.mcp.jsonparsing and namespacingsrc/extension/hooks/— hook execution and consentsrc/extension/runtime/wasm/— WASM runtimesrc/extension/watcher.rs— hot reload
Related pages
- Extension System — cross-kind architecture
- Skills — SKILL.md authoring
- Extensions Store — Hub catalog and installation
- Capability System — capability declarations and runtime ledger