Plugins
A plugin is a self-contained, installable bundle of authored content: agents, skills, pipelines, prompts, custom commands, and optionally its own MCP servers. Plugins make it easy to share and reuse a set of agents as a unit.
Everything you author or install lives under one of three namespaces:
| Namespace | Location | Role |
|---|---|---|
| local | ~/.muaz/plugins/local/ | Your own workspace — where agents create and edits land |
| plugins | ~/.muaz/plugins/<id>/ | Installed plugins you manage (enable/disable/uninstall) |
| built-ins | ~/.muaz/builtins/<id>/ | Shipped, read-only defaults embedded in the binary |
Name resolution
Section titled “Name resolution”When you reference an agent (or pipeline) by a bare name, muaz resolves it across namespaces in tiers, most-specific first:
- local workspace — wins outright if it defines the name.
- installed plugins (in priority order).
- built-ins.
If two or more plugins define the same name and your local workspace does not,
the name is ambiguous: muaz lists every match and asks you to use a
fully-qualified @plugin/name. A fully-qualified name (e.g. @web-research/researcher,
or @local/coding) always targets exactly one namespace.
muaz chat --agent coding # bare name → local, else plugins, else built-inmuaz chat --agent @web-research/researcher # qualified → that plugin onlyBuilt-ins and the local workspace
Section titled “Built-ins and the local workspace”- The
starteragent is an embedded built-in (in thepresetplugin). It is re-materialised under~/.muaz/builtins/preset/on every start, so upgrades always ship the current version. Built-ins are read-only — to customise one, shadow it with a same-named agent in your local workspace (the CLI’sagents editand the UI’s “Fork” both do this for you). - The
codingagent ships as an editable example plugin (auto-sde) at~/.muaz/plugins/auto-sde/, seeded once on first run. Edit it, or uninstall it. - Your local workspace (
~/.muaz/plugins/local/) is just another namespace, but it always wins resolution and can’t be uninstalled.
Plugin layout
Section titled “Plugin layout”~/.muaz/plugins/web-research/├── manifest.yaml # required — plugin metadata├── agents/│ └── researcher.yaml├── skills/│ └── web-digger/│ └── SKILL.md├── pipelines/│ └── research-and-write.yaml├── prompts/│ └── researcher.md├── commands/│ └── crawl.yaml└── mcp.json # optional — MCP servers this plugin declaresAgents reference their co-located files with relative paths
(system_prompt: ./../prompts/researcher.md or ./researcher.md), so a plugin is
fully portable.
manifest.yaml
Section titled “manifest.yaml”Manifests are version 2 — manifest_version: 2 is required (there is no v1
fallback). Beyond metadata, a manifest declares everything privileged the plugin
wants, all surfaced verbatim at the trust prompt.
manifest_version: 2 # requiredname: Web Research # human-facing name; the directory is the canonical idversion: 0.2.0description: Research agents + browsing skillsauthor: youmuaz: ">=0.2" # semver constraint, enforced at install and by doctor
# Typed settings → an auto-generated form on the Plugins page. Non-secret values# are stored in plugins/<id>/config.yaml; `secret` values go to the OS keychain.# Reference any of them as ${plugin.<key>} inside the plugin's agents/mcp.json/tools.config: index_url: type: string # string | int | bool | enum | path | secret description: "Base URL to crawl" required: true api_token: type: secret # never written to disk; keychain only
# What the plugin is allowed to do (replaces the old implicit folder-scan).permissions: mcp: [crawler] # MCP servers (from the plugin's mcp.json) it attaches network: true # may its tools/servers reach the network tools: [fetch_webpage] # built-in tools its agents rely on
# Lifecycle hooks (argv arrays) — run only for trusted plugins, shown verbatim# at trust time, and audit-logged.hooks: post_install: ["./setup.sh"]
# Command-backed custom tools, registered as plugin_<id>__<name>. The command# receives the tool input as JSON on stdin; stdout is the result.tools: - name: crawl description: "Crawl a URL and return extracted text" command: ["./crawl.py"] parameters: { type: object, properties: { url: { type: string } } } timeout_secs: 60
# RAG source declarations (surfaced on the plugin card; backend deferred).knowledge: - name: handbook source: ./docs/handbook.mdManaging plugins
Section titled “Managing plugins”muaz plugins list # installed + built-ins, with enabled/trusted statemuaz plugins show web-research # manifest + contentsmuaz plugins install ./web-research.zip # install from a local .zipmuaz plugins install web-research # install by name from the registrymuaz plugins install web-research@0.2.0 # pin a versionmuaz plugins enable web-research # re-enable a disabled pluginmuaz plugins disable web-research # keep installed, but hide from resolutionmuaz plugins uninstall web-research # delete itmuaz plugins search browsing # search the remote registryThe same operations are available in the browser UI’s Plugins page.
Installing a plugin runs none of its code, but its skills can request tool
pre-approvals (allowed-tools) and it can declare MCP servers (which launch
processes). On install, muaz shows exactly what a plugin requests and asks whether
to trust it:
- Trusted — the plugin’s skill
allowed-toolsare honoured silently. - Untrusted (default) — those tools simply prompt on use, like any other tool.
A plugin installed without trust is fully usable; trust only governs silent
pre-approval. Re-trust later with muaz plugins (UI) or by editing plugins.yaml.
The registry overlay (~/.muaz/plugins.yaml)
Section titled “The registry overlay (~/.muaz/plugins.yaml)”plugins.yaml records per-plugin state — it never duplicates manifest content.
Plugins on disk without an entry default to enabled at priority 0.
web-research: enabled: true priority: 10 # higher wins a bare-name tie between plugins trusted: true source: ./web-research.zip version: 0.2.0Remote registry
Section titled “Remote registry”muaz plugins install <name> / search fetch a JSON index describing
available plugins. The URL resolves from $MUAZ_PLUGIN_REGISTRY, then
plugin_registry in config.yaml, then a built-in default.
{ "plugins": [ { "name": "web-research", "version": "0.2.0", "description": "Research agents + browsing skills", "url": "https://example.com/web-research-0.2.0.zip", "sha256": "<hex>", "minisign_sig": "untrusted comment: …\nRW…\ntrusted comment: …\n…", "publisher_key_id": "E7620F1842B4E81F", "muaz": ">=0.2" } ]}sha256 is verified for integrity on download. minisign_sig adds
authenticity: it is checked against muaz’s embedded publisher key, and the
result sets the install tier —
- valid signature → verified: installed with a verified banner.
- no signature → community: installed, but warned as unverified.
- present but invalid → hard error: the download is rejected as tampered.
The muaz hint mirrors the manifest’s compatibility constraint (the manifest’s
muaz: is the hard gate, checked at install and re-checked by muaz doctor).
Authoring a plugin
Section titled “Authoring a plugin”- Create a directory with a
manifest.yamland anyagents/,skills/,pipelines/,prompts/,commands/,mcp.jsonyou want to ship. - Agents are provider-agnostic, so a shipped agent automatically adopts the
installing user’s default binding — or a
binding they set for it in
models.yaml. - Zip the directory (the manifest may be at the root or under a single top-level
folder) and
muaz plugins install ./your-plugin.zip.
A complete, copy-pasteable sample plugin is in the Examples page.