6 min read
What changes when your user is an agent
We started exposing Graphtr over the Model Context Protocol expecting an integration job. Wrap the endpoints, describe the tools, ship it. What we got instead was a list of places where the product quietly assumed a person was sitting in front of it.
The API returned a plan, not a design
Our AI endpoint took a prompt and returned a template id plus the copy to put in it. That was the right shape when the caller was our own editor, because the browser did the rendering. An agent has no canvas. It asked for a design and got instructions for making one, which is a bit like ordering dinner and being handed a recipe.
The fix was not more AI. Everything needed already existed: a template registry, a fill function and a renderer. They had simply never been called in sequence on the server, because until now nobody needed them to be.
Every request assumed a canvas
The request type required context: canvas width and height, whether something was selected, what colour the background was. All of it was built by reading a live editor. A headless caller had to invent a canvas it did not have in order to ask a question that had nothing to do with one.
A required field that only one caller can populate is not a required field. It is a coupling you have not noticed yet.
The agent could not see what it made
This was the interesting one. A person looks at the design, decides the headline is too long, and shortens it. That loop is so ordinary it is invisible. An agent that gets back a URL cannot close it.
MCP has an answer: a tool can return an image block, and a vision capable model can look at it. So create_design returns the rendered PNG rather than a link. The agent makes something, looks at it, and tries again. Giving the model eyes mattered more than giving it better instructions.
What we would tell someone starting this
- Return the artefact, not the recipe. If a human would have to do a second step to get the thing they asked for, the API is not finished.
- Audit your required fields for ones only your own client can fill in. Each is a place a second caller cannot go.
- Give the model a way to check its work. An agent that cannot see its output cannot iterate, and iteration is most of what makes it useful.
- Meter it properly. A rate limiter that fails open is fine for a UI feature and wrong for something an automated caller can hit in a loop.
None of this was really about agents. Each one was an assumption that had been sitting in the product since the day it was written, invisible because only one kind of caller ever existed. Adding a second caller is the cheapest audit we have run.