Tools that suggest the next tool
How we put tool chaining inside MCP responses, so an AI agent never has to guess what to do after a violation.
An AI agent writes code. The code breaks a design system rule. Now what?
If governance lives in the system prompt, the agent is expected to notice its own mistake and self-correct. Sometimes it does. Usually it doesn't, because fifty rules across three design systems is not a thing you hold in working memory while also writing React.
MCP moves governance from the prompt to tools. get_forbidden_primitives returns what not to use.
get_active_constraints returns recommendations for the current context.
validate_code checks a snippet. suggest_fixes returns remediation options.
Each call is discrete, with a typed input and a typed output.
The gap is what happens between calls. If validate_code returns a list of violations,
what does the agent do next? Call suggest_fixes? Call get_forbidden_primitives
to understand the rule it broke? Re-validate after the fix lands? The order matters. It is not obvious
from the tool names.
The common fix is to put that logic in the client. Write a state machine in the agent harness. Bind the chain at the call site. That works until you add a new tool, at which point every client reimplementation breaks.
We put the chain inside the response instead.
Every response carries the next step with it.
Every tool we expose returns a relatedToolHints field. The hints are keyed by outcome state.
A clean result returns hints under onClean. A result with violations returns hints under
onIssues. The agent reads the hints and calls the suggested next tool.
The loop, written out
validate_code runs. Clean? onClean points at the generator or the commit step.
Violations? onIssues points at suggest_fixes, with the violation payload already
shaped for the next call. Call suggest_fixes. Its response points at validate_code
again, with the proposed revision in hand. The loop closes inside the tool responses. There is no
orchestration layer.
For context-gathering, the order is reversed. Call get_forbidden_primitives first. Its
onClean hints point at the generator, because if you know what is forbidden you can generate
without guessing. If the result includes recently deprecated entries, the onIssues hints point
at a cleanup flow before generation starts.
For free-text intent, call route_intent with a human description of what you want to build.
The response carries hints that point at get_active_constraints scoped to the resolved context,
then at the generator. One intent call cascades into a full context-aware chain, without the agent
assembling the chain itself.
Why it has to live in the response
The chain is semantic, not orchestrational. suggest_fixes follows validate_code
because the second consumes the first's output. That relationship is a property of the tools, not of the
caller. Putting it in the caller duplicates the relationship in every client and leaks the tool topology
into every consumer.
Putting it in the response means the tools own their own composition. A new tool ships with its hints.
Swap suggest_fixes for suggest_fixes_v2, update the hint, every client follows.
The client stays a thin dispatcher. The tools stay in charge of how they compose.
What we got from it
Agents that used to call one governance tool and stop now run full chains. A validate_code
call that finds a violation no longer returns a list and leaves the agent guessing. It returns the list
and a pointer to the tool that produces fixes, with the violation payload ready to pass through. The fix
runs, the code re-validates, and the loop ends either in a commit or a refinement request. Five to ten
calls, runs on its own, every step logged.
Clients stay simple. The agent harness does not know anything about design systems. It calls tools and follows the hints.
And the hints are themselves governance, not just orchestration. onIssues does not say
"call suggest_fixes." It says "call suggest_fixes with this violation payload, at this severity, scoped
to this context." The response is not just suggesting the next call. It is preparing it.
The claim, in one line
A tool response that carries its own next-step chain, keyed by the outcome state of the call, with the payload for that next call pre-shaped in the hint. For governance, the domain is design-system rules. The shape generalizes.
Note on prior art. This post is also a defensive publication. The combination of
state-keyed response hints (onClean / onIssues), closed-loop tool chaining scoped
to design-system governance, and context-prepared hint payloads that pre-fill the next call's arguments is
disclosed here as of April 20, 2026. This disclosure is licensed CC0 / public domain.
Building preset AI to make design systems executable. Writing about governance, AI in design tooling, and the space between prototype and production.