Skip to main content
Toolsets are dynamic, per-turn tool groups. Unlike the static tools array - which sends every tool to the model on every turn - toolsets are resolved at the start of each turn and can depend on context: the user’s role, feature flags, which phase the agent is in, and so on. An agent can mix static tools and any number of toolsets. All are merged into a single flat tool list before each model call.

Toolset composition

FunctionToolset - basic toolset

FunctionToolset is the simplest toolset: a named group of static tools. Use it to logically bundle related tools together.
import { FunctionToolset } from "@vibesjs/sdk";

const myToolset = new FunctionToolset([searchTool, fetchTool]);
myToolset.addTool(anotherTool);

const agent = new Agent({
  model,
  toolsets: [myToolset],
});

FilteredToolset - conditional tools

FilteredToolset wraps another toolset with a boolean predicate. When the predicate returns false, the entire inner toolset is hidden from the model for that turn.
import { FilteredToolset } from "@vibesjs/sdk";

const adminToolset = new FilteredToolset(
  innerToolset,
  (ctx) => ctx.deps.isAdmin,
);
The predicate is all-or-nothing: the inner toolset is either shown in full or hidden entirely. For per-tool filtering within a toolset, see PreparedToolset.

PreparedToolset - per-turn filtering

PreparedToolset lets you return a subset of tools based on context. The prepare function receives the full RunContext and the complete tool list, and returns whichever tools to expose.
import { PreparedToolset } from "@vibesjs/sdk";

const safe = new PreparedToolset(
  adminTools,
  (ctx, tools) => ctx.deps.confirmed
    ? tools
    : tools.filter((t) => t.name !== "delete"),
);
PreparedToolset vs FilteredToolset:
FilteredToolsetPreparedToolset
GranularityAll-or-nothingPer-tool
Predicate receives(ctx)(ctx, tools)
Use whenHiding entire toolset by roleFiltering individual tools by state

CombinedToolset - merging toolsets

CombinedToolset merges multiple toolsets into one. Tools from later toolsets override earlier ones on name conflict (last name wins).
import { CombinedToolset } from "@vibesjs/sdk";

const combined = new CombinedToolset([toolsetA, toolsetB]);

PrefixedToolset - namespacing

PrefixedToolset adds a string prefix to every tool name. Use it to avoid collisions when combining toolsets from different domains.
import { PrefixedToolset } from "@vibesjs/sdk";

const namespaced = new PrefixedToolset(innerToolset, "admin_");
// "search" → "admin_search", "delete" → "admin_delete"

RenamedToolset - custom names

RenamedToolset renames specific tools using a mapping object.
import { RenamedToolset } from "@vibesjs/sdk";

const renamed = new RenamedToolset(innerToolset, {
  old_name: "new_name",
});

WrapperToolset - middleware

WrapperToolset wraps another toolset and intercepts execute calls. Use it for cross-cutting concerns like logging, tracing, input transformation, or output transformation - without modifying the underlying tools.
import { WrapperToolset } from "@vibesjs/sdk";

const logged = new WrapperToolset(innerToolset, {
  wrapExecute: async (ctx, tool, args, next) => {
    console.log(`Calling ${tool.name}`, args);
    const result = await next(ctx, args);
    console.log(`Result from ${tool.name}:`, result);
    return result;
  },
});

ApprovalRequiredToolset - mark all for approval

ApprovalRequiredToolset wraps a toolset and marks every tool inside it as requiresApproval: true. Use it when you want to require human approval for an entire group of tools without modifying them individually.
import { ApprovalRequiredToolset } from "@vibesjs/sdk";

const gated = new ApprovalRequiredToolset(dangerousToolset);
When any tool from this toolset is requested by the model, Vibes throws ApprovalRequiredError with the deferred tool requests. See Human-in-the-Loop for the full approval flow.

ExternalToolset - tools without Zod schemas

ExternalToolset is for tools that have pre-existing JSON schemas - for example, tools loaded from an MCP server. Parameters are passed as raw JSON instead of going through Zod parsing.
import { ExternalToolset } from "@vibesjs/sdk";

const external = new ExternalToolset(mcpTools);
Use ExternalToolset when integrating with external tool registries that provide their own JSON Schema definitions.