Extending BMAD: customization, MCP, skills, and modules

BMAD is built to be shaped. This page is the extension ladder: from a one-line override, through wiring in your own tools over MCP, up to authoring whole new skills and modules. The guiding rule is to use the smallest mechanism that expresses the need, so you gain behavior without gaining a fork you can never upgrade.

On this page

The extension ladder

NeedMechanism
add an evidence rule, a standing fact, or a completion hook to one agent/workflowa per-skill TOML override in _bmad/custom/
set org-wide paths, roster, or install defaultscentral config override (_bmad/custom/config.toml)
wire in an external tool or data source (docs, tracker, database)an MCP server, referenced from an override
add a reusable, standalone procedurea custom skill (BMad Builder)
add a whole domain: agents, workflows, templates, standardsa custom module (BMad Builder)
change BMAD's core behavior for everyonecontribute upstream
maintain fundamentally different method behaviorfork, accepting the update cost

Most needs are satisfied at the top of the ladder. "All our recommender claims must name a baseline and population" is a one-line override; "a reusable offline-evaluation workflow with its own templates" is a custom skill or module; forking to add one evidence column is disproportionate.

Customization in practice

Overrides are sparse TOML files under _bmad/custom/ (see the resolution rules on the anatomy page). The surfaces you will reach for, across agents and workflows:

  • persistent_facts (append array): literal sentences or file: references that load on every activation. The workhorse for org rules and MCP routing.
  • activation_steps_prepend / _append (append arrays): instructions to run before or after the standard activation flow.
  • on_complete (scalar or array): runs once at the terminal step, for publishing or a final review pass.
  • [[agent.menu]] (merged by code): add or replace menu items, each bound to a skill or a prompt.
  • template and checklist swaps (scalars like prd_template, validation_checklist): point at your own files.
  • external_sources / external_handoffs / doc_standards: on-demand knowledge lookups, publish steps that degrade gracefully, and finalize-time writing standards.

You can hand-author these, but bmad-customize scans the installed skills, picks the right scope, writes the file, and verifies the merged result, which is safer than guessing which surface a field belongs to. Two specialized customizations worth knowing: Deep Recon takes custom research packs (a new research type defined in an override, encoding your source hierarchy and freshness rules, see the recon how-to), and both Party Mode and bmad-review take custom personas and lenses the same way, so you can ship a review panel or a focus-group cast your whole team shares.

MCP: wiring your tools into BMAD

MCP (the Model Context Protocol) is how BMAD reaches tools and data your AI host does not have built in: your documentation index, your issue tracker, your database, a web-search backend. There are two directions, and the official one is the first.

Consuming MCP tools inside workflows

BMAD does not install MCP servers; your AI host does. Once a server is connected in your host, you point BMAD's workflows at its tools through the override surfaces above, by their exact tool names. A team override that makes the dev agent always consult your docs server and file tickets on completion:

# _bmad/custom/bmad-agent-dev.toml  (committed; applies to every dev workflow)
[agent]
persistent_facts = [
  "For any external library, resolve docs via mcp__context7__resolve_library_id then mcp__context7__get_library_docs before writing code.",
  "If a story is not in the local epics, look it up with mcp__linear__search_issues.",
]

# _bmad/custom/bmad-prd.toml  (publish the finished PRD)
[workflow]
on_complete = "Publish prd.md to Confluence with mcp__atlassian__confluence_create_page; on approval, open a tracking issue with mcp__atlassian__jira_create_issue."
external_sources = [
  "Company handbook (notion): consult for policy questions only when a requirement touches compliance.",
]

The one caveat that bites people: hardcoded tool names only work if the MCP server is actually connected in the session. Use the exact names the server exposes (they vary by server), and expect graceful skips rather than hard failures when a tool is absent; external_handoffs in particular is designed to degrade if a tool is offline. Deep Recon also discovers installed search-shaped MCP tools at its plan gate and can route to them, with external_sources adding guidance the discovery cannot infer (see the recon how-to).

BMAD packaged as an MCP server (community)

