Skip to content
Back to skills

Add Tool

ASecurity

Create or modify an agent tool — use when asked to add a new capability to an agent, build a search/retrieval/analysis/API integration tool, or wire a tool into an existing agent.

  • 2 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added October 26, 2026
ai-agentstypescriptgosqlapidatabase

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned October 26, 2026

npx -y skills add JoshuaShepherd/my-skills --skill add-tool --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Tool?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Tool
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/joshuashepherd-add-tool/badge)](https://www.skillsdirectory.com/skills/joshuashepherd-add-tool)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add-tool
description: Create or modify an agent tool — use when asked to add a new capability to an agent, build a search/retrieval/analysis/API integration tool, or wire a tool into an existing agent.
---

Create or modify an agent tool: $ARGUMENTS

## Before Starting

1. Search OpenAI docs for latest tool patterns:
   - Use `mcp__openai-docs__search_openai_docs` with query "Agents SDK tool definition" for current `tool()` helper signature
   - Use `mcp__openai-docs__search_openai_docs` with query "Agents SDK function tools parameters" for parameter schema patterns
2. Read existing tool implementations:
   - `{{PROJECT_ROOT}}/{{AGENTS_DIR}}/ai-lab/tools/base.ts` — search_books, file_search tools with caching + metrics
   - `{{PROJECT_ROOT}}/{{AGENTS_DIR}}/seo-expert/tools.ts` — 9-tool suite (analyze, research, score, optimize, generate)
   - `{{PROJECT_ROOT}}/{{AGENTS_DIR}}/ai-lab/tools/utils.ts` — `executeToolWithMetrics()`, timeout constants
3. Read the shared tool infrastructure:
   - `{{PROJECT_ROOT}}/src/services/toolCacheService.ts` — param-based LRU caching with TTL

## Tool Template

```typescript
import { tool } from '@openai/agents';
import { z } from 'zod';
import type { RunContext } from '@openai/agents';

export const myTool = tool({
  name: 'my_tool',
  description: 'Clear, specific description of what this tool does and when the agent should use it.',
  parameters: z.object({
    query: z.string().describe('What to search for'),
    maxResults: z.number().optional().default(5).describe('Maximum results to return'),
  }),
  strict: true,
  execute: async (params, context?: RunContext<MyContext>) => {
    // 1. Check cache (if applicable)
    const cacheKey = `my_tool:${params.query}`;
    const cached = await toolCacheService.get(cacheKey);
    if (cached) return cached;

    // 2. Execute with metrics and timeout
    const { result } = await executeToolWithMetrics('my_tool', async () => {
      // Tool implementation here
      return { data: 'result' };
    }, TOOL_TIMEOUTS.MEDIUM);

    // 3. Cache result
    toolCacheService.set(cacheKey, result).catch(() => {});

    return result;
  },
});
```

## Patterns by Tool Type

### Search / Retrieval Tools
- Return structured results with title, snippet, url/slug, relevance score
- Always include a `maxResults` parameter with sensible default
- Gracefully degrade when external service is unavailable (return empty array, not error)
- Add citation metadata when results reference source material

### Analysis / Computation Tools
- Accept content as string input
- Return structured analysis object (scores, categories, suggestions)
- Include confidence scores where applicable
- Keep descriptions prescriptive so the agent knows when to invoke

### API Integration Tools
- Validate API keys exist before calling
- Set appropriate timeouts (TOOL_TIMEOUTS: SHORT=5s, MEDIUM=15s, LONG=30s)
- Return user-friendly error messages, not raw API errors
- Never expose API keys in tool results

### Database Query Tools
- Use the service layer (never raw SQL in tools)
- Scope by `organizationId` from context for multi-tenant safety
- Return only fields the agent needs, not entire rows

## Registration

After creating the tool, register it with the target agent:

**Static registration** (simple agents):
```typescript
// In the agent's index.ts
import { myTool } from './tools';
export const myAgent = new Agent({
  tools: [myTool, existingTool1],
});
```

**Dynamic registration** (function-based agents):
```typescript
// In the agent's tools/index.ts
export function getToolsForConfiguration(context: RunContext<MyContext>): Tool[] {
  const tools = [...getBaseTools()];
  if (context.context.someCondition) {
    tools.push(myTool);
  }
  return tools;
}
```

## Rules

- Tool names must be snake_case
- Descriptions should tell the agent WHEN to use the tool, not just what it does
- Parameters must use Zod schemas with `.describe()` on every field
- Always handle errors gracefully — return error objects, never throw
- Cache results when the tool calls external services
- Wrap execution in `executeToolWithMetrics()` for observability
- Tool results are sent to the LLM — keep payloads concise (truncate large results)
- Check OpenAI docs MCP for any SDK changes to the `tool()` helper before generating code

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.