build-agent-broker-project
Build, edit, validate, publish, and deploy a MuleSoft Agent Broker (Agent Network V2) project end-to-end. Use whenever the user asks to build, create, scaffold, configure, edit, validate, publish, or deploy an Agent Broker, agent network V2, AgentScript, `.agent` file, or `agentNetwork: 2.0.0` project. Do NOT trigger for V1→V2 migration (use the converter skill).
How do I install this agent skill?
npx skills add https://github.com/mulesoft/mulesoft-dx --skill build-agent-broker-projectIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides a guided workflow for building MuleSoft Agent Network V2 projects using official MuleSoft CLI and MCP tools. It implements secure handling of credentials through parameterization and follows standard development practices. No malicious activity or security vulnerabilities were detected.
- Socketpass
No alerts
- Snykwarn
Risk: MEDIUM · 1 issue
What does this agent skill do?
⚠️ HARD OUTPUT CONTRACT — applies to EVERY assistant turn in this skill
You MUST output ≤ 4 lines of user-facing text per turn, unless you are emitting a numbered list of confirmed items (asset list, validation findings, asset → node assignments) — in which case the list itself is the output and gets no preamble.
FORBIDDEN openings. Never start a turn with any of these phrases or their synonyms. If you catch yourself typing one, delete it:
- "I'll now..." / "Now I'll..." / "Next, I'll..." / "Let me..."
- "First, ..." / "To start, ..." / "Before I do..."
- "Based on..." / "Given that..." / "Since..."
- "Great!" / "Perfect!" / "Got it!" / "Understood!" / "Sure!"
- "I'm going to..." / "I plan to..." / "My approach is..."
- "Let me think about..." / "Let me analyze..." / "Let me check..."
- "Here's what I'm doing..." / "Here's my plan..." / "Here's a summary..."
- "Moving on to..." / "Now that we've..." / "Now we'll..."
- Any sentence describing what you are about to do. Just do it.
FORBIDDEN content. Never include in a turn:
- Recap of what the user just said. They remember.
- Pre-explanation of what comes after this turn. Wait until you get there.
- Restating the goal of the current phase. The phase headings handle that.
- Step-by-step narration of how you're reasoning. The user sees only the conclusion.
- Phase numbers or step numbers in the prose ("Step 4 says..." / "In Phase 2..."). The model uses these to navigate; the user doesn't see them.
REQUIRED shape of a normal turn:
<one action OR one question OR one bulleted list>
<optional: one short follow-up sentence, only if strictly needed>
<stop>
End-of-phase confirmation shape:
<bulleted list of what was captured, ≤ 6 bullets>
Anything missing?
Validation-result shape:
✅ PASS (or) ❌ FAIL — <N> issue(s)
- <issue 1>
- <issue 2>
If a phase needs multiple actions, do them in tool calls without narrating between them. Only emit user-facing text at decision/confirmation points.
MuleSoft Agent Broker Builder
Turns a natural-language description of a multi-agent workflow into a complete, validated, deployable Agent Network V2 (GA, A2A v1.0) project. Runs a 6-phase guided experience and adds publish + deploy.
The skill is CLI-first end-to-end. Validate/publish/deploy use the Anypoint CLI Agent Fabric plugin (mulesoft-anypoint-cli-agent-fabric-plugin). Exchange asset search uses Anypoint CLI v4 (anypoint-cli-v4 exchange asset list). Both are portable across Claude Code, Cursor, Codex, and Vibes, and match the CI/CD path. MCP tools (mcp__mulesoft__*) work as a fallback when present, but no MCP dependency is required.
When to use
- Use for: building a new Agent Broker; adding/swapping nodes, agents, MCP tools, or LLMs; tuning instructions; changing routing; running validate/publish/deploy.
- Don't use for: V1→V2 conversions (use
translate-agent-broker-old-to-new-project); standalone Mule apps, DataWeave, or APIs.
If the YAML has schemaVersion: 1.0.0, this is V1 — stop and route to the converter. The V2 marker is agentNetwork: 2.0.0 (unquoted, top of file).
References (read on demand)
references/canonical-example.md— A complete, working Agent Network V2 (GA, A2A v1.0) project. The structural template — when in doubt, copy it.references/gotchas.md— GA syntax rules, compile-error rules, RULE-ASSET-MODE (inline vs Exchange), subagent-vs-orchestrator decision, auth casing, CLI + MCP tooling integration, graceful degradation.
The MuleSoft Agent Network GA docs (Anypoint Code Builder section) are the authoritative reference. The references above cover the gotchas and worked example.
Node-type terminology (phase language ↔ schema keyword)
The 6 phases below use user-facing names for node types. The actual .agent file uses schema keywords. When talking to the user, use the phase name; when writing the file, use the keyword.
| Phase language | .agent keyword | What it is |
|---|---|---|
| Reasoning node | subagent | LLM-with-tools. Accepts actions; has built-in HITL. The default LLM-powered node type. |
| Orchestrator node | orchestrator | LLM-with-tools, specialized for coordinating multiple actions toward a compound goal. Use only when a node has ≥2 actions AND they jointly serve one outcome. |
| Generate node | generator | LLM without tools. For one-shot generation/summarization/classification with structured output. |
| (no LLM, deterministic) | router | Branching based on a known value. Conditions, not prompts. |
| (no LLM, side-effect) | executor | Runs one tool with known args, sets a variable. |
| (terminal) | echo | Sends the final A2A response to the client. |
Tooling integration (CLI-first, MCP-fallback)
The skill prefers the Anypoint CLI Agent Fabric plugin (mulesoft-anypoint-cli-agent-fabric-plugin) for validate/publish/deploy and Anypoint CLI v4 (anypoint-cli-v4) for Exchange search. The MuleSoft MCP server (mcp__mulesoft__*) is the fallback.
Try CLI first. If the CLI fails, fall back to MCP immediately — do NOT ask the user, do NOT retry the CLI, do NOT stop the phase.
A CLI attempt counts as failed when ANY of these happen:
command -vreturns nothing (binary not installed).- The command exits non-zero for a reason OTHER than the user's own input (e.g.,
ENOENT, plugin not installed, auth env vars unset, network error, npm install needed, "command not found",EACCES). - The command hangs past a reasonable timeout (~60s for search, ~5min for build/publish/deploy).
- The command returns success but the output is empty / malformed when the schema requires content (e.g., zero assets returned where the user explicitly named one).
A CLI attempt does NOT count as failed when:
- The user's input was bad (invalid project name, missing required field) — surface the error to the user, don't fall back.
- The validation/build legitimately found schema errors — report them; that's the CLI doing its job.
Fallback procedure (apply silently, in this order):
- Catch CLI failure. Note the failure reason in one short internal line — do NOT narrate it to the user unless they ask.
- Check if the equivalent
mcp__mulesoft__*tool is registered in the session. If yes, call it with the equivalent inputs. - If MCP also fails or isn't present, fall back to the no-tool path (doc link / structural checklist / user prompt) per
references/gotchas.md§ "Graceful degradation". - Tell the user only the outcome ("found 3 LLM assets" / "validated — 2 issues" / "couldn't reach Exchange — give me the assetId manually?"), not the tool-by-tool path you took to get there.
If a CLI command needs more info before running (unknown flag, unfamiliar subcommand, ambiguous syntax error): try <command> --help first, then a public-web search if --help doesn't resolve it. Only after both come up empty should you ask the user. This applies to the CLI plugin AND anypoint-cli-v4. Do NOT narrate the lookup; just run the command with the corrected syntax.
See references/gotchas.md § "Tooling integration" for the full capability matrix, CLI command syntax, env-var auth (ANYPOINT_CLIENT_ID/SECRET/ORG/ENV), and the per-step CLI ↔ MCP mapping.
Workflow A — Build a new project (Phases 1–6 + Publish/Deploy)
The 6 phases below structure the build experience. Each phase ends with a stop point — wait for the user. Apply each user response immediately (no batch-then-update).
Step 1: Pre-flight + scaffold
- Detect existing project. If working folder has
agent-network.yaml+exchange.json+brokers/, ask: "Edit this one, or scaffold new in a sibling folder?" Default edit (Workflow B). - Detect schema version.
schemaVersion: 1.0.0→ route to converter. - Confirm intent in one sentence: "You want me to build a new Agent Broker that does X. Sound right?"
- Collect scaffold inputs (ask before invoking CLI):
- Project name (kebab-case, e.g.
it-help-investigation) — also becomes the defaultassetId. - Output directory (default: current working dir).
- Asset version (default
0.0.0while in development; user can bump on first publish).
- Project name (kebab-case, e.g.
- Scaffold via CLI. Run the create command from the parent directory:
This producesanypoint-cli-agent-fabric-plugin agent-network project create \ --name <project-name> \ --output-dir <parent-dir> \ --create-dir<project-name>/agent-network.yaml+exchange.json+brokers/with the correctgroupId/organizationId(pulled fromANYPOINT_ORG) and starter template. Skill then edits the generated files in place.- If CLI is unavailable AND
mcp__mulesoft__create_agent_network_projectis present, call the MCP tool with the same inputs. - If neither is available, fall back to writing the canonical scaffold structure directly (
agent-network.yamlwithagentNetwork: 2.0.0,exchange.jsonwith"classifier": "agentic-network", emptybrokers/) and tell the user thegroupId/organizationIdplaceholder needs to be filled in before publish.
- If CLI is unavailable AND
- Capture network
infoforagent-network.yaml: ask forinfo.label(required) andinfo.description(optional). Defaultinfo.versionto1.0.0unless user provides one. Apply to the scaffold immediately.
Step 2: Functional Requirements (Phase 1)
Goal: Get the user to define functional requirements clearly. Refuse vague answers — keep prompting until each item is concrete. The user does not need to use graph terminology; natural-language steps are fine.
Capture, in order:
- Trigger — what event starts the flow? (Almost always A2A
message/send. Confirm.) - Workflow steps & branching logic — "If X happens, then strictly do Y." Walk through each step.
- Hard constraints — what is absolutely restricted? These become router conditions, not prompt sentences.
- Determinism vs. open-endedness — per step: 100% predictable outcome (graph branching) or LLM reasoning/judgment (LLM-powered node)?
If the user gives a vague answer twice on the same item, accept a placeholder, flag it, and move on.
End the phase with one confirmation: "Here's what I captured: [bulleted summary]. Anything missing?" Stop.
Step 3: Initial Asset Registration (Phase 2)
Goal: Find the right assets in Exchange and register them in the YAML.
Asset types: LLMs (always ≥1), MCP tools, A2A agents.
Asset search order — for each capability identified in Phase 1:
- Private Exchange first. If
anypoint-cli-v4is installed:anypoint-cli-v4 exchange asset list --search "<keywords>" --organization <orgId>. Else if MCPsearch_assetis available: call withassetFilters: ["llm"]/["mcp"]/["agent"]+exchangeScope: "Private". - Public Exchange if no Private match. Drop
--organization/ setexchangeScope: "Public". - Placeholder if neither has it. Register as Inline with
${var}-style URL/auth placeholders the user can fill in later.
LLM selection is different. Don't auto-pick. List the LLM options found in Exchange (e.g., claude, openai, gemini) and ask: "Pick one or more, or create a new one." Stop.
Review with the user before writing: "Selected: [list]. Confirm?" Stop.
Register every confirmed asset in agent-network.yaml + exchange.json. Each asset is in one of two modes — see references/gotchas.md § "RULE-ASSET-MODE":
- Inline (asset NOT in Exchange): registry entry +
context.connectionswithref.name. - Exchange (asset already published):
exchange.json.dependencies+context.connectionswithref.nameANDref.namespace. No registry entry.
Auth always lives on context.connections.<id>.authentication. Parameterize URLs/secrets via ${<name>.url} / ${<name>.apiKey}. Add corresponding exchange.json.metadata.variables. Mark secrets "secret": true.
Per-type schema notes:
- LLM — Inline:
info.label,metadata.platform: Gemini | OpenAI | AzureOpenai. Connection:kind: llm+url+authentication. - MCP — Inline:
info.label,metadata.transport.kind(streamableHttp|sse|stdio). After registering, ask the user whattool_nameto call (required for the action). Ask if they know the input parameters. If yes, declare in actioninputs:. If no, omitinputs:— runtime auto-discovers. Never fabricate tool names or input schemas. - A2A — Inline:
info.label+ interfaces branch. Usea2afor current A2A v1.0 agents,a2a_v03for legacy A2A v0.3 (Agent Broker stays backward-compatible). Card undermetadata.interfaces.<branch>.cardincludesname,description,url,protocolVersion,version,capabilities,defaultInputModes,defaultOutputModes,skills. Seereferences/gotchas.md§ "Registry agents" for the per-branch shape.
Step 4: Technical Graph Definition (Phase 3 — Agent Script)
Goal: Translate the functional requirements into the .agent graph. Brief drafts of system.instructions and per-node instructions only — Phase 5 refines prose.
Guiding principle: Graph = pre-defined rules. LLM node = reasoning. Use the graph for anything that can be definitively hard-coded. Use an LLM-powered node (reasoning/orchestrator/generate) only for tasks that genuinely need reasoning. The graph acts as the spine that enforces high-level stages (e.g. Research → Draft → Review); within each stage, the LLM-powered node has autonomy.
Write the first version of the graph:
- Configuration. Pick
agent_namefrom the user's requirements (kebab-case; also the.agentfilename stem and broker id, e.g.it-help-investigation). - Trigger (entrypoint). Each broker has exactly one trigger per declared interface.
kind: "a2a",target: "brokers://<broker-id>/a2a",on_message:is a fixedtransition to. Conditionals in the trigger are a compile error — use a router downstream. - LLM-powered nodes (pick the right type per stage):
- Reasoning node (
subagentkeyword) — LLM-with-tools. Default LLM-powered type. Has built-in HITL. - Orchestrator node (
orchestratorkeyword) — LLM-with-tools, specialized for coordinating multiple actions toward a compound goal. - Generate node (
generatorkeyword) — LLM-without-tools. One-shot generation, summarization, or classification with structured output.
- Reasoning node (
- Data structure (variables). Declare any state shared across nodes.
- Deterministic connections. Every non-terminal node has a single
on_exit: -> transition to @<nodeType>.<nodeId>. Every reachable path terminates atecho. - Conditionals live in router nodes. Routers declare
routes:+otherwise:and have noon_exit(transition toinside routeron_exitis a compile error). Hard constraints from Phase 1 → router conditions, not prompts. Prompts can be ignored; router conditions cannot. - First node after trigger should NOT be a pass-through executor that copies
@request.payload.message. Reference@request.payload.message.parts[0].textdirectly downstream. - Echo terminus. Every reachable path ends in
echowithkind: "a2a:status_update_event"(or"a2a:artifact_update_event"for artifacts). Seereferences/gotchas.md§ "Echo node" for theTASK_STATE_*enum anda2a.*helper rules.
Write a first version of system.instructions and each LLM-powered node's prompt — keep them brief; Phase 5 refines.
Update the brokers entry in agent-network.yaml to reference the new .agent file. For full compile-error rules see references/gotchas.md § "Compile-error rules". For the structural template see references/canonical-example.md.
Step 5: Asset Assignment to Graph (Phase 4)
Goal: Assign assets from the YAML to the correct LLM-powered nodes.
Guiding principles:
- Specialize each LLM-powered node in one domain. Lump similar assets into the same node rather than spreading them.
- Reasoning vs. Orchestrator — pick by what's connected:
- Only MCP assets on the node → Reasoning node (
subagent). - Any A2A assets on the node → Orchestrator node (
orchestrator).
- Only MCP assets on the node → Reasoning node (
- ≤ 4 total assets per LLM-powered node (A2A + MCP combined). More than that → hallucinations. Split the node.
- Principle of Least Privilege. One node gets read-only tools; another gets write-access tools. Never combine.
- Irreversible mutations (escalate, delete, send-to-customer, etc.) MUST be in
executornodes gated byrouter. Never put them on a reasoning/orchestrator node — the LLM could invoke them bypassing the router. Idempotent updates (status updates, ticket updates) MAY live on an orchestrator if part of the compound goal.
Action:
- Re-read the graph, the YAML, and the per-node instructions to refresh context.
- For each reasoning/orchestrator node, assign assets: "Which YAML asset does this node need?" If none is available, ask the user to create one.
- Bind in the
.agentfile. Each asset gets anactions:entry (A2A:target+kindonly, noinputs:; MCP:target,kind,tool_name, optionalinputs:). Reference fromreasoning.actions(reasoning/orchestrator nodes) ordo: run(executor nodes). - Review with the user once all nodes are assigned: "Here are the asset → node assignments: [list]. Confirm?" Stop.
- Ask the user to pick the LLM for each LLM-powered node (different nodes can use different LLMs — cheap one for classification, stronger one for orchestration).
- Write a one-line human-readable description of what each reasoning/orchestrator node does. Store it on the node.
For full binding rules see references/gotchas.md:
- § "Compile-error rules — action invocation" — A2A bare reference vs
with message =in executor; MCPwithrules;http_headersimplicit. - § "Stage 4: Bind to nodes" — 4-asset cap, least-privilege, action alias naming.
Step 6: Instruction Refinement (Phase 5)
Goal: Refine and battle-test instructions on every LLM-powered node. One node at a time, never batch.
For each generate/reasoning/orchestrator node:
- Name the node, once: "Refining
classifySeverity." (Don't repeat which node you're on across turns — the user remembers.) - Show V1 of
system.instructions(the brief draft from Phase 3). - Ask once: "Overall feedback? Any success criteria or few-shot examples?" Stop.
- Write V2 as a numbered routine. Each step → one tool call or one output decision. No "be helpful" / "be professional".
- Make outputs concrete. If the node has
outputs.properties.severity.enum, the prompt must say "Set severity to high when X, low otherwise" using the enum literals exactly. - Anticipate edge cases. What if a key field is missing? Bake the answer in.
- Per-node contradiction test. Does any V2 step get ruled out by deterministic graph logic? Reconcile.
- Apply V2 to file immediately. Move to next node.
After every node is refined: run the cross-node contradiction test — does any prompt step conflict with another node's prompt or the graph? Surface conflicts to the user and resolve.
Step 7: Final Topology Review (Phase 6)
Cleanup, then validate.
Cleanup:
- Remove unresolved
{{...}}markers, unusedexchange.jsonvariables. - Remove unused
registryassets (not referenced bycontext.connections, actions, or LLM blocks). - Remove unused
context.connectionsentries. - Remove orphaned action definitions in
.agentfile. - Remove empty YAML keys (
registry.llms:with no entries → drop the key).
Validate. Run the build command (CLI preferred → MCP fallback → structural checklist below + install hint). Full command syntax in references/gotchas.md § "Step 7 — Validate / build".
Structural checklist:
- Every node reachable from trigger? No orphans.
- Every reachable path terminates at
echo? - Every
routerhasroutes(≥1) andotherwise? - Every
subagent/orchestratorhasreasoning.instructionsAND ≥1 action OR HITL? - Every action referenced in nodes matches an entry in
actions:? - Every
${...}variable has matchingexchange.json.metadata.variablesentry? - Every
context.connections.<id>.ref.nameresolves to a registry entry ORexchange.json.dependencies? - All A2A actions in
reasoning.actionsare bare references (nowith message =)? - All MCP
withparameters reference declaredinputs:fields? - All echo
statevalues in the allowed enum? - Hard constraints enforced via router conditions, not prompts?
- Operational caps set:
max_number_of_loopslowered from default 25 (e.g., 3 classification, 5–10 orchestration);task_timeout_secsset if calling slow downstream agents?
Fix loop:
- Group errors by file. Auto-fix formatting/indentation/missing required keys. For schema-required references missing, ask the user — never auto-insert missing assets. Loop until clean.
When clean: "Project is validated and ready. Want to publish to Exchange and deploy to runtime?"
Step 8: Publish (optional)
Only if user wants to. Prereqs: authenticated CLI/MCP context; exchange.json has assetVersion and no empty default: "" for secret: true variables.
Run the publish command (CLI preferred → MCP fallback → doc link). Surface published asset URLs from the output. Full command syntax is in references/gotchas.md § "Step 8 — Publish".
Step 9: Deploy (optional)
Only if user wants to. Publish must have happened first.
Ask the user: environmentName, targetSpace (private space), and any deployment properties for env-specific secrets (e.g., --property openai.apiKey:STAGING_API_KEY).
One-time setup per private space: if the target space has no gateways yet, run the gateway setup command first.
Run the deploy command (CLI preferred → MCP fallback → doc link). Surface deployment URL/ID. Full command syntax, gateway defaults, and CI flags are in references/gotchas.md § "Step 9 — Deploy".
Workflow B — Edit an existing project
Universal edit principles:
- Impact analysis first. Identify every downstream node, expression, or connection that depends on the change. Confirm with user.
- Minimal disruption. Edit only what's asked. Exception: node-type changes (subagent ↔ orchestrator) when actions are added/removed.
- Registry-first. New assets go in
agent-network.yamlregistry/context (orexchange.json.dependencies) BEFORE being referenced from.agent. - Defer validation while editing. Lint errors mid-edit are expected; validate at the end.
B.1 — Add or swap an asset
- Decide mode (Inline or Exchange — see
gotchas.md). - Inline:
registry.{agents,mcps,llms}+context.connections.<id>with auth +exchange.json.metadata.variables. Exchange:exchange.json.dependencies+context.connections.<id>withref.name+ref.namespace. - Add
actions:entry in the.agentfile. - Reference from target node's
reasoning.actions(subagent/orchestrator) ordo: run(executor). - Re-evaluate node type if action count changed. Single action →
subagent. Multi-action →orchestrator. Update@<oldType>.<id>references downstream. - Cap check. If a node now exceeds 4 actions, propose splitting.
- Update
system.instructionsto explain how to use the new asset. - Run Step 7 (validate).
B.2 — Change graph logic
Edit .agent. After any change, walk trigger → every echo and confirm:
- Every router
when:references a real, reachable upstream output (not@request.payloaddirectly). - Hard constraints still in router conditions, not prompts.
- No node became unreachable or dead-end.
- No
transition toin a router'son_exit(compile error).
Run Step 7.
B.3 — Refine instructions
Edit .agent only. Apply Phase 5 contradiction tests. If user pastes a policy doc, transform into numbered routine — don't paste verbatim. Run Step 7.
B.4 — Add or change a connection policy
Edit agent-network.yaml. The GA schema supports policies even though the build flow doesn't surface them.
A policy has two parts:
- Definition —
context.policies.<policyId>. - Binding — referenced from
context.connections.<connId>.policies.outboundorbrokers.<brokerId>.interfaces.a2a.policies.{inbound,outbound}. Always reference by id.
For Exchange-published policies: add to exchange.json.dependencies first, then bind. Run Step 7.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/mulesoft/mulesoft-dx/build-agent-broker-project">View build-agent-broker-project on skillZs</a>