Scaffold a new agent tool with a typed Zod schema, a safe
Scanned 9/19/2026
Install to Claude Code
npx -y skills add thecoderpanda/fde-starter-kit --skill add-tool --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Add Tool?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/thecoderpanda-add-tool)More formats (shields.io, HTML) on the badges page.
---
name: add-tool
description: Scaffold a new agent tool with a typed Zod schema, a safe
execute body, an entry in the tool registry, and a starter eval case.
Use when the user says "add a tool", "new tool", "give the agent a
<verb> tool", or "let the agent call <api>".
---
# add-tool
Purpose: keep every new tool consistent with the existing four — same
shape, same safety rails, same test coverage — so tool sprawl doesn't
turn the agent into an unpredictable mess.
## When to fire
- User says: "add a tool for X", "create a tool that calls Y", "the
agent needs to be able to Z", "scaffold a tool".
- User pastes an API spec and asks the agent to wrap it.
## Inputs you need
Ask for these in one message, not one at a time:
1. **Tool name** — snake_case, verb-first (e.g. `send_email`, not
`email_tool`).
2. **One-line description** — what the model sees when deciding whether
to call it.
3. **Parameters** — name, type, whether required, one-line description
per param.
4. **Where the data comes from** — HTTP call? Local file? Shell? DB?
5. **Failure modes** — what returns an `{ error }` object vs what
throws.
## Steps
1. **Create `./agent/tools/<name>.ts`** using the template in
`./skills/add-tool/resources/template.ts`. Fill in:
- Zod schema mirroring the parameters spec.
- `execute` body implementing the call.
- Explicit early return with `{ error: "..." }` for every failure
mode identified in input 5. Never throw for expected failures — the
agent handles error objects gracefully but a throw ends the turn.
2. **Register it** in `./agent/tools/index.ts`:
```ts
import { <camelName>Tool } from "./<name>";
export const tools = {
...,
<name>: <camelName>Tool,
} as const;
```
Keep the object keys snake_case (that's what the model sees) and the
identifiers camelCase (that's what TypeScript prefers).
3. **Add a smoke eval case** to `./evals/cases/tools.jsonl`. Every tool
must have at least one case that asserts `tool_called` for its name,
plus one negative case that ensures it does NOT get called for
irrelevant queries. Copy the pattern from existing entries.
4. **Update `.env.example`** if the tool needs a new env var. Add a
comment explaining what happens when the var is missing (the tool
should degrade gracefully — see `web_search` as reference).
5. **Type check + eval.**
```bash
npm run typecheck
npm run eval
```
Both must be green before you consider the tool done.
## Definition of done
- New file at `./agent/tools/<name>.ts` matching the template shape.
- Entry added to `./agent/tools/index.ts`.
- At least two new cases in `./evals/cases/tools.jsonl` (positive +
negative).
- `.env.example` updated if applicable.
- `npm run typecheck` passes.
- `npm run eval` passes (or the user acknowledges an expected regression
and approves).
## Anti-patterns to avoid
- **No side-channel state.** Tools must be pure functions of their
inputs plus process env. No module-level mutable caches.
- **No `any`.** The Zod schema is the contract; `execute` must be
typed against `z.infer<typeof schema>`.
- **No silent truncation.** If a response is truncated for size, return
a field like `truncated: true` so the model knows.
- **No unbounded loops.** If the tool paginates, cap page count and
return `{ nextPageToken, truncated: true }` when hit.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!