Delegating from Claude Code
The platform MCP server includes a set of delegation tools. They let an AI coding assistant such as Claude Code hand a piece of work to an FYAI agent, team or workflow, carry on with something else, and find out how it went — the same way it would hand work to one of its own subagents.
Typical uses:
- "Delegate this bug fix to our developer agent and tell me when the PR is up."
- "Run the weekly compliance workflow with this input and report back."
- "Turn this implementation plan into a program the platform runs, with a sign-off between phases."
The tools work from any MCP client. This page uses Claude Code in its examples.
How a delegation is tracked
Each delegation becomes an activity in a program called Claude Code delegations, in a phase called Inbox. The first delegation in a project creates that program for you. Because delegations are ordinary program activities, you can see and manage them in the web app under Programs, with their status, transcript, artifacts and history. See Programs.
Every delegation has a ref — an opaque string such as p12.ph34.a567.r890 — which you pass to the other tools to check on it, answer it or cancel it. The tools also return a fui_url that opens the program in the web app.
Before you start
- Connect the platform MCP server to Claude Code, with an API key that has Write access to the project you want the work to run in. See Platform MCP server.
- Make sure the agent, team or workflow you'll hand work to exists in that project, and has the tools and integrations the work needs — for example a GitHub integration if it should open pull requests. See Agents.
- If the work involves code, push it first. The platform agent clones from your repository; it can't see your local, uncommitted changes or your conversation with Claude.
The delegation tools
| Tool | What it does |
|---|---|
delegate_task | Hand a free-form task to an agent or team and start it. |
run_workflow | Start an existing workflow with an input, as a tracked delegation. |
delegation_status | Get a delegation's current state, progress, summary, artifacts and pull request links. |
list_delegations | List recent delegations, optionally filtered by state. Default 20. |
answer_delegation | Answer the question a blocked delegation asked, and resume it. |
cancel_delegation | Stop a delegation's run and drop any queued work behind it. |
create_program_from_plan | Create a whole multi-phase program from a plan. |
delegate_task
| Argument | Required | Purpose |
|---|---|---|
task_brief | Yes | The task, written so the assignee needs nothing else: what to do, which repository and branch, and how to verify it. |
acceptance_criteria | Yes | What "done properly" means. It's added to the message the agent receives under DEFINITION OF DONE, and the run is judged against it. |
repo | No | The repository the task is about, for example acme/billing-service. |
base_branch | No | The branch to work from. |
assignee_agent | No | Agent name or ID. |
assignee_team | No | Team name or ID. Takes precedence over assignee_agent. |
llm_config | No | LLM config name or ID to use for this run only. |
guidance | No | Extra instructions for this run only. |
idempotency_key | No | Only needed to force two identical-looking calls to create two delegations. |
Names must match exactly; if two agents share a name, pass the ID. Calling delegate_task again with exactly the same arguments returns the same delegation rather than starting a duplicate.
It returns:
{
"ref": "p12.ph34.a567.r890",
"program_id": 12,
"phase_id": 34,
"activity_id": 567,
"run_id": 890,
"mission_id": 5150,
"fui_url": "https://fyai.co.nz/programs/12"
}
run_workflow
| Argument | Required | Purpose |
|---|---|---|
workflow | Yes | Workflow name or ID. |
input | Yes | The message the workflow starts with. It must stand on its own. |
attribute_values | No | Values for the workflow's input attributes, keyed by attribute name. |
idempotency_key | No | As for delegate_task. |
It returns the same shape as delegate_task.
delegation_status
Pass the ref. The response includes:
| Field | Meaning |
|---|---|
state | queued, running, blocked, completed, failed, orphaned, cancelling or cancelled |
progress, summary | What the run reports about itself |
artifacts, pr_urls | What it produced, including links to any pull requests |
error, error_kind | Why it failed |
blocked_question | When state is blocked, the question the agent needs answered |
last_heartbeat_age_s | Seconds since the run last reported it was alive |
completed, failed, orphaned and cancelled are final. orphaned means the run stopped reporting and was presumed lost. cancelling isn't final yet: the platform is waiting for the run to confirm it stopped.
A completed state means the run finished, not that it succeeded at the task. Check summary, artifacts and pr_urls — and the pull request's own checks — before treating the work as done.
answer_delegation
When a run is blocked, it has stopped to ask a question. Call answer_delegation with the ref and your answer. The activity runs again with your answer, as a new run — the tool returns a new ref, and you should follow that one from then on.
Waiting without polling: fyai-platform-mcp wait
Rather than having your assistant poll delegation_status in a loop, use the server's wait command. It polls every 15 seconds and exits when the delegation reaches a state you need to act on:
fyai-platform-mcp wait p12.ph34.a567.r890 --timeout 7200
| Exit code | Meaning |
|---|---|
0 | completed |
1 | failed, orphaned or cancelled |
2 | blocked — answer it with answer_delegation |
3 | wait itself timed out (default 3 hours). The delegation may still be running; run wait again to keep watching. |
It prints a line each time the state changes, and uses the same FYAI_API_KEY as the server.
In Claude Code, run it as a background Bash command straight after delegate_task or run_workflow returns. Claude carries on with other work and is woken when the command exits, then reads delegation_status and reports the real outcome.
wait is a command of the Python package (fyai-platform-mcp). The npm wrapper (npx @fyainz/platform-mcp) always starts the MCP server and doesn't pass arguments through, so with an npm install run the fyai-platform-mcp executable from the package's .venv/bin folder instead.
A typical exchange
- You ask Claude Code to delegate a task.
- Claude pushes any work the task depends on, then calls
delegate_taskwith a self-contained brief and acceptance criteria, and gives you thefui_url. - Claude starts
fyai-platform-mcp wait <ref>in the background and carries on. - When
waitexits, Claude callsdelegation_status:- Exit 0: it checks the pull request exists and its checks pass, then tells you.
- Exit 2: it relays the agent's question to you, and calls
answer_delegationonly with what you actually said. Then it waits on the newref. - Exit 1: it tells you it failed, with
error_kind. - Exit 3: it checks the status before deciding whether to keep waiting.
Turning a plan into a program
create_program_from_plan creates a complete program from a structured plan in one call. Use it when the work has several phases, dependencies between steps, or needs a person to sign off between stages.
{
"name": "Migrate billing to the new API",
"brief": "Move every billing call from v1 to v2 without downtime.",
"business_context": "v1 is retired on 1 March.",
"tags": ["billing"],
"documents": [
{ "title": "v2 API notes", "content": "…", "doc_type": "reference" }
],
"phases": [
{
"key": "p1",
"name": "Inventory",
"activities": [
{
"key": "p1-a1",
"name": "List every v1 call site",
"description": "Search the billing service for v1 client usage and write up each call site.",
"acceptance_criteria": "A table of every call site with file and line.",
"assignee": { "agent": "Code Analyst" }
}
]
},
{
"key": "p2",
"name": "Migrate",
"activities": [
{
"key": "p2-a1",
"name": "Switch call sites to v2",
"assignee": { "team": "Backend Team" },
"depends_on": ["p1-a1"],
"expected_artifact_types": ["pull_request"]
}
]
}
]
}
| Part | Fields |
|---|---|
| Program | name (required), brief, business_context, tags, documents |
| Document | title, content, optional doc_type (brief, spec, runbook, research, reference, report, meeting_notes, okr, strategy or other), summary, pinned, inject_into_runs (default true) |
| Phase | key and name (required), execution_mode (sequential or parallel), completion_mode, description, activities |
| Activity | key and assignee (required), name, description, acceptance_criteria, prompt, llm_config, depends_on (activity keys), expected_artifact_types |
| Assignee | One of {"agent": …}, {"team": …} or {"workflow": …}, by name or ID |
Behaviour to know:
- The whole plan is checked before anything is created: keys must be unique, every
depends_onkey must exist with no cycles, and every agent, team, workflow and LLM config name must resolve. If anything fails part-way through creation, the program is deleted, so you never get a half-built one. - Every phase except the last gets an approval checkpoint by default, so the program waits for a person to approve before moving to the next phase. Set a phase's
completion_modeyourself to change that. - Pass
run_first_phase: trueto start phase 1 straight away. Otherwise the program is created and waits for you to run it.
The response gives the new program_id, its phase and activity IDs and a fui_url. To run and monitor programs, see Running a program.
Known limitations
- Default assignee. If you don't pass
assignee_agent, the tools look for an agent named Software Developer Agent Escalation, and for an LLM config named GPT 6 Sol. Unless your project has agents and configs with those exact names, always passassignee_agent(orassignee_team) explicitly. If no default LLM config is found and you don't passllm_config, the assignee's own model is used. run_workflowand team delegations also need that default agent. They look up Software Developer Agent Escalation when creating the delegations program, and fail withNo agent named 'Software Developer Agent Escalation' foundif your project has none. Until this is fixed, delegate to an agent withassignee_agent, or create an agent with that name.- Delegations run in the API key's project. To delegate into another project, use a key from that project.
The fyai-delegate Claude Code plugin
FYAI also maintains a Claude Code plugin, fyai-delegate, that bundles the platform MCP server with skills for delegating (delegate), checking status, running workflows (run-workflow) and turning a plan into a program (plan-to-program). It encodes the practices on this page — self-contained briefs, pushing first, background wait, honest reporting. It isn't yet published for customer installation; in the meantime, connect the platform MCP server directly as described above.