Extensions
Docs/Extend/Extensions

Extensions

Edit on GitHub
docs-site/extend/overview.md

Orrery is a harness you shape. Extensions are how: tools, model providers, commands, UI clients, MCP servers, memory and more. The built-in harness is made of the same parts anyone else gets. Most of what ships with orrery (each provider, the git tools, the theme, the agents) is itself an extension.

What an extension can provide

One package can provide several things at once. Many extensions may contribute to each of these:

FieldWhat it adds
toolsTools the model (and a person, through a command) can call.
providersModel providers.
agents · workflowsRole agents and multi-step orchestrations.
interceptors · lifecycleHooks around a call; session start and stop handlers.
commandsCLI subcommands.
skillsPrompt-level capabilities.
mcpMCP servers exposed as tools.
clients · elementsA UI, and UI elements.
views · gradersSurface bindings for loop events, and eval verdicts. Show things with ctx.ui.show and the other ctx.ui.* calls (Show things: placements, Tell the person). renderers is accepted and unused: an extension never draws.

Exactly one extension may hold each of these: memory, session, permissions, router. A second claim is a load error, not a silent override.

The rule behind the list: if a subsystem can be replaced, it is a field here. If it is not a field, it is part of the kernel's boundary.

Runtimes

The manifest's runtime line says how the code runs. The rest is the same in every language: the same manifest, the same grants, the same namespacing.

RuntimeHow it runsBoundary
wasmA WebAssembly component.A real sandbox: no file access except through the host.
nodeA Node.js child process, using @getorrery/ext.Capabilities are withheld, not sandboxed.
pythonA Python child process.Same as node.
processAny program that speaks the protocol, started by a [process] table.Same as node.
nativeRust compiled into the harness.No process boundary.
noneNo process: a manifest that only declares components, their data and actions (Components).Nothing runs; it reads only the files its read grant covers.

node, python and process extensions get no file, process or network handles: everything goes through ctx, which the policy engine checks. But a determined extension in those runtimes can reach around that. Only wasm is a real boundary. See Grants and the supply chain.

Tools are namespaced

A tool's name is always <extension id>.<tool>: buildgraph.impacted, git.commit, mcp.github.search_issues. Two extensions cannot claim the same name, and a name in a transcript says where it came from.

Where extensions live

LayerFolder
User~/.orrery/extensions/<id>/, in every project
Workspace<workspace>/.orrery/extensions/<id>/, committed with the repository

Each folder holds an orrery.toml manifest. Both folders are scanned at session start. A workspace's extensions load only once you trust the workspace.

Settings for an extension go under its id:

[extensions.theme]
default = "dark"

See what loaded

orrery ext list          # loaded, degraded and skipped, with reasons
orrery ext show theme    # what one registered: tools, commands, state

degraded means a grant it asked for was not given. The tools that need it are disabled and the rest work. It is not a failure.

Next