run_stitch & code-mode
Drive stitches from a sandbox with one context-frugal tool instead of flooding the model with per-endpoint tools.
Drive stitches from an agent sandbox with a single run_stitch tool — pass
{ name, input } and it covers every stitch you register, so the model's tool
list (and its context) stays tiny no matter how many stitches there are. Two
companion tools round out the surface: list_stitches discovers the available
names, and describe_stitch returns one stitch's shape before it runs.
Example
The agent first discovers what is available, then runs one by name. Both are plain MCP tool calls — there is no library import on the agent side.
{ "name": "list_stitches", "input": {} }list_stitches returns the registered stitches with their method and path, so
the agent knows what to pass to run_stitch:
{
"name": "run_stitch",
"input": { "name": "getUser", "input": { "params": { "id": 1 } } }
}Here the inner input is the stitch input — { params?, query?, body?, headers? } — and the stitch runs against api.example.com behind the
capability boundary. The agent never sees the credential.
describe_stitch
Before running a name, an agent can ask for its shape. describe_stitch takes
{ name } and returns one text result — a JSON description built from the
stitch's public __config: its endpoint and surface, which input slots it
takes, whether the output is validated and what it picks, the auth scheme
(never the token), which policies are on, the pipeline of steps a call runs
through, and a Mermaid diagram.
{ "name": "describe_stitch", "input": { "name": "getWidget" } }returns one text result whose body is JSON like:
{
"name": "getWidget",
"endpoint": "GET https://api.example.com/widgets/{id}",
"surface": "http",
"input": {
"params": true,
"query": false,
"body": false,
"headers": false
},
"output": { "validated": true, "pick": "data" },
"auth": "bearer",
"policies": {
"retry": true,
"throttle": false,
"cache": false,
"timeout": true
},
"pipeline": [
"call",
"GET /widgets/{id}",
"retry",
"validate",
"pick: data",
"result"
],
"diagram": "flowchart TD\n subgraph ..."
}The auth field is the scheme only (read from __config.authScheme) — the
credential never crosses the boundary. The diagram reuses
toMermaid(registry, { name }), the same call graph stitch diagram renders. An
unknown name is an error result, not a throw:
{
"content": [
{
"type": "text",
"text": "unknown stitch \"x\". Available: getWidget, ping"
}
],
"isError": true
}Options
Three tools make up the whole surface. run_stitch takes { name, input },
where input is the stitch input { params?, query?, body?, headers? };
list_stitches takes no arguments and returns the names, methods, and paths;
describe_stitch takes { name } and returns the JSON shape above.
This is code-mode: one tool for every stitch, rather than one MCP tool per
endpoint. One-tool-per-endpoint floods the model's context — every registered
stitch adds another schema the model must carry — while run_stitch keeps the
tool list at a constant three no matter how many stitches you register.
The agent calls run_stitch and never touches the credential: it names a
capability, the server holds the secret. That is
capability, not credential applied
to the agent boundary.
This page is about the tool shape and why code-mode. For starting the server
(stitch mcp) and the transport details, see the MCP
surface.
If you author the stitch that backs a name like getUser, it is an ordinary
stitch from stitchapi. Adding an output schema (raw Zod here, the visible
default) is what makes describe_stitch report validated: true:
import { } from 'stitchapi';
import { } from 'zod';
const = ({
: 'https://api.example.com',
: '/users/{id}',
: .({ : .(), : .() }),
});