The reverse pattern exists too: several community projects package BMAD's agents and workflows as an MCP server, so any MCP client (Claude Desktop, VS Code with Copilot, Cline) can call BMAD's personas as tools, installed once and used across every project rather than copied into each repo. These are third-party, not official, so vet them like any dependency, but they are the current answer to "install BMAD once, use it everywhere," a capability the official roadmap lists as "Centralized Skills" but has not yet shipped.

Building your own with BMad Builder

BMad Builder (bmb) is the meta-module for extending the framework itself. It ships five skills:

SkillWhat it builds
bmad-agent-buildera new Agent Skill (persona + capability) through conversational discovery
bmad-workflow-buildera new multi-step workflow, or edits/analyzes an existing one
bmad-module-buildera distributable module packaging agents and workflows
bmad-eval-runnerruns a skill's evals: validate triggers, optimize the description, grade outputs
bmad-bmb-setupone-time setup of the builder in a project

Everything BMad Builder produces sits on the Agent Skills open standard (the same SKILL.md format Claude Code and 40+ other tools use), so a skill you build is portable, not BMAD-locked. The workflow is conversational: describe the agent or workflow you want, the builder scaffolds it, and bmad-eval-runner grades it against evals so you ship something tested rather than hoped. When a skill is worth reusing across projects, wrap it in a module and publish it.

Custom and community modules

A module is a family of skills, agents, and config distributed as a unit. You add them at install time:

# From a Git URL or local path (repeatable, comma-separated)
npx bmad-method install --directory . --custom-source https://github.com/org/my-module --tools claude-code --yes
npx bmad-method install --directory . --custom-source /path/to/local-module --tools claude-code --yes

The installer resolves a source two ways. If it contains a .claude-plugin/marketplace.json, discovery mode lists every plugin in the manifest and you pick; otherwise direct mode scans the directory for skills (subdirs with a SKILL.md) and installs it as one module. That manifest file is a cross-tool convention, not a Claude-specific one, so a module works across hosts. Local sources are referenced by path and re-read on update, so deleting the source keeps installed files but skips it until the path returns.

For discovering community work, the interactive installer offers a browse step over the curated plugins marketplace (organized by category, pinned to approved commits for safety), and a first-party marketplace with one-command install is on the roadmap. To publish your own, build it with bmad-module-builder, include a marketplace.json for discovery mode, push it to Git, and share the --custom-source URL.

Choosing the right surface

A quick decision guide for "the model can't do X":

  • If the model knows the data exists but cannot reach it, add an MCP server or connector.
  • If it can reach the data but uses it inconsistently, add or customize a skill (an override, usually).
  • If a whole domain needs its own agents, workflows, and standards, build a module.
  • If work decomposes into independent searches, use subagents (already how Deep Recon and the review skills parallelize); do not install a module just for parallelism.
  • If an operation must be deterministic and testable, prefer a real CLI or API over asking the model to imitate it, which is exactly why BMad Loop is Python and Deep Recon hands its counting to a script.

Hands-on: extend BMAD with an MCP server, a hook, and a skill

Three artifacts, one per rung: a tool source over MCP, a deterministic gate over a hook, a method over a skill. Each command is real; run them in your own repo.

1. Add a docs tool over MCP. Context7 serves current library documentation. Add it at project scope so the config commits and every teammate inherits it:

claude mcp add --transport http --scope project context7 https://mcp.context7.com/mcp

That writes .mcp.json:

{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}

Its tools now namespace as mcp__context7__resolve_library_id and mcp__context7__get_library_docs. Route the dev agent to them with one line on the persistent_facts surface of its override (see the resolution rules on the anatomy page):

# _bmad/custom/bmad-agent-dev.toml   (the customize.toml surface)
[agent]
persistent_facts = [
  "For any external library, resolve docs via mcp__context7__resolve_library_id then mcp__context7__get_library_docs before writing code.",
]

2. Gate prod deploys with a hook. A PreToolUse hook sees every tool call before it runs, reads the tool JSON on stdin, and answers on stdout. Author .claude/hooks/block-prod-deploy.sh:

