Every lesson so far has looked at abilities mostly one at a time. Real requests rarely are: “find last month’s top posts and draft a roundup linking to them” needs several tool calls in sequence, each one feeding the next. This lesson is about designing abilities that chain well, and understanding what actually orchestrates that chain, which is not your MCP server.
Several related abilities from Course 2 (or built across earlier lessons in this course), and a connected client from Lessons 1 or 2. This lesson doesn’t introduce new MCP mechanics, it’s about designing your existing abilities so a model can combine them well.
There is no “workflow” object in MCP
This is worth stating plainly because it’s easy to expect otherwise: MCP has no concept of a multi-step workflow, a saved sequence, or a pipeline. What actually happens when an agent completes a multi-step task is that the model, Claude or whichever client you’re using, reads the available tool list, decides on its own which tools to call and in what order, calls the first one, reads the result, decides the next call based on that result, and repeats until it thinks the task is done. Your abilities are the building blocks. The model is the one doing the planning, every single time, fresh, based on what’s in front of it.
This means your job isn’t to build “a workflow,” it’s to build individual abilities whose inputs and outputs compose well together, so that whatever plan the model comes up with actually works.
Designing abilities that chain well
A worked example: three abilities, one request
You: "Find last month's three best-performing posts by comment count,
draft a roundup post linking to each of them, and leave it as a draft
for me to review."
For a model to complete that in one conversational turn, it needs three abilities that compose:
// File: inc/abilities/workflow-example.php
// Ability 1: returns structured data with IDs, not just prose
wp_register_ability( 'my-plugin/top-posts-by-comments', array(
'label' => 'Find top posts by comment count',
'description' => 'Returns the top N posts published in a given date range, '
. 'ranked by comment count, each with its post ID, title, URL, and comment '
. 'count. Use this to identify posts worth referencing in a roundup or summary.',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'since' => array( 'type' => 'string', 'format' => 'date' ),
'until' => array( 'type' => 'string', 'format' => 'date' ),
'limit' => array( 'type' => 'integer', 'default' => 3 ),
),
'required' => array( 'since', 'until' ),
),
'execute_callback' => 'my_plugin_top_posts_by_comments',
'permission_callback' => 'my_plugin_can_read_posts',
'meta' => array( 'mcp' => array( 'public' => true ) ),
) );
// Ability 2: explicitly documents that it accepts the shape Ability 1 returns
wp_register_ability( 'my-plugin/create-draft-roundup', array(
'label' => 'Create a draft roundup post linking to given posts',
'description' => 'Creates a new draft post that summarizes and links to a list of '
. 'existing posts. Accepts an array of post IDs, typically from a tool like '
. 'my-plugin/top-posts-by-comments. Always creates the roundup as a draft.',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'title' => array( 'type' => 'string' ),
'post_ids' => array( 'type' => 'array', 'items' => array( 'type' => 'integer' ) ),
),
'required' => array( 'title', 'post_ids' ),
),
'execute_callback' => 'my_plugin_create_draft_roundup',
'permission_callback' => 'my_plugin_can_edit_posts',
'meta' => array( 'mcp' => array( 'public' => true ) ),
) );
With those descriptions in place, a capable model reliably plans: call
top-posts-by-comments with last month’s date range, read the three post IDs back,
call create-draft-roundup with those exact IDs. Nobody wrote that sequence down
anywhere, it’s a consequence of the abilities being described well enough for the
model to connect them itself.
What breaks mid-chain, and how to design around it
Even with well-written descriptions, models don’t always chain steps in the sequence you’d design by hand, particularly with ambiguous requests. Test with realistic, slightly underspecified phrasing, not just the cleanest possible request, that’s what reveals which of your descriptions need to be more explicit about ordering or dependencies.
Test it
Run the full worked example against your own connected client and confirm each step actually happened, not just that a plausible-looking final message came back.
Recap
Multi-step agent workflows aren’t something you configure, they emerge from the model planning a sequence of calls against whatever abilities you’ve registered. Your part of the job is making each ability’s inputs and outputs compose well, IDs over prose, explicit references to the tools that typically feed them, and specific, recoverable errors, so that whatever sequence the model comes up with actually works end to end.
Resources & further reading
- MCP tools specification, modelcontextprotocol.io
- Abilities API reference, developer.wordpress.org
- MCP Adapter repository, GitHub