Custom Tools
Tools are structured functions that an LLM can call. The SDK uses Zod schemas to validate inputs and serialize parameters for model providers.
Define tools with schemas
Section titled “Define tools with schemas”Use defineTool to describe inputs and return types. The SDK will validate parameters before
execution and expose a JSON schema to the model.
import { defineTool } from '@dreadnode/agents';import { z } from 'zod';
export const enrichIndicator = defineTool({ name: 'enrich_indicator', description: 'Look up an indicator in a local cache.', parameters: z.object({ indicator: z.string().describe('IP, domain, or hash to enrich'), }), execute: async ({ indicator }) => ({ indicator, verdict: 'unknown' }),});Group tools with createToolkit
Section titled “Group tools with createToolkit”createToolkit turns a list of tools into a keyed map with helpers for execution and schema
generation.
import { createToolkit } from '@dreadnode/agents';import { enrichIndicator } from './tools/enrichIndicator';
const toolkit = createToolkit([enrichIndicator]);const schemas = toolkit.toSchema();console.log(schemas);Wrap capability tools
Section titled “Wrap capability tools”Capabilities ship tool definitions in capability.yaml. Use wrapTool and wrapCapability to
convert capability tool defs into AI SDK tool() instances that can be merged into your tool map.
import { loadCapability, wrapCapability, wrapTool } from '@dreadnode/agents';
async function main(): Promise<void> { const loaded = await loadCapability('./capabilities/threat-hunting'); const wrapped = wrapCapability(loaded);
const firstTool = loaded.manifest.tools?.[0]; if (firstTool) { const single = wrapTool(firstTool, loaded); console.log('Wrapped tool:', (single as Record<string, unknown>)._capName); }
console.log(`Wrapped ${wrapped.tools.length} tools from ${wrapped.name}.`);}
main().catch((error) => { console.error(error); process.exit(1);});Tool design best practices
Section titled “Tool design best practices”- Keep inputs small and explicit (prefer enums or constrained strings).
- Return structured objects, not raw strings.
- Fail fast with clear error messages when preconditions are not met.