Skip to content

Customize and Extend

Customize FMAD

You want an agent to remember your organization’s rules, a workflow to publish its output somewhere, a menu item that runs your own skill, or a different name on the roster. Each of these is an override file next to FMAD’s installed defaults. Updates do not touch your files, and you do not edit installed files.

Run the fmad-customize skill and say what you want changed. It scans your installation for what is customizable, picks the right surface for your intent (an agent or a workflow), writes the override file, and verifies that the merged result contains your change. Use it for any per-skill change. The rest of this page describes what each surface exposes and how the pieces combine.

There are two surfaces:

SurfaceFileShapes
Per-skill override_fmad/custom/<skill>.tomlHow one agent or workflow behaves when it activates: persona, facts, hooks, menu, workflow fields
Central configuration_fmad/custom/config.tomlInstall answers and the agent roster that other skills read

fmad-customize writes per-skill overrides only. Central configuration is hand-authored; see Central configuration.

For ready-made team recipes (an agent-wide rule, publishing to Confluence, swapping a template, a rebranded roster), see Adopt FMAD Across a Team.

Every named agent has two parts. Name, title, and domain are fixed: “hey Ember” always activates the analyst. Everything else is customizable: role, identity statement, communication style, principles, icon, menu, persistent facts, and activation hooks. The shipped agents are listed in Agents.

The per-skill file controls how the agent behaves when it activates. Central configuration controls how fmad-party-mode, fmad-retrospective, and fmad-advanced-elicitation introduce the agent. Rewriting Ember’s principles is per-skill; changing the one-line description a party uses to introduce her is central.

Every customizable skill ships a customize.toml in its installed folder. That file is the schema: read it to see what is customizable. Never edit it; updates overwrite it. Instead, create sparse override files that contain only the fields you change.

Three layers. The resolver reads three files and the highest wins:

Priority 1 (wins): _fmad/custom/<skill>.user.toml (personal, gitignored)
Priority 2: _fmad/custom/<skill>.toml (team, committed)
Priority 3 (base): the skill's own customize.toml (shipped defaults)

_fmad/custom/ starts empty. Files appear only when someone customizes.

Four rules, by shape. The resolver does not treat fields differently by name; the merge depends only on the value’s shape:

ShapeRule
Scalar (string, int, bool, float)Override wins
TableDeep merge — apply these rules recursively
Array of tables where every item has code, or every item has idMerge by that key: matching keys replace in place, new keys append
Any other array (scalars, tables with no key, arrays mixing code and id)Append — base items, then team, then user

No removal. An override cannot delete a base item. To suppress a default menu item, override it by code with a description or prompt that does nothing; to restructure an array further, fork the skill. If you author your own array of tables, use code on every item or id on every item — mixing them falls back to append.

Read-only fields. agent.name and agent.title sit in customize.toml as metadata, but the agent never reads them at runtime. name = "Bob" in an override does nothing. For a differently named agent, copy the skill folder, rename it, and ship it as a custom skill.

Find the surface. The schema is the skill’s installed customize.toml:

.claude/skills/fmad-agent-pm/customize.toml

The path varies by IDE — Cursor uses .cursor/skills/, Cline .cline/skills/, and so on. Fields live directly under [agent].

Scalars. Create _fmad/custom/ in your project root if it does not exist, then add <skill>.toml with only the fields you change. icon, role, identity, and communication_style are scalars, so the override wins:

_fmad/custom/fmad-agent-pm.toml
[agent]
icon = "🏥"
role = "Drives product discovery for a regulated healthcare domain."
communication_style = "Precise, regulatory-aware, asks compliance-shaped questions early."

Facts, principles, and hooks. These four arrays append: shipped items first, then team, then user. persistent_facts are static context the agent keeps in mind all session; an entry is a literal sentence or a file: reference (globs allowed) whose contents are loaded as facts.

[agent]
persistent_facts = [
"Our org is AWS-only -- do not propose GCP or Azure.",
"file:{project-root}/docs/compliance/hipaa-overview.md",
]
principles = [
"Ship nothing that can't pass an FDA audit.",
]
# Runs before the greeting.
activation_steps_prepend = [
"Scan {project-root}/docs/compliance/ and load any HIPAA-related documents as context.",
]
# Runs after the greeting, before the menu.
activation_steps_append = [
"Read {project-root}/_fmad/custom/company-glossary.md if it exists.",
]

