Skip to content

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:

NamespaceLocationRole
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

When you reference an agent (or pipeline) by a bare name, muaz resolves it across namespaces in tiers, most-specific first:

  1. local workspace — wins outright if it defines the name.
  2. installed plugins (in priority order).
  3. 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.

Terminal window
muaz chat --agent coding # bare name → local, else plugins, else built-in
muaz chat --agent @web-research/researcher # qualified → that plugin only
  • The starter agent is an embedded built-in (in the preset plugin). 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’s agents edit and the UI’s “Fork” both do this for you).
  • The coding agent 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.
~/.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 declares

Agents reference their co-located files with relative paths (system_prompt: ./../prompts/researcher.md or ./researcher.md), so a plugin is fully portable.

Manifests are version 2manifest_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 # required
name: Web Research # human-facing name; the directory is the canonical id
version: 0.2.0
description: Research agents + browsing skills
author: you
muaz: ">=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.md
Terminal window
muaz plugins list # installed + built-ins, with enabled/trusted state
muaz plugins show web-research # manifest + contents
muaz plugins install ./web-research.zip # install from a local .zip
muaz plugins install web-research # install by name from the registry
muaz plugins install web-research@0.2.0 # pin a version
muaz plugins enable web-research # re-enable a disabled plugin
muaz plugins disable web-research # keep installed, but hide from resolution
muaz plugins uninstall web-research # delete it
muaz plugins search browsing # search the remote registry

The 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-tools are 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.0

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).

  1. Create a directory with a manifest.yaml and any agents/, skills/, pipelines/, prompts/, commands/, mcp.json you want to ship.
  2. 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.
  3. 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.