Getting Started
File system
Facilities
Architecture
Examples
Reference
Custom tools
Custom tools
Custom tools extend the agent with workspace-specific actions, running through the same scoped API as a hook.
Declare a tool
Create +<lower_snake_case>.ts in src/capabilities/tools/ . The filename is the tool name, and the file exports one defineAgentTool:
// src/capabilities/tools/+product_lookup.ts
import { defineAgentTool } from '@norbital-ai/bolt/authoring';
import { Effect, Schema } from 'effect';
export default defineAgentTool({
description: 'Returns one product by id, with its current stock level.',
input: Schema.Struct({ productId: Schema.String }),
run: (api, { productId }) =>
Effect.gen(function* () {
const product = yield* api.db.query.products.findFirst({
where: { id: { eq: productId } }
});
return product ?? null;
})
});
Scoped, not privileged
A custom tool is not a backdoor — it runs with the same scoped API as a hook : policies, hooks, and audit apply to everything it does.
Reserved names
Built-in tool names are owned by the platform — an authored tool with one of those names never runs, because platform calls are matched on the name first. See Built-in tools .