extensions.*
Unified Extension façade RPC methods (Extensions Store)
extensions.* is the unified façade over Aleph's three extension kinds — Skill / Plugin / Mcp. For everyday users these are one concept (the Extension); the namespace powers the Extensions Store panel and routes by kind to the existing skills.* / plugins.* / mcp.* backends.
Seven methods are wired in two passes:
register_extensions_handlers(src/bin/aleph-server/commands/start/builder/handlers/extensions.rs:15-58) — the four lifecycle / read methods.register_extensions_install_handlers(same file, lines 60-98) — the three trust-gated install flow methods, which additionally need the vault andMarketplaceManager.
The whole namespace is gated on hub_catalog.db opening successfully at boot; if the local cache cannot be created the four lifecycle methods are skipped and a warn is logged. The install-side methods additionally need the MarketplaceManager to be constructed.
The two sources.* methods documented in earlier versions of this page (extensions.sources.list / refresh) were retracted in the 26.6.22+ Hub convergence — the catalog sources are now an internal concept owned by AlephHubCatalog, and operators reach the same outcome through the bundled sync loop + the extensions.catalog view.
Catalog entry shape
extensions.catalog and extensions.installed return ExtensionEntry rows. The id is kind-prefixed (mcp:registry/exa-search, plugin:acme/foo, skill:user/web_search); the via field is the upstream provenance label (e.g. Aleph Hub, MCP Registry).
{
"id": "mcp:registry/exa-search",
"kind": "Mcp",
"name": "Exa Search",
"description": "Web and code search via the Exa API.",
"category": "Search",
"trust_tier": "Verified",
"installed": false,
"enabled": false,
"requires_config": true,
"via": "Aleph Hub"
}| Field | Type | Description |
|---|---|---|
id | string | Stable extension identifier (kind-prefixed) |
kind | string | Skill / Plugin / Mcp |
name | string | Display name |
description | string | Short summary |
category | string | Functional category (Search / Developer / Data / Productivity / Writing / Communication / Knowledge / Files / Design / Automation / Finance / Utilities / Other) |
trust_tier | string | Official / Verified / Community / Unverified |
installed | boolean | Whether the extension is currently installed |
enabled | boolean | Whether the installed extension is enabled (only meaningful when installed) |
requires_config | boolean | Whether config/secret values are required before it can run |
via | string | Upstream provenance label (set by the catalog source) |
Methods
extensions.catalog
Read the cached, offline-capable catalog, reconciled against the live installed set. Filtering is in-memory; missing backends degrade to empty rather than erroring.
| Parameter | Type | Required | Description |
|---|---|---|---|
kind | string | no | Skill / Plugin / Mcp |
category | string | no | Functional category |
source_id | string | no | Catalog source id (e.g. aleph-hub, mcp-registry) |
query | string | no | Free-text search over name and description |
Response: { "extensions": [ ...ExtensionEntry (with source_label from via)... ] }. Each row's installed and enabled fields are stamped by reconciling against the live MCP actor + plugin registry + skill system.
extensions.installed
Live-reconciled installed extensions across all three backends. Failures in any single backend are logged and skipped, so a flaky MCP actor cannot blank the panel's installed list.
Request: no params.
Response: { "extensions": [ ...ExtensionEntry... ] }. Each row carries the canonical id (e.g. local:mcp:<id>, local:plugin:<id>, local:skill:<id>) and the installed: true stamp.
extensions.disclosure
Return the mandatory pre-install disclosure payload for a catalog entry. The Panel renders this before extensions.install. The disclosure is built from the resolved install spec; a missing spec returns an error.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | Catalog extension id |
Response: { "disclosure": { ...DisclosurePayload... }, "injection_findings": [ ...InjectionFinding... ], "post_install": { ...post-install verification payload... } }.
DisclosurePayload carries the exact command / args, declared secrets and their purpose, network / filesystem reach, version, sha256, risk_class (mcp-remote / mcp-stdio / plugin-… / skill), trust_tier, ack_required, and requires_ack (true on community/LLM-derived MCP entries).
risk_class:
mcp-stdio— runs commands, highest riskmcp-remote— softer (network only)plugin-*— can instruct the agentskill-*— can instruct the agent
Community or LLM-derived MCP entries set ack_required: true and requires_ack: true, demanding an explicit "I understand the risk" acknowledgement at install time.
extensions.configure
Validate a submitted config against the spec.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | Catalog extension id |
values | object | no | Key/value config; secret fields are detected by the spec's secret: true flag |
Response: { "ok", "missing": [ ...string... ] }. missing lists required fields that were absent or blank.
extensions.install
Trust-gated install pipeline. The server re-validates the spec, the trust verdict, the pinned version, and the SHA256. Secret fields are written to the vault and referenced in the MCP config as {{secret:NAME}} (resolved per-server at spawn — never persisted in plaintext).
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | Catalog extension id |
values | object | no | Key/value config; secret fields go to the vault, plain fields to config |
acknowledge_risk | boolean | no | true for community/LLM-derived MCP entries (otherwise the install stops at needs_ack) |
Response (needs_ack): { "ok": false, "needs_ack": true, "disclosure": { ...DisclosurePayload... }, "injection_findings": [...] }.
Response (missing): { "ok": false, "missing": [ ...required fields... ] }.
Response (installed): { "ok": true, "outcome": { "kind": "mcp|plugin|skill", "id" | "path" }, "verify": { "ok", "tool_count"? | "error"? }, "pin": { "version", "sha256" }, "injection_findings": [...] }. On a successful MCP install, verify.tool_count confirms the server is listed after the spawn attempt. On a successful plugin/skill install, extensions.reload() is called so the new capabilities take effect without a daemon restart.
OCI / Docker MCP entries are not installable in v1 — the request returns INVALID_PARAMS: OCI/Docker MCP containers are not installable in this version. Sandboxed execution is a fast-follow.
extensions.toggle
Enable or disable an installed extension. The id must be an installed (local:) id; catalog ids (mcp-official:io.x/y) are rejected with INVALID_PARAMS.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | Installed (local:) extension id |
enabled | boolean | yes | Target enabled state |
Response: { "ok": true }.
Behaviour by kind:
local:mcp:<id>—mcp.start_server/mcp.stop_serverlocal:plugin:<id>—ExtensionManager::set_plugin_enabled(syncs the in-memory registry, then re-checks service status)local:skill:<id>—SkillSystem::update_configwithSetEnabled(enabled)
extensions.uninstall
Remove an installed extension and revoke its stored secrets. The id must be an installed (local:) id.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | Installed (local:) extension id |
Response: { "ok": true }.
Behaviour by kind:
local:mcp:<id>—mcp.remove_serverlocal:plugin:<id>— unload runtime +remove_dir_allon the plugin directory (a path-traversal guard mirrorsplugins::handlers::manage::is_safe_plugin_name; relative components like..or/are rejected)local:skill:<id>—SkillSystem::remove_skill
A fresh extensions.reload() is fired after the remove, so the live extensions.installed view reflects the change immediately.
Per-kind backends
extensions.* is a thin façade. Each method's actual work is delegated to a per-kind backend; the catalogues and backends stay in sync because every method also reconciles against the live set before responding.
| Kind | Backend namespace | Where the work happens |
|---|---|---|
Skill | skills.* | SkillSystem + the bundled sync loop |
Plugin | plugin.* / plugins.* | ExtensionManager + MarketplaceManager |
Mcp | mcp.* / mcp_config.* | McpManagerActor + the McpManagerHandle |
A change to a backend (e.g. mcp.add) is reflected the next time the Panel re-fetches extensions.installed (the bus also emits tools.changed).
Capability ledger
A per-install visible-capability list is rebuilt from disk on every install (the "Capability Ledger" in ~/.aleph/runtimes/ledger.json). The install handler's pre-install disclosure is built from this ledger so the Panel can render exactly what the extension will see at runtime — not the optimistic "what it says it can do" from the catalog.
See Also
- Methods Reference -- All currently registered namespaces
- Extensions Store -- The unified façade in context
- skills.* / plugins.* / mcp.* -- Per-kind backends