#!/usr/bin/env bash
# PreToolUse hook: deny Bash commands that target prod, allow everything else.
set -euo pipefail

input=$(cat)
tool=$(printf '%s' "$input" | jq -r '.tool_name // ""')
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // ""')

if [ "$tool" = "Bash" ] && printf '%s' "$cmd" | grep -Eiq 'deploy.*(prod|production)|--env[= ]prod'; then
  printf '{"permissionDecision":"deny","permissionDecisionReason":"Prod deploy blocked by BMAD policy; ship through the staging workflow or an approval gate."}'
else
  printf '{"permissionDecision":"allow"}'
fi

Wire it in .claude/settings.json under hooks.PreToolUse, matched to Bash:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/block-prod-deploy.sh" }
        ]
      }
    ]
  }
}

A deploy --env prod from any agent, BMAD or not, is now denied deterministically; the model never has to remember the rule.

3. Ship a method as a skill. .claude/skills/release-notes/SKILL.md gives you a /release-notes command on the same Agent Skills standard bmad-agent-builder emits:

---
name: release-notes
description: Draft release notes from merged PRs and the changelog since the last tag. Use when the user asks for release notes or a changelog summary.
---

# Release notes

1. Read `CHANGELOG.md` and `git log <last-tag>..HEAD --oneline`.
2. Group entries into Features, Fixes, and Breaking.
3. Write a dated section, one imperative line per change.

Make the hook executable and confirm the server connected:

chmod +x .claude/hooks/block-prod-deploy.sh
claude mcp list

Illustrative (run it in your own repo; not machine-verified here).

context7: https://mcp.context7.com/mcp (HTTP) - ✓ Connected

Inside a session, /mcp shows the connection and OAuth state, /release-notes invokes the skill, and a deploy --env prod draws the deny. The three surfaces are independent: remove any one and the others still work. That is the extension ladder made concrete, one artifact per rung, before the deep dive below.

Under Claude Code: MCP, hooks, skills, and plugins in depth

BMAD's extension ladder is host-agnostic; Claude Code implements it across four concrete surfaces, one per rung.

Tools over MCP. You do not install servers from inside BMAD; you run claude mcp add <name> <target> at local, user, or project scope. Project scope writes a committed .mcp.json whose mcpServers map holds a command/args pair for type: "stdio" or a url for type: "http" (SSE included). /mcp manages connections and OAuth sign-in. Tools then namespace as mcp__<server>__<tool>, exactly the mcp__context7__resolve_library_id and mcp__linear__search_issues strings the override above hardcodes. A server exposing dozens of tools does not flood context: schemas are deferred by default and pulled on demand through ToolSearch (ENABLE_TOOL_SEARCH auto-loads all only when they fit in about 10% of the window, else defers).

Method over SKILL.md. The chapter's "an MCP server supplies tools, a skill supplies method" is literal here. Author .claude/skills/<name>/SKILL.md (or .claude/agents/<name>.md for a subagent) and the method arrives portably, on the same Agent Skills standard bmad-agent-builder emits.

Enforcement over hooks. Between tools and method sits the deterministic layer. Wire shell commands in settings under hooks.<Event> (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop, SubagentStop, PreCompact). They trade JSON on stdin/stdout; a PreToolUse hook returns permissionDecision allow/deny plus a rewritten tool_input, so a BMAD policy (block a command, redact output, gate a deploy) holds without trusting the model to remember it.

Distribution over plugins. Bundle skills, agents, hooks, and a .mcp.json behind plugin.json and share via /plugin marketplace; BMAD itself can ship this way, the tools arriving over .mcp.json and the method over SKILL.md.

RungSurfaceArtifact
toolsMCP.mcp.json
methodskill/subagentSKILL.md
enforcementhookhooks.<Event>
bundlepluginplugin.json

An MCP server supplies tools, not a method; a BMAD skill supplies a method, not credentials. Together they give you disciplined work over your own systems, which is the whole point of extending BMAD rather than replacing it. The next pages go deeper: first under the hood, into how BMAD actually works from its own source. 👉