# Writing Tools For Agents

> Use when designing, building, or refactoring tools (function calls / MCP tools) that an AI agent will invoke — how to consolidate tools around workflows instead of wrapping API endpoints, namespace them, return high-signal natural-language context instead of raw IDs/UUIDs, offer concise vs detailed response formats, stay token-efficient with pagination/filtering/truncation, write actionable error messages, prompt-engineer tool descriptions, and drive the whole thing with evaluation-driven development. Reach for it whenever an agent misuses tools, calls too many, chokes on raw tool output, or you're standing up a new MCP server.

- Skill: `nsharandroidnstudio/writing-tools-for-agents` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nsharandroidnstudio/writing-tools-for-agents`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nsharandroidnstudio/writing-tools-for-agents/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: nsharandroidnstudio (https://skillmd.com/u/nsharandroidnstudio)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/nsharandroidnstudio/writing-tools-for-agents

---


# Writing Effective Tools for AI Agents

**Core mental model:** *"Tools are a new kind of software which reflects a contract between deterministic systems and non-deterministic agents."* Traditional APIs optimize for **predictability** (same input → same output). Agent tools must optimize for **ergonomics** — an agent might use a tool differently every time, or skip it and rely on its own knowledge. Design for how the agent actually thinks, not for API tidiness.

## When to use this

- Standing up a new MCP server / function-call toolset.
- An agent calls the wrong tool, chains too many calls, or ignores a tool it should use.
- Tool output floods the context with raw data (UUIDs, full dumps, logs).
- You're wrapping an existing REST API 1:1 and the agent struggles.
- You want to iterate on tools with data, not vibes.

## 1. Context is a scarce resource
Agents read token-by-token with a limited window — unlike software that cheaply iterates memory. Push filtering, search, and pagination **into the tool**, don't make the agent process raw data.
- Prefer `search_contacts` over `list_contacts`.
- Prefer `search_logs` (returns relevant lines + surrounding context) over `read_logs`.

## 2. Choose the right tools — consolidate, don't proliferate
*"More tools don't always lead to better outcomes."* Don't just wrap every endpoint. Build a **few thoughtful tools targeting high-impact workflows** that mirror how a human subdivides the task.

| Instead of many low-level tools | Build one workflow tool |
|---|---|
| `list_users`, `list_events`, `create_event` | `schedule_event` (finds availability **and** schedules) |
| `read_logs` | `search_logs` (relevant lines with context) |
| `get_customer_by_id`, `list_transactions`, `list_notes` | `get_customer_context` (compiles recent info) |

Start with a handful matched to your eval tasks, then scale.

## 3. Namespace your tools
Help the agent pick the right one:
- **Prefix:** `asana_search`, `jira_search`
- **Resource-based:** `asana_projects_search`, `asana_users_search`

Prefix vs. suffix has **non-trivial, model-dependent** effects — test your naming against your evals. Good namespacing also reduces how many tools load into context.

## 4. Return meaningful context (signal over flexibility)
Return high-signal, contextually relevant fields. **Avoid low-level identifiers** the agent can't reason about.
- Use `name`, `image_url`, `file_type` — not `uuid`, `256px_image_url`, `mime_type`.
- Agents handle natural-language names far better than cryptic UUIDs. Resolve arbitrary IDs to meaningful language (or 0-indexed IDs) to sharply improve retrieval precision.

### Response-format enum (let the agent control verbosity)
```
enum ResponseFormat { DETAILED = "detailed", CONCISE = "concise" }
```
Example: a Slack thread tool returns **206 tokens** detailed (`thread_ts`, `channel_id`, `user_id` …) vs **72 tokens** concise (thread content only) — roughly ⅓ the tokens. Also test the *structure* (XML / JSON / Markdown) against your evals — it measurably affects performance; there's no universal winner.

## 5. Optimize token efficiency
- Sensible defaults for **pagination, range selection, filtering, truncation**.
- Claude Code caps tool responses at **25,000 tokens** by default — a useful reference ceiling.
- **Steer via truncation messages:** don't just cut off. Append guidance like *"Consider using filters or pagination for more targeted results"* to push the agent toward efficient strategies.

## 6. Actionable error messages
Errors are a steering surface. Replace opaque codes/tracebacks with specific next steps.
- ❌ `404 Not Found`
- ✅ `No user found with name 'jane'. Try searching by email (e.g., jane@company.com) or use list_users filter_by_department='engineering'.`

## 7. Prompt-engineer tool descriptions
Descriptions collectively steer tool-calling — write them like onboarding a new teammate; make implicit context explicit: query formats, niche terminology, resource relationships, unambiguous inputs/outputs.
- Name params clearly: `user_id`, not `user`.
- *Even small refinements yield dramatic improvements* — Claude Sonnet 3.5 hit SWE-bench SOTA after precise description tweaks; Anthropic's web-search tool stopped uselessly appending "2025" to queries after a description fix.

## 8. Evaluation-driven development (the loop that ties it together)

**Prototype:** stand up quick tools → give Claude the library/API docs (look for `llms.txt` on docs sites) → wrap in a local MCP server → `claude mcp add <name> <command> [args...]` → test locally, gather feedback.

**Generate eval tasks:** dozens of prompt/response pairs on **realistic data**, complex enough to need many tool calls. Strong vs weak:
- ✅ *"Schedule a meeting with Jane next week to discuss the Acme Corp project; attach the planning notes; reserve a conference room."*
- ❌ *"Schedule a meeting with jane@acme.corp next week."*
- ✅ *"Customer ID 9182 was charged three times for one purchase — find all log entries and determine if other customers were affected."*

**Verifiers:** pair each task with a verifiable outcome (exact-match → Claude-as-judge). Don't over-strict on formatting/punctuation; optionally note expected tool calls but don't overspecify — multiple valid paths exist.

**Run programmatically:** simple agentic `while`-loop with direct API calls:
```
for each task:
  while not finished:
    response = claude_api_call(task, tools)
    if response.calls_tool:
      result = execute_tool(); feed_result_back()
```
Have the agent output reasoning **before** the tool call (or enable interleaved thinking) so you can see *why* it called or skipped a tool.

**Collect metrics beyond accuracy:** per-tool runtime, total runtime, tool-call count, token consumption, tool errors. Redundant calls → consolidation opportunity; frequent invalid-parameter errors → clearer descriptions needed.

**Analyze strategically:** read raw transcripts, not just the agent's stated feedback — *"what agents omit can be more important than what they include."* Watch where they get stumped; agents don't always know the correct answer.

## 9. Collaborate with agents to improve tools
Concatenate eval transcripts and paste into Claude Code — agents are strong at analyzing transcripts and refactoring **multiple tools at once** while keeping them consistent. Use a **held-out test set** (separate from the eval set you iterate on) to avoid overfitting; this reliably extracts gains beyond hand-written or first-pass Claude-generated tools.

## Best-practices checklist
1. **Selection:** few thoughtful workflow tools > many overlapping endpoint wrappers.
2. **Namespacing:** consistent prefix/resource scheme, tested against evals.
3. **Content:** natural-language names, high-signal fields, no raw UUIDs.
4. **Format:** concise/detailed enum; test XML/JSON/Markdown.
5. **Token efficiency:** pagination + filtering + truncation *with steering messages*.
6. **Errors:** specific, actionable guidance.
7. **Descriptions:** explicit context, unambiguous param names.
8. **Evals:** measure, iterate, use held-out sets.

---

*Distilled from Anthropic Engineering, "Writing tools for agents": https://www.anthropic.com/engineering/writing-tools-for-agents*

