Skip to content

Configuration

muaz keeps everything under ~/.muaz/. Authored content (agents, skills, pipelines, prompts, commands) lives inside plugins — your own in the local workspace, shared ones under plugins/, and read-only defaults under builtins/. The root holds only config files and runtime state.

~/.muaz/
├── config.yaml # global settings (default agent, tool access, web tools, telemetry)
├── models.yaml # provider profiles + global default + per-agent bindings (one file)
├── plugins.yaml # per-plugin state (enabled / priority / trusted / source)
├── mcp.json # global MCP server registry
├── secrets.json # chmod-600 API-key store (only when the OS keychain is unavailable)
├── gateway-token # chmod-600 persisted gateway token
├── builtins/
│ └── preset/ # embedded, read-only `starter` agent + preset pipelines (refreshed each start)
├── plugins/
│ ├── local/ # YOUR workspace: agents/ skills/ pipelines/ prompts/ commands/
│ │ └── agents/
│ ├── auto-sde/ # seeded example plugin (editable; its agent is `coding`)
│ └── <installed>/ # plugins you install
├── sessions/ # saved sessions + index.json
├── memory/ # per-agent cross-session notebooks (<agent>.md)
├── audit/ # append-only security audit log (audit.jsonl)
└── runtimes/ # on-demand Node.js / uv runtimes for MCP servers
# The agent used when no --agent flag is passed
default_agent: starter
# Provider/model selection lives in models.yaml (see below), not here.
# Override the remote plugin registry index (else $MUAZ_PLUGIN_REGISTRY, else default)
# plugin_registry: "https://example.com/muaz-plugins/index.json"
# Global tool access — one level per tool (off | ask | auto). Per-agent `tools:`
# blocks override these; `blocked` forces a tool Off everywhere and cannot be
# re-enabled by an agent. A tool value is a bare level, or `{ level, allow_when }`
# where allow_when auto-approves specific calls: "program=NAME" (first shell
# token), "dir=PATH" (path containment), or a glob over the primary argument.
tools:
default: ask # fallback for any tool without a more specific setting
built_in:
read_file: auto # read-only tools are workspace-confined, so auto
list_dir: auto
search: auto
edit_file: ask
write_file: ask
patch_file: ask
shell: ask
fetch_webpage: ask
web_search: ask
blocked: [] # e.g. [shell] to hard-disable shell for every agent
Terminal window
muaz config show # print the current config.yaml
muaz config edit # edit config fields interactively

The tool-access model (levels, allow_when, resolution order, MCP servers) is explained on Tools & approval; provider binding on Providers & models.

web_tools bounds the network tools (fetch_webpage, web_search). It applies globally; a per-agent web_tools block merges field by field over it (fields the agent sets win, omitted fields inherit the global value). All fields are optional and shown here with their defaults.

web_tools:
allow_private_hosts: false # reach localhost/private addresses (off blocks SSRF)
https_only: true # reject plain http:// URLs (set false to allow http)
allowed_urls: [] # glob allowlist, e.g. "https://*.example.com/*"
denied_urls: [] # glob denylist (wins over the allowlist)
max_response_bytes: 2097152 # download cap before truncation (2 MiB)
max_content_chars: 50000 # character cap on returned content
default_format: markdown # fetch_webpage default output: markdown | text
user_agent: "..." # override the User-Agent (defaults to a desktop Chrome string)

web_search queries DuckDuckGo by default (a keyless HTML scrape — nothing to configure). To use a different backend, set web_search in config.yaml. This is install-wide (endpoint + credentials), not per-agent; the web_tools guardrails above still apply to the backend request. Configurable in the browser UI’s Settings → Web search section.

web_search:
provider: brave # duckduckgo | brave | searxng
api_key: ${BRAVE_SEARCH_API_KEY} # Brave: reference a secret (never inline the token)
web_search:
provider: searxng # a self-hosted SearXNG instance
base_url: https://searx.example.org # must have the JSON format enabled

Brave needs a subscription token: store its value as a secret (Settings → Web search, or PUT /api/secrets) and reference it with ${VAR} — the value never lands in config.yaml. SearXNG needs its instance to expose the JSON output format; if the instance is on a private address, also set web_tools.allow_private_hosts: true.

Everything about model routing lives in this one file: named connection profiles, the global default, and per-agent agents overrides. Agents are provider-agnostic, so this is the single place models are chosen. It is re-read on every resolution, so edits take effect without a restart. Edit directly or use the browser UI’s Providers + Agents pages.

profiles:
anthropic-main:
type: anthropic # native Anthropic provider (prompt caching on)
default_model: claude-opus-4-8
api_key: ${ANTHROPIC_API_KEY}
bedrock-work:
type: bedrock
region: us-east-1
default_model: anthropic.claude-3-5-sonnet-20241022-v2:0
profile: work
# Global default: every agent that isn't bound below uses this profile.
default: anthropic-main
# Per-agent overrides (agent name, or @plugin/agent), with an optional model swap.
agents:
coding:
profile: bedrock-work
Terminal window
muaz models list # profiles, the default, and per-agent bindings
muaz models set <name> --type <type> --model <model> [--base-url --api-key …]
muaz models set-model <name> <model> # change just a profile's model
muaz models default <profile> # set the global default
muaz models bind <agent> --profile <p> [--model <m>]
muaz models unbind <agent>
muaz models remove <name>

Keep the api_key: ${ANTHROPIC_API_KEY} reference here and store the actual key with muaz (OS keychain, chmod 600 secrets.json fallback) via muaz auth (or /auth in the REPL) or the UI’s Providers page — ${VAR} resolves from the store first, then the environment. See API keys & authentication and Providers & models for the full reference.

Global MCP server definitions. Plugins may also declare their own MCP servers in a plugin-level mcp.json.

[
{
"transport": "stdio",
"name": "filesystem",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
},
{
"transport": "http",
"name": "my-api",
"url": "http://localhost:3000/mcp"
}
]
Terminal window
muaz mcp install <spec> # register an npm package, uvx package, or HTTP URL
muaz mcp list # list registered servers
muaz mcp remove <name> # remove a server by name

Use /mcp inside the REPL to see live MCP connection status.

Per-plugin enabled/priority/trusted state. Managed by muaz plugins … — see Plugins.

Drop a YAML file in your local workspace’s commands/ directory (~/.muaz/plugins/local/commands/) to add a custom / command. It appears in /help alongside the built-ins.

~/.muaz/plugins/local/commands/deploy.yaml
name: deploy
description: "Deploy to staging"
command: "cd ~/project && make deploy-staging"

The command runs via sh -c, with these environment variables available:

VariableValue
MUAZ_SESSION_IDCurrent session UUID
MUAZ_AGENT_NAMECurrent agent name
MUAZ_MODELCurrent model identifier