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 Parameter | Default type | Description |
|---|---|---|
TContext | - | Base application context (from initFusion<TContext>()) |
TInput | void | Accumulated input type (built by with*() methods) |
TCtx | TContext | Accumulated context type (enriched by .use()) |
Constructors
Constructor
new FluentToolBuilder<TContext, TInput, TCtx>(name, defaults?): FluentToolBuilder<TContext, TInput, TCtx>;Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:110
Parameters
| Parameter | Type | Description |
|---|---|---|
name | string | Tool name in domain.action format (e.g. 'users.list') |
defaults | SemanticDefaults | Semantic defaults from the verb (query, mutation, action) |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
Methods
annotations()
annotations(a): FluentToolBuilder<TContext, TInput, TCtx>;Defined in: packages/core/src/core/builder/FluentToolBuilder.ts:473
Set MCP tool annotations.
Parameters
| Parameter | Type | Description |
|---|---|---|
a | Record<string, unknown> | Annotation key-value pairs |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
bindState()
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
| Parameter | Type | Description |
|---|---|---|
states | string | string[] | FSM state(s) where this tool is visible |
transition? | string | Event to send to the FSM on successful execution |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
Example
// 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()
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()
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
| Parameter | Type | Description |
|---|---|---|
config | ConcurrencyConfig | Concurrency configuration |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
describe()
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
| Parameter | Type | Description |
|---|---|---|
text | string | Human-readable description |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
destructive()
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()
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
| Parameter | Type | Description |
|---|---|---|
bytes | number | Maximum payload size in bytes |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
handle()
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
| Parameter | Type | Description |
|---|---|---|
handler | (input, ctx) => Promise<unknown> | Async function receiving typed (input, ctx) |
Returns
GroupedToolBuilder<TContext>
A GroupedToolBuilder ready for registration
Example
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()
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()
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
| Parameter | Type | Description |
|---|---|---|
text | string | System prompt for the tool |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
Example
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()
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
| Parameter | Type | Description |
|---|---|---|
...patterns | string[] | Glob patterns (e.g. 'sprints.*', 'tasks.*') |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
readOnly()
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()
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
| Parameter | Type | Description |
|---|---|---|
presenter | Presenter<unknown> | A Presenter instance |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
sandboxed()
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:
- A
SandboxEngineis lazily created on theGroupedToolBuilder - A system instruction is auto-injected into the tool description (HATEOAS auto-prompting) so the LLM knows to send JS functions
- The handler can use
SandboxEngine.execute()to run LLM code in a sealed V8 isolate (no process, require, fs, network)
Parameters
| Parameter | Type | Description |
|---|---|---|
config? | SandboxConfig | Optional sandbox configuration (timeout, memory, output size) |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
Example
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()
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()
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
| Parameter | Type | Description |
|---|---|---|
...tags | string[] | Tag strings for filtering |
Returns
FluentToolBuilder<TContext, TInput, TCtx>
this for chaining
toonDescription()
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
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
MiddlewareDefinitionfromf.middleware()(recommended) - An inline function
({ ctx, next }) => Promise<ToolResponse>
Type Parameters
| Type Parameter |
|---|
TDerived extends Record<string, unknown> |
Parameters
| Parameter | Type | Description |
|---|---|---|
mw | MiddlewareDefinition<TCtx, TDerived> | Middleware definition or inline function |
Returns
FluentToolBuilder<TContext, TInput, TCtx & TDerived>
A new type of FluentToolBuilder with TCtx enriched
Example
// 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
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
MiddlewareDefinitionfromf.middleware()(recommended) - An inline function
({ ctx, next }) => Promise<ToolResponse>
Type Parameters
| Type Parameter |
|---|
TDerived extends Record<string, unknown> |
Parameters
| Parameter | Type | Description |
|---|---|---|
mw | (args) => Promise<ToolResponse> | Middleware definition or inline function |
Returns
FluentToolBuilder<TContext, TInput, TCtx & TDerived>
A new type of FluentToolBuilder with TCtx enriched
Example
// 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()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
itemType | I | Type of array items ('string', 'number', 'boolean') |
description? | string | Human-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
f.mutation('tasks.tag')
.withString('task_id', 'The task to tag')
.withArray('tags', 'string', 'Tags to apply')
.handle(async (input) => { ... });
// input.tags: string[] ✅withBoolean()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Record<K, boolean>, TCtx>
Builder with narrowed TInput type
withEnum()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
values | readonly [V, V] | Allowed enum values |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Record<K, V>, TCtx>
Builder with narrowed TInput type
Example
f.query('invoices.list')
.withEnum('status', ['draft', 'sent', 'paid'], 'Filter by status')
.handle(async (input) => { ... });
// input.status: 'draft' | 'sent' | 'paid' ✅withNumber()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Record<K, number>, TCtx>
Builder with narrowed TInput type
withOptionalArray()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
itemType | I | Type of array items ('string', 'number', 'boolean') |
description? | string | Human-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()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Partial<Record<K, boolean>>, TCtx>
Builder with narrowed TInput type
withOptionalEnum()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
values | readonly [V, V] | Allowed enum values |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Partial<Record<K, V>>, TCtx>
Builder with narrowed TInput type
withOptionalNumber()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Partial<Record<K, number>>, TCtx>
Builder with narrowed TInput type
withOptionalString()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Partial<Record<K, string>>, TCtx>
Builder with narrowed TInput type
withString()
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
| Parameter | Type | Description |
|---|---|---|
name | K | Parameter name |
description? | string | Human-readable description for the LLM |
Returns
FluentToolBuilder<TContext, TInput & Record<K, string>, TCtx>
Builder with narrowed TInput type
Example
f.query('projects.get')
.withString('project_id', 'The project ID to retrieve')
.handle(async (input) => { ... });
// input.project_id: string ✅