Skip to content

Class: FluentToolBuilder<TContext, TInput, TCtx>

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:79

Fluent builder that accumulates types at each step.

Type Parameters

Type ParameterDefault typeDescription
TContext-Base application context (from initFusion<TContext>())
TInputvoidAccumulated input type (built by with*() methods)
TCtxTContextAccumulated context type (enriched by .use())

Constructors

Constructor

ts
new FluentToolBuilder<TContext, TInput, TCtx>(name, defaults?): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:110

Parameters

ParameterTypeDescription
namestringTool name in domain.action format (e.g. 'users.list')
defaultsSemanticDefaultsSemantic defaults from the verb (query, mutation, action)

Returns

FluentToolBuilder<TContext, TInput, TCtx>

Methods

annotations()

ts
annotations(a): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:473

Set MCP tool annotations.

Parameters

ParameterTypeDescription
aRecord<string, unknown>Annotation key-value pairs

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


bindState()

ts
bindState(states, transition?): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:596

Bind this tool to specific FSM states.

When a StateMachineGate is configured on the server, this tool will only appear in tools/list when the FSM is in one of the specified states. The LLM physically cannot call tools that don't exist in its reality.

Parameters

ParameterTypeDescription
statesstring | string[]FSM state(s) where this tool is visible
transition?stringEvent to send to the FSM on successful execution

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining

Example

typescript
// Visible only in 'has_items' state, sends CHECKOUT on success
const checkout = f.mutation('cart.checkout')
    .bindState('has_items', 'CHECKOUT')
    .handle(async (input, ctx) => { ... });

// Visible in multiple states
const addItem = f.mutation('cart.add_item')
    .bindState(['empty', 'has_items'], 'ADD_ITEM')
    .handle(async (input, ctx) => { ... });

cached()