Prepend runs before the greeting, when the greeting itself needs that context. Append runs after, for setup the user should not wait on.

Menu. [[agent.menu]] is an array of tables keyed by code, so a matching code replaces the shipped item and a new code appends. Each item has exactly one of skill or prompt:

# Replace the shipped TK item with your own skill
[[agent.menu]]
code = "TK"
description = "Plan epics and tickets using our delivery framework"
skill = "custom-ticket"
# Add a new item
[[agent.menu]]
code = "RC"
description = "Run compliance pre-check"
prompt = """
Read {project-root}/_fmad/custom/compliance-checklist.md
and scan all documents in {output_folder}/{active_initiative} against it.
"""

When any field points at a file, spell out the full path from {project-root}, even for a file sitting next to your override in _fmad/custom/. The agent resolves {project-root} at runtime.

Team or personal. The team file (fmad-agent-pm.toml) is committed and shared: compliance rules, company persona, custom menu items. The personal file (fmad-agent-pm.user.toml) is gitignored: tone, private preferences, facts only you want the agent to hold.

_fmad/custom/fmad-agent-pm.user.toml
[agent]
persistent_facts = [
"Always include a rough complexity estimate (low/medium/high) when presenting options.",
]

Workflows — skills that drive a multi-step process, such as fmad-product-brief — use the same files and rules. Their surface lives under [workflow]. The baseline fields every customizable workflow exposes are the same hooks and facts as agents plus on_complete. For workflows, a persistent_facts entry is a literal sentence, a file: path or glob, or a skill: reference to a skill that holds relevant knowledge. on_complete is a string, or an array of instructions run in order, that runs once the workflow finishes its main output:

_fmad/custom/fmad-product-brief.toml
[workflow]
activation_steps_prepend = [
"Load {project-root}/docs/product/north-star-principles.md as context.",
]
persistent_facts = [
"All briefs must include an explicit regulatory-risk section.",
"file:{project-root}/docs/compliance/product-brief-checklist.md",
]
on_complete = "Summarize the brief in three bullets and offer to email it via the gws-gmail-send skill."

Individual workflows add fields on top — output paths, templates, toggles — and each follows the shape rules above. For example, fmad-code-review exposes review, the default review depth:

_fmad/custom/fmad-code-review.toml
[workflow]
review = "quick"

Read a workflow’s customize.toml to see the fields it exposes. If the field you need is not there, use activation_steps_* and persistent_facts, or open an issue asking for a customization point.

Activation order. A customizable workflow activates in a fixed sequence, so you know when each hook fires:

  1. Resolve the [workflow] block (base, then team, then user).
  2. Run activation_steps_prepend.
  3. Load persistent_facts as context for the run.
  4. Load config and resolve standard variables (project name, languages, paths, date).
  5. Greet the user.
  6. Run activation_steps_append.

The workflow body begins after step 6.

To change a skill’s customization for one run only, add --set key=value arguments or an --overrides <file.toml> file to the render_skill.py command in its SKILL.md. Persistent project and user files stay as they are.

Terminal window
uv run /abs/project/_fmad/scripts/render_skill.py \
--project-root /abs/project \
--skill /abs/path/to/fmad-build \
--overrides ./invocation.toml \
--set 'workflow.on_complete=Summarize the result in three bullets.'

Keys are dotted parameter paths such as workflow.on_complete. The override file has the same shape as the skill’s customize.toml. Both layer on top of the persistent files, and --set wins over the file.

String values can be written as plain text. Other types use TOML syntax:

Terminal window
--set 'workflow.persistent_facts=["Additional context"]'

Per-skill files cover one agent or workflow. Central configuration holds [core] values such as output_folder, module answers under [modules.<code>], and optional [agents.<code>] tables. It lives in three TOML files:

_fmad/config.toml (created by fmad setup) team answers (committed)
_fmad/custom/config.toml (hand-written only) team pins (committed)
_fmad/custom/config.user.toml (fmad setup, and by hand) personal answers (gitignored), including `[core] active_initiative`

Three layers, merged with the same shape rules:

Priority 1 (wins): _fmad/custom/config.user.toml
Priority 2: _fmad/custom/config.toml
Priority 3 (base): _fmad/config.toml

What lives where. fmad setup asks the config_questions declared in each module’s fmod.toml and files each answer under [modules.<code>] by the question’s scope: team answers land in _fmad/config.toml, user answers in _fmad/custom/config.user.toml. The agent roster comes from each installed module’s roster.toml, not from central config. [agents.<code>] tables are laid on top of it: use them to add an agent of your own, or to add details such as team or description to an installed one. An installed agent’s name, title, and icon come from its skill and its per-skill override, so setting them here has no effect.

