Design tools, functions, CLIs, and API endpoints that AI agents call reliably. Use when defining a new tool schema, reviewing one that agents misuse, or adding safety (dry-run, idempotency, undo) to an existing tool.
./install.sh tool-design-for-agentsname: "tool-design-for-agents" description: "Design tools, functions, CLIs, and API endpoints that AI agents call reliably. Use when defining a new tool schema, reviewing one that agents misuse, or adding safety (dry-run, idempotency, undo) to an existing tool."
A model calling your tool has no intuition about it. Everything it can rely on is in the schema, the description, the error messages, and the output shape. This skill turns those four surfaces into a tool an agent can actually drive: narrow enough to route correctly, descriptive enough to call correctly, and forgiving enough to recover from mistakes.
List every operation the toolset must support. Then split until each tool does one thing:
search_invoices, not invoice_manager. Agents route by name, and a kitchen-sink name forces them to guess which mode they are in.The description carries as much weight as the parameter list. Treat it like a system prompt for this one tool:
verb_noun. Say what it returns, not just what it does: "returns the matching rows, or an empty list" beats "queries the database"."status": filter by status. One of: open, paid, overdue. Anything else returns an error listing the valid values.limit with a default and a max, not unbounded lists.limit/cursor), summarize instead of dumping, return references (ids, paths) the agent can fetch later.Agents recover from errors constantly; your error message is their debugger. Every failure returns a structured error with these fields:
code: machine-readable, names the category (invalid_enum, not_found, conflict, rate_limited, needs_approval).message: plain-language, states what was wrong and what to do next.retryable: true or false. The agent decides whether to retry based on this, so get it right: rate_limited is retryable, invalid_enum is not.details: the missing piece. Invalid enum? List the valid values. Not found? Say what was searched and where. The fix belongs inside the error.Rules: never return a bare "Error: something went wrong". Never make the agent guess from HTTP codes alone. For duplicates, return the semantically equivalent success (see step 5), not a conflict error the agent cannot resolve.
A ready-to-use error catalog template is in references/error-catalog-template.md.
Sort every mutating tool into one of three tiers and treat each tier differently:
undo handle in the result: the exact inverse call or an id that reverts it.dry_run flag that returns the full plan (what would change, conflicts found, cost/impact estimate, a preview_id), then an apply step that commits the exact preview. Previews expire and log the actor and inputs. Never apply a plan the agent has not seen.Agents retry. Networks drop. The tool must make "call it again" mean "finish it once":
idempotency_key (client-generated, one per logical operation). Same key + same inputs returns the stored result. Same key + different inputs is rejected.{"status": "already_done", "id": "inv_123"}, not an error the agent has to interpret.references/worked-example.py shows a minimal in-memory version with tests.Before shipping, run this gauntlet against the real implementation:
dry_run and confirm nothing changed, then apply and confirm the change matches the preview exactly.For each tool you design, deliver:
references/checklist.md checked, with the failing items fixed or the tool redesigned.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.