ts
cached(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:496

Mark this tool's data as immutable (safe to cache forever).

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


concurrency()

ts
concurrency(config): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:519

Set concurrency limits for this tool (Semaphore + Queue pattern).

Parameters

ParameterTypeDescription
configConcurrencyConfigConcurrency configuration

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


describe()

ts
describe(text): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:123

Set the tool description shown to the LLM.

Parameters

ParameterTypeDescription
textstringHuman-readable description

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


destructive()

ts
destructive(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:446

Override: mark this tool as destructive (irreversible)

Returns

FluentToolBuilder<TContext, TInput, TCtx>


egress()

ts
egress(bytes): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:530

Set maximum payload size for tool responses (Egress Guard).

Parameters

ParameterTypeDescription
bytesnumberMaximum payload size in bytes

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


handle()

ts
handle(handler): GroupedToolBuilder<TContext>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:627

Set the handler and build the tool — the terminal step.

The handler receives (input, ctx) with fully typed TInput and TCtx. Implicit success() wrapping: if the handler returns raw data (not a ToolResponse), the framework wraps it with success().

Parameters

ParameterTypeDescription
handler(input, ctx) => Promise<unknown>Async function receiving typed (input, ctx)

Returns

GroupedToolBuilder<TContext>

A GroupedToolBuilder ready for registration

Example

typescript
const getProject = f.query('projects.get')
    .describe('Get a project by ID')
    .withString('project_id', 'The exact project ID')
    .handle(async (input, ctx) => {
        return await ctx.db.projects.findUnique({ where: { id: input.project_id } });
    });

idempotent()

ts
idempotent(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:452

Override: mark this tool as idempotent (safe to retry)

Returns

FluentToolBuilder<TContext, TInput, TCtx>


instructions()

ts
instructions(text): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:146

Set AI-First instructions — injected as system-level guidance in the tool description.

This is Prompt Engineering embedded in the framework. The instructions tell the LLM WHEN and HOW to use this tool, reducing hallucination.

Parameters

ParameterTypeDescription
textstringSystem prompt for the tool

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining

Example

typescript
f.query('docs.search')
    .describe('Search internal documentation')
    .instructions('Use ONLY when the user asks about internal policies.')
    .withString('query', 'Search term')
    .handle(async (input) => { ... });

invalidates()

ts
invalidates(...patterns): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:486

Declare glob patterns invalidated when this tool succeeds.

Parameters

ParameterTypeDescription
...patternsstring[]Glob patterns (e.g. 'sprints.*', 'tasks.*')

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


readOnly()

ts
readOnly(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:440

Override: mark this tool as read-only (no side effects)

Returns

FluentToolBuilder<TContext, TInput, TCtx>


returns()

ts
returns(presenter): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:418

Set the MVA Presenter for automatic response formatting.

When a Presenter is attached, the handler can return raw data and the framework pipes it through schema validation, system rules, and UI block generation.

Parameters

ParameterTypeDescription
presenterPresenter<unknown>A Presenter instance

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


sandboxed()

ts
sandboxed(config?): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:564

Enable zero-trust sandboxed execution for this tool.

When enabled:

  1. A SandboxEngine is lazily created on the GroupedToolBuilder
  2. A system instruction is auto-injected into the tool description (HATEOAS auto-prompting) so the LLM knows to send JS functions
  3. The handler can use SandboxEngine.execute() to run LLM code in a sealed V8 isolate (no process, require, fs, network)

Parameters

ParameterTypeDescription
config?SandboxConfigOptional sandbox configuration (timeout, memory, output size)

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining

Example

typescript
f.query('data.compute')
    .describe('Run safe computation on server data')
    .sandboxed({ timeout: 3000, memoryLimit: 64 })
    .withString('expression', 'JS arrow function: (data) => result')
    .handle(async (input, ctx) => {
        const data = await ctx.db.records.findMany();
        const engine = new SandboxEngine({ timeout: 3000 });
        const result = await engine.execute(input.expression, data);
        return result.ok ? result.value : { error: result.error };
    });

stale()

ts
stale(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:506

Mark this tool's data as volatile (never cache).

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


tags()

ts
tags(...tags): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:432

Add capability tags for selective tool exposure.

Tags are accumulated — calling .tags() multiple times (or inheriting from a router) appends rather than replaces.

Parameters

ParameterTypeDescription
...tagsstring[]Tag strings for filtering

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


toonDescription()

ts
toonDescription(): FluentToolBuilder<TContext, TInput, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:462

Enable TOON-formatted descriptions for token optimization.

Returns

FluentToolBuilder<TContext, TInput, TCtx>

this for chaining


use()

Call Signature

ts
use<TDerived>(mw): FluentToolBuilder<TContext, TInput, TCtx & TDerived>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:375

Add context-derivation middleware (tRPC-style).

Accepts either:

  • A MiddlewareDefinition from f.middleware() (recommended)
  • An inline function ({ ctx, next }) => Promise<ToolResponse>
Type Parameters
Type Parameter
TDerived extends Record<string, unknown>
Parameters
ParameterTypeDescription
mwMiddlewareDefinition<TCtx, TDerived>Middleware definition or inline function
Returns

FluentToolBuilder<TContext, TInput, TCtx & TDerived>

A new type of FluentToolBuilder with TCtx enriched

Example
typescript
// Option 1: f.middleware() (recommended)
const withAuth = f.middleware(async (ctx) => {
    if (ctx.role === 'GUEST') throw error('Unauthorized');
    return { verified: true };
});
f.mutation('users.delete')
    .use(withAuth)
    .handle(async (input, ctx) => { ... });

// Option 2: inline
f.mutation('users.delete')
    .use(async ({ ctx, next }) => {
        const admin = await requireAdmin(ctx.headers);
        return next({ ...ctx, adminUser: admin });
    })
    .handle(async (input, ctx) => { ... });

Call Signature

ts
use<TDerived>(mw): FluentToolBuilder<TContext, TInput, TCtx & TDerived>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:378

Add context-derivation middleware (tRPC-style).

Accepts either:

  • A MiddlewareDefinition from f.middleware() (recommended)
  • An inline function ({ ctx, next }) => Promise<ToolResponse>
Type Parameters
Type Parameter
TDerived extends Record<string, unknown>
Parameters
ParameterTypeDescription
mw(args) => Promise<ToolResponse>Middleware definition or inline function
Returns

FluentToolBuilder<TContext, TInput, TCtx & TDerived>

A new type of FluentToolBuilder with TCtx enriched

Example
typescript
// Option 1: f.middleware() (recommended)
const withAuth = f.middleware(async (ctx) => {
    if (ctx.role === 'GUEST') throw error('Unauthorized');
    return { verified: true };
});
f.mutation('users.delete')
    .use(withAuth)
    .handle(async (input, ctx) => { ... });

// Option 2: inline
f.mutation('users.delete')
    .use(async ({ ctx, next }) => {
        const admin = await requireAdmin(ctx.headers);
        return next({ ...ctx, adminUser: admin });
    })
    .handle(async (input, ctx) => { ... });

withArray()

ts
withArray<K, I>(
   name, 
   itemType, 
description?): FluentToolBuilder<TContext, TInput & Record<K, I extends "string" ? string : I extends "number" ? number : boolean[]>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:315

Add a required array parameter.

Type Parameters

Type Parameter
K extends string
I extends "string" | "number" | "boolean"

Parameters

ParameterTypeDescription
nameKParameter name
itemTypeIType of array items ('string', 'number', 'boolean')
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Record<K, I extends "string" ? string : I extends "number" ? number : boolean[]>, TCtx>

Builder with narrowed TInput type

Example

typescript
f.mutation('tasks.tag')
    .withString('task_id', 'The task to tag')
    .withArray('tags', 'string', 'Tags to apply')
    .handle(async (input) => { ... });
// input.tags: string[] ✅

withBoolean()

ts
withBoolean<K>(name, description?): FluentToolBuilder<TContext, TInput & Record<K, boolean>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:230

Add a required boolean parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Record<K, boolean>, TCtx>

Builder with narrowed TInput type


withEnum()

ts
withEnum<K, V>(
   name, 
   values, 
description?): FluentToolBuilder<TContext, TInput & Record<K, V>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:270

Add a required enum parameter.

Type Parameters

Type Parameter
K extends string
V extends string

Parameters

ParameterTypeDescription
nameKParameter name
valuesreadonly [V, V]Allowed enum values
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Record<K, V>, TCtx>

Builder with narrowed TInput type

Example

typescript
f.query('invoices.list')
    .withEnum('status', ['draft', 'sent', 'paid'], 'Filter by status')
    .handle(async (input) => { ... });
// input.status: 'draft' | 'sent' | 'paid' ✅

withNumber()

ts
withNumber<K>(name, description?): FluentToolBuilder<TContext, TInput & Record<K, number>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:199

Add a required number parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Record<K, number>, TCtx>

Builder with narrowed TInput type


withOptionalArray()

ts
withOptionalArray<K, I>(
   name, 
   itemType, 
description?): FluentToolBuilder<TContext, TInput & Partial<Record<K, I extends "string" ? string : I extends "number" ? number : boolean[]>>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:333

Add an optional array parameter.

Type Parameters

Type Parameter
K extends string
I extends "string" | "number" | "boolean"

Parameters

ParameterTypeDescription
nameKParameter name
itemTypeIType of array items ('string', 'number', 'boolean')
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Partial<Record<K, I extends "string" ? string : I extends "number" ? number : boolean[]>>, TCtx>

Builder with narrowed TInput type


withOptionalBoolean()

ts
withOptionalBoolean<K>(name, description?): FluentToolBuilder<TContext, TInput & Partial<Record<K, boolean>>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:245

Add an optional boolean parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Partial<Record<K, boolean>>, TCtx>

Builder with narrowed TInput type


withOptionalEnum()

ts
withOptionalEnum<K, V>(
   name, 
   values, 
description?): FluentToolBuilder<TContext, TInput & Partial<Record<K, V>>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:288

Add an optional enum parameter.

Type Parameters

Type Parameter
K extends string
V extends string

Parameters

ParameterTypeDescription
nameKParameter name
valuesreadonly [V, V]Allowed enum values
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Partial<Record<K, V>>, TCtx>

Builder with narrowed TInput type


withOptionalNumber()

ts
withOptionalNumber<K>(name, description?): FluentToolBuilder<TContext, TInput & Partial<Record<K, number>>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:214

Add an optional number parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Partial<Record<K, number>>, TCtx>

Builder with narrowed TInput type


withOptionalString()

ts
withOptionalString<K>(name, description?): FluentToolBuilder<TContext, TInput & Partial<Record<K, string>>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:183

Add an optional string parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Partial<Record<K, string>>, TCtx>

Builder with narrowed TInput type


withString()

ts
withString<K>(name, description?): FluentToolBuilder<TContext, TInput & Record<K, string>, TCtx>;

Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:168

Add a required string parameter.

Type Parameters

Type Parameter
K extends string

Parameters

ParameterTypeDescription
nameKParameter name
description?stringHuman-readable description for the LLM

Returns

FluentToolBuilder<TContext, TInput & Record<K, string>, TCtx>

Builder with narrowed TInput type

Example

typescript
f.query('projects.get')
    .withString('project_id', 'The project ID to retrieve')
    .handle(async (input) => { ... });
// input.project_id: string ✅