Editing rules. All three files may be hand-edited. fmad setup never changes an existing value, so to change an answer, edit its key in the file fmad setup reports for it. fmad setup never writes _fmad/custom/config.toml; it is the place for custom agents, descriptor additions, and any team value you want pinned over the answers in _fmad/config.toml.

Rebrand an agent. Party mode and other roster skills pick up the new description automatically. To change the agent’s icon as well, set icon under [agent] in its per-skill override (_fmad/custom/fmad-agent-pm.toml):

_fmad/custom/config.toml
[agents.fmad-agent-pm]
description = "Healthcare PM — regulatory-aware, stakeholder-driven, FDA-shaped questions first."

Add a fictional agent. No skill folder is needed; the descriptor alone lets a party include Kirk, and the team field filters who gets invited. See Run Multi-Agent Discussions.

_fmad/custom/config.user.toml
[agents.kirk]
team = "startrek"
name = "Captain James T. Kirk"
title = "Starship Captain"
icon = "🖖"
description = "Bold, rule-bending commander. Speaks in dramatic pauses."

Override an install setting. The team pin wins over the answer in _fmad/config.toml; a developer’s own _fmad/custom/config.user.toml still wins over it:

_fmad/custom/config.toml
[core]
output_folder = "/shared/org-fmad-output"

Which surface to use:

NeedUse
Add MCP tool calls to every dev workflowPer-skill: _fmad/custom/fmad-agent-dev.toml persistent_facts
Add a menu item to an agentPer-skill: _fmad/custom/fmad-agent-<role>.toml [[agent.menu]]
Swap a workflow’s output templatePer-skill: _fmad/custom/<workflow>.toml scalar override
Rebrand an agent’s public descriptorCentral: _fmad/custom/config.toml [agents.<code>]
Add a custom or fictional agent to the rosterCentral: _fmad/custom/config.*.toml new [agents.<code>]
Pin team-enforced install settingsCentral: _fmad/custom/config.toml [modules.<code>] or [core]
Choose which initiative your documents and tickets go toCentral: _fmad/custom/config.user.toml [core] active_initiative, or ask the fmad skill to switch it

On activation, a shared Python script merges the files and returns the result as JSON. Run it yourself to see exactly what an agent or workflow will use:

Terminal window
# Resolve the full agent block
uv run {project-root}/_fmad/scripts/resolve_customization.py \
--skill /abs/path/to/fmad-agent-pm \
--project-root {project-root} \
--key agent
# Resolve a single field
uv run {project-root}/_fmad/scripts/resolve_customization.py \
--skill /abs/path/to/fmad-agent-pm \
--project-root {project-root} \
--key agent.icon
# Full dump: omit --key

Replace {project-root} with your project root; the skill resolves it for you at activation, but a shell will not.

--skill points at the skill’s installed directory; the script derives the skill name from that folder and finds the matching _fmad/custom/ files itself. Output is always JSON.

--project-root names the project whose _fmad/custom/ files apply. Skills pass it on activation. Omit it and the script infers a root — working directory first, then its own install path, then the skill directory — which lands correctly in ordinary use but has to guess when a skill is installed under your home directory and a ~/_fmad exists there too. If it picks a root with no override for that skill while another candidate has one, it says so on stderr rather than quietly returning defaults.

Use uv run so the script gets Python 3.11 or later. If you run it with python3 instead, check the version: 3.10 and earlier lack tomllib. If the script cannot run, an agent reads the three TOML files and applies the same rules; many workflows fall back to shipped defaults, so keep uv working if you rely on workflow overrides.

Customization not appearing. Check that the file is in _fmad/custom/ and named exactly after the skill directory. Check TOML syntax: strings quoted, [section] for tables, [[section]] for arrays of tables, and a table’s scalar or array keys placed before any of its [[subtables]]. For agents, fields belong under [agent]. Remember that agent.name and agent.title are read-only.

An update broke it. You probably copied the full customize.toml. Trim the override back to only the fields you changed.

See what is customizable. Run fmad-customize, which lists every customizable skill and which already have overrides, or read the skill’s customize.toml directly.

Reset. Delete the override file from _fmad/custom/. The skill falls back to its shipped defaults.