Add a Tool

You want to add a new tool to a route and call it with full type safety. Here's how.

The code

import { z } from "zod"
 
export default z.object({
  query: z.string(),
  count: z.number().default(0),
})

Notes

  • No registration. Drop the file into tools/. Run b4 typegen to regenerate types, or let the dev server do it on reload. Use b4 check to validate the app without writing files.
  • Two discovery locations. Tools are discovered from both <route>/tools/ (route-local, only available to that route) and src/tools/ (shared across all routes). Place a tool in src/tools/ when multiple routes need it; place it in <route>/tools/ to keep it scoped.
  • Serializable types wherever they are declared. B4.run's compiler pass extracts input and output types written inline, declared as local aliases or interfaces, or imported from another module. Keep the root input object-shaped so B4.run can emit the model-facing tool schema.
  • Plain JSON in, plain JSON out. Tool inputs and outputs cross the runtime boundary. No Date, no Map, no class instances.
  • agent routes don't call ctx.tools. The LLM picks tools by name once b4 build binds them. The example above uses a workflow route to show the typed call site.