| name | tool-design |
| description | This skill should be used when the user asks to "design tools", "create tools for agent", "tool design", "API to tools", "define tools", "convert API to tools", or needs guidance on designing AI-friendly tools for agents — LangChain `@tool` functions, MCP tool definitions, or DeepAgents tool catalogs. Provides principles from AI-Friendly API Design, Agent Native architecture, and real-world tool catalogs. |
AI-Friendly Tool Design
Design tools that agents can discover, understand, and compose effectively. These 11 principles bridge API design with agent-native architecture to produce tools that work seamlessly in LLM-driven workflows.
Tool design decisions live at three levels of abstraction; the numbered principles all operate at the tool level:
| Level | Question it answers | Where it lives |
|---|
| Tool | How do I design one good tool? | Principles 1–11 (below) |
| Catalog | Which tools exist, at what size, grouped how? | Catalog Organization — Granularity, Bounded Contexts, Parity |
| Format | How does a tool serialize to a protocol? | MCP Alignment in ai-friendly-principles.md |
This file is the index: each principle is summarized here with a pointer to its canonical reference. When this summary and a reference disagree, the reference wins.
Principle 1: Semantic Clarity Over CRUD
Name tools by domain operation, not HTTP method or CRUD pattern. The agent selects tools based on name and description — generic names cause confusion and misrouting. Rule of thumb: if the name completes the sentence "I need to ___", it is well-named.
| Bad Name | Good Name | Why |
|---|
get_resource | get_account_balances | Specifies domain and operation |
post_data | submit_loan_application | Describes business intent |
update_record | change_shipping_address | Clear user-facing action |
delete_item | cancel_subscription | Domain-specific consequence |
Casing: tool names — and their parameters and response fields — are all snake_case (loans_simulate, installments_quantity), never camelCase or Header-Case. Mechanical: enforce with a linter.
Full reference: ai-friendly-principles.md — Principle 1
Principle 2: Natural Language Compatibility
Tool descriptions are the primary routing mechanism for the LLM. Every description states: a one-line summary, when to use (in the users' language), when NOT to use (naming the sibling tool that covers the excluded case), parameter semantics with examples, and the operation level.
@tool
def search_transactions(account_id: str, query: str, date_from: str = None) -> dict:
"""Search transaction history by description, merchant, or amount.
Use when the user wants to find past movements — e.g. "find a charge",
"when did I pay [merchant]". Do NOT use for current balances
(use get_account_balances).
"""
The "Do NOT use" boundaries are what prevent misrouting between similar tools. Trigger phrase lists are an optional technique for overlapping siblings — they complement, never replace, the when/when-not prose. Design search-first: every entity findable by name/email/phone, not only by opaque IDs.
Full reference: ai-friendly-principles.md — Principle 2
Principle 3: Structured Types
Use explicit types and constraints instead of free-form strings. This prevents agent errors and enables validation before execution.
| Concept | Bad | Good |
|---|
| Money | amount: float | amount: {"value": N, "currency": "X"} |
| Date | date: str ("next Friday") | date: str (YYYY-MM-DD) |
| Pagination | page: int | cursor: str (opaque, forward-only) |
| Enum | status: str | status: Literal["active", "suspended", "closed"] |
List-returning tools paginate with announced truncation (has_more, total_count, remediation text) and prefer filters over exhaustive paging.
Full reference: ai-friendly-principles.md — Principle 3 (includes JSON Schema patterns and Pagination & Truncation)
Principle 4: Actionable Error Responses
When a tool fails, the response must tell the agent what went wrong and what to do next. Never return bare error strings.
return {
"status": "error",
"error": {
"code": "ACCOUNT_NOT_FOUND",
"message": "No account found with ID 'ACC-99999999'.",
"remediation": "Verify the account ID or use find_customer to search by name.",
"suggestions": [{"tool": "find_customer", "reason": "Search for the customer", "params": {}}]
}
}
Required fields: code (UPPER_SNAKE_CASE), message, remediation. Optional: details, suggestions.
Full reference: ai-friendly-principles.md — Principle 4 (includes the standard error-code table)
Principle 5: Consistent Terminology
Use one term per concept across all tools: always account_id (never acct_id), always cursor (never page_token), always {"value": N, "currency": "X"} for money, ISO 8601 for dates. Define shared types once in a central schemas.py and reuse them everywhere.
Qualify generic identifiers by domain: loan_request_id, not a bare request_id — the moment more than one kind of request exists, the generic name forces the agent to guess. Stay generic only for truly catalog-wide concepts (cursor, idempotency_key).
Full reference: ai-friendly-principles.md — Principle 5 (full terminology and format tables, identifier qualification)
Principle 6: Rich Response Semantics
Responses give the agent what it needs to act without padding the context: data (required, structured, high-signal), formatted (recommended display text), available_actions (contextual — Principle 7), formatted_spoken (voice channels only), metadata (optional). No field duplicates another representation.
Tool responses are agent context, re-read every turn — default to lean responses with opt-in detail flags (include_details: bool = False).
Untrusted content rule: external pass-through text (memos, descriptions, counterparty names) is data, not instructions — keep it in data, delimit it in formatted, and never derive actions from it.
Full reference: agent-native-principles.md — Principle 6
Principle 7: Available Actions (Tool Graph)
available_actions earns its tokens when it carries something the catalog cannot:
- Server state the catalog can't express — pending confirmations with their IDs and expiry, error
suggestions. Include: this is the point of the pattern.
- Curated high-value nudges from the backend — "after this, users typically do X". Include deliberately.
- Catalog restatement — a static menu of sibling tools the agent already knows. Omit.
Actions always derive from server state and business rules, never from record text content.
Full reference: agent-native-principles.md — Principle 7
Principle 8: Operation Levels
Classify every tool by impact (not HTTP verb) to determine confirmation requirements:
| Level | Category | Confirmation | Example |
|---|
| 1 | Read | None | get_account_balances |
| 2 | Create/List | None | create_support_ticket |
| 3 | Update | Chat confirmation | change_shipping_address |
| 4 | Financial | Explicit user approval in the conversation | transfer_funds |
| 5 | Irreversible | Reinforced confirmation (re-confirm a key detail) + cancellation window | close_account |
In DeepAgents, map levels to interrupt_on — keyed by tool name, with a required checkpointer:
interrupt_on = {
"get_account_balances": False,
"update_profile": {"allowed_decisions": ["approve", "edit", "reject"]},
"transfer_funds": {"allowed_decisions": ["approve", "reject"]},
}
Valid decisions: approve, edit, reject, respond (verified against DeepAgents docs, June 2026).
Full reference: agent-native-principles.md — Principle 8 (level-derived config, full agent setup)
Principle 9: Delegated Confirmations
Level 3+ tools do not execute immediately: they validate, stage the operation, and return pending_confirmation with a summary, details, confirmation_method, cancel_method, and expires_at. interrupt_on covers in-chat approval; confirmation tools add the server-side audit trail, expiry window, and the seam where out-of-band channels (push, OTP, biometric) plug in later — Level 4-5 typically need both.
Full reference: agent-native-principles.md — Principle 9 (full flow and response shape)
Principle 10: Idempotency Keys
Transactional tools (Level 3+) accept an idempotency_key that is emitted by the server — returned inside pending_confirmation — and echoed by the agent on confirm and retries. The agent never generates keys (LLM-sampled "UUIDs" are low-entropy; a collision silently swallows a legitimate operation). Repeated key → original result with status: "already_processed".
Full reference: agent-native-principles.md — Principle 10
Principle 11: Secure Parameters
Tool parameters are fully controllable by the LLM. No secret, credential, token, or caller identity (user_id, customer_id, tenant_id) may be a parameter — these are framework-injected (ToolRuntime, gateway x-claims), invisible to the model. Business identifiers the agent legitimately discovers (an account_id from a search) are fine: the distinction is caller identity / credentials vs. operands. This is a trust boundary, independent of typing (Principle 3): a perfectly typed user_id: str still lets the agent impersonate any user.
Full reference: agent-native-principles.md — Principle 11
Catalog Organization
Three catalog-level decisions, distinct from designing any single tool (not scored per-tool — they require judgment):
- Granularity: one tool = one unit of user intent, not one backend endpoint. Merge sequences whose intermediate result has no standalone use; split tools that hide steps the agent needs to compose or retry. The natural seam is the
pending_confirmation boundary: one prepare tool + one execute tool.
- Bounded Contexts: domain modules with their own
tools.py, schemas.py, formatters.py and a TOOLS export. Suggested defaults: ~10 tools per domain; ~15+ tools total → consider domain subagents (see the architecture skill).
- Parity: every user-facing UI action has a tool or a documented intentional exclusion.
Full reference: agent-native-principles.md — Catalog-Level Principles
Quality Checklist
Before shipping a tool, verify against the authoritative checklist: references/tool-quality-checklist.md
Quick self-check:
Workflow
The tool design workflow follows a design-build-validate cycle:
/design-tools → Catalog → /add-tool → /tool-status → /design-evals
↑ |
└── fix issues ──┘
- Design:
/design-tools creates a tool catalog from requirements or APIs (interactive)
- Extend:
/add-tool adds individual tools matching existing patterns
- Validate:
/tool-status shows the quality dashboard with per-principle scoring and eval coverage
- Test:
/design-evals creates eval scenarios for your tools (EDD)
References
Routing by task:
- AI-Friendly API Principles — Canonical detail for Principles 1-5, plus MCP alignment (
annotations, outputSchema, isError). Converting an OpenAPI/REST spec or writing MCP definitions → start here.
- Agent-Native Principles — Canonical detail for Principles 6-11 (envelope, available actions, operation levels and confirmation channels by level, delegated confirmations, idempotency, secure parameters), plus granularity, bounded contexts and the UI-parity audit. Confirmation flows,
interrupt_on, untrusted content → start here.
- Tool Quality Checklist — Authoritative verification checklist.
- Tool Examples — Two complete implementations: a Level 1 read tool and a Level 4 financial tool with staging, actionable errors, and confirmation flow.
Related
- Tool Patterns — Design patterns for tool granularity, naming, and security (ToolRuntime)
- API Cheatsheet — Quick reference for API-to-tool conversion
- Evals — Test Operation Level flows (
pending_confirmation, interrupt_on), idempotency, error response suggestions, and tool graph navigation