Tools API
Discover, convert, execute, and dispatch canonical tools from model tool calls.
Discover, convert, execute, and dispatch canonical tools from model tool calls.
ToolsClient
Local tool discovery and authenticated canonical execution.
execute
Starts one canonical execution and returns its immediate execution envelope.
Canonical dotted and restricted wire names are accepted. Mutations receive a generated UUID idempotency key when one is not supplied; pass a stable key to correlate retries across separate calls.
execute(toolName: string, options: ExecuteToolOptions): Promise<ExecutionResult>| Parameter | Type | Required | Description |
|---|---|---|---|
toolName | string | Yes | Canonical dotted name or restricted name emitted to a model. |
options | ExecuteToolOptions | Yes | Canonical input, user binding, execution mode, and retry identity. |
Returns: Promise<ExecutionResult>
Throws
- EyeballError when local validation, transport, authentication, or executor admission fails.
Example
import { Eyeball } from "@eyeball/sdk";
const eyeball = new Eyeball({
apiKey: process.env.EYEBALL_API_KEY!,
baseUrl: process.env.EYEBALL_EXECUTOR_URL!,
});
const execution = await eyeball.tools.execute("gmail.create_draft", {
userId: "user_42",
input: { to: ["guest@example.com"], subject: "Review", body: "Draft" },
idempotencyKey: "draft:reservation:42",
});get
Resolves and converts the open-core catalog locally without calling the executor.
Hosted per-project enablement and catalog policy are eyeball-cloud concerns.
get<Format extends EyeballToolFormat = "canonical">(options?: GetToolsOptions<Format>): Promise<GetToolsResult<Format>>| Parameter | Type | Required | Description |
|---|---|---|---|
options | GetToolsOptions<Format> | No | Toolkit and capability filters plus the requested model format. |
Returns: Promise<GetToolsResult<Format>>
Throws
- EyeballError with
invalid_inputwhen filters are invalid or AI SDK callbacks have no user binding.
Example
import { Eyeball } from "@eyeball/sdk";
const eyeball = new Eyeball({
apiKey: process.env.EYEBALL_API_KEY!,
baseUrl: process.env.EYEBALL_EXECUTOR_URL!,
});
const bundle = await eyeball.tools.get({
toolkits: ["gmail"],
format: "anthropic",
});
console.log(bundle.tools, bundle.nameMap);run
Runs a model-selected tool to completion and returns only its canonical output.
The exact canonical or restricted wire name emitted by a model is accepted. Async work
is polled through executions.wait before this method resolves.
run(toolName: string, input: unknown, options?: RunToolOptions): Promise<JsonValue>| Parameter | Type | Required | Description |
|---|---|---|---|
toolName | string | Yes | Canonical dotted name or restricted name emitted to a model. |
input | unknown | Yes | Canonical JSON object for the selected tool. |
options | RunToolOptions | No | User, connection, execution, idempotency, and polling controls. |
Returns: Promise<JsonValue>
Throws
- EyeballError for local validation, request failures, terminal tool errors, or polling timeout.
Example
import { Eyeball } from "@eyeball/sdk";
const eyeball = new Eyeball({
apiKey: process.env.EYEBALL_API_KEY!,
baseUrl: process.env.EYEBALL_EXECUTOR_URL!,
});
const output = await eyeball.tools.run(
"gmail.search_emails",
{ query: "reservation", pageSize: 5 },
{ userId: "user_42", timeoutMs: 30_000 },
);search
Searches and ranks the local open-core catalog without contacting the executor.
search(options: SearchToolsOptions): Promise<SearchToolsResult>| Parameter | Type | Required | Description |
|---|---|---|---|
options | SearchToolsOptions | Yes | Search text, result limit, and optional local catalog filters. |
Returns: Promise<SearchToolsResult>
Throws
- EyeballError with
invalid_inputwhen the query or a filter is invalid.
executeToolCalls
Dispatches framework tool calls and returns model-ready result blocks. Each call's framework ID becomes its stable, format-prefixed idempotency key so redispatching the same model response reuses the original execution instead of duplicating a mutation.
Per-call failures are serialized into safe model-facing results instead of rejecting the batch.
Overload 1
executeToolCalls(eyeball: Eyeball, calls: readonly AnthropicToolCall[], options: ExecuteToolCallsOptions): Promise<AnthropicToolResultBlock[]>| Parameter | Type | Required | Description |
|---|---|---|---|
eyeball | Eyeball | Yes | Configured SDK client used for canonical execution. |
calls | readonly AnthropicToolCall[] | Yes | Anthropic tool-use blocks or OpenAI function tool calls from one response. |
options | ExecuteToolCallsOptions | Yes | Exact emitted name map plus optional execution and polling controls. |
Returns: Promise<AnthropicToolResultBlock[]>
Overload 2
executeToolCalls(eyeball: Eyeball, calls: readonly OpenAIToolCall[], options: ExecuteToolCallsOptions): Promise<OpenAIToolResultMessage[]>| Parameter | Type | Required | Description |
|---|---|---|---|
eyeball | Eyeball | Yes | Configured SDK client used for canonical execution. |
calls | readonly OpenAIToolCall[] | Yes | Anthropic tool-use blocks or OpenAI function tool calls from one response. |
options | ExecuteToolCallsOptions | Yes | Exact emitted name map plus optional execution and polling controls. |
Returns: Promise<OpenAIToolResultMessage[]>
Types
SearchToolsOptions
Query and optional local catalog filters for tools.search.
export interface SearchToolsOptions {
query: string;
limit?: number;
/** Optional local catalog filters, applied before ranking. */
toolkits?: readonly string[];
capability?: CapabilitySlug;
/** Accepted for parity with the future hosted project-scoped search surface. */
userId?: string;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
capability | "email" | "calendar_scheduling" | "messaging_chat" | "voice_telephony" | "sms" | "crm" | "erp_accounting" | "social_media_data" | "social_media_publishing" | "file_storage_docs" | "spreadsheets_databases" | "project_management_dev_tools" | "payments_billing" | "ecommerce" | "customer_support" | "web_search_scraping" | "hr_recruiting" | "marketing_ads" | "sign_forms" | "ai_media_utilities" | No | No | — |
limit | number | No | No | — |
query | string | Yes | No | — |
toolkits | readonly string[] | No | No | Optional local catalog filters, applied before ranking. |
userId | string | No | No | Accepted for parity with the future hosted project-scoped search surface. |
SearchToolsResult
Canonical definitions ranked by local catalog relevance.
export interface SearchToolsResult {
tools: readonly ToolDefinition[];
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
tools | readonly ToolDefinition[] | Yes | No | — |
GetToolsOptions
Local catalog filters and conversion controls for tools.get.
export interface GetToolsOptions<
Format extends EyeballToolFormat = "canonical",
> {
/**
* Binds framework-owned execute callbacks to an end user. Tool discovery itself is
* resolved entirely from the local `@eyeball/catalog`; hosted project catalog policy
* belongs to eyeball-cloud and is not fetched by this method.
*/
userId?: string;
toolkits?: readonly string[];
capability?: CapabilitySlug;
format?: Format;
/** MCP only: include async-by-nature tools after Tasks support is negotiated. */
includeAsync?: boolean;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
capability | "email" | "calendar_scheduling" | "messaging_chat" | "voice_telephony" | "sms" | "crm" | "erp_accounting" | "social_media_data" | "social_media_publishing" | "file_storage_docs" | "spreadsheets_databases" | "project_management_dev_tools" | "payments_billing" | "ecommerce" | "customer_support" | "web_search_scraping" | "hr_recruiting" | "marketing_ads" | "sign_forms" | "ai_media_utilities" | No | No | — |
format | Format | No | No | — |
includeAsync | boolean | No | No | MCP only: include async-by-nature tools after Tasks support is negotiated. |
toolkits | readonly string[] | No | No | — |
userId | string | No | No | Binds framework-owned execute callbacks to an end user. Tool discovery itself is resolved entirely from the local @eyeball/catalog; hosted project catalog policy belongs to eyeball-cloud and is not fetched by this method. |
GetToolsResult
Converted model tools plus canonical definitions and reversible names.
export interface GetToolsResult<Format extends EyeballToolFormat> {
tools: EyeballToolFormatMap[Format];
nameMap: ToolNameMap;
raw: readonly ToolDefinition[];
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
nameMap | ToolNameMap | Yes | No | — |
raw | readonly ToolDefinition[] | Yes | No | — |
tools | EyeballToolFormatMap[Format] | Yes | No | — |
EyeballToolFormat
Tool-definition formats emitted for supported model frameworks and MCP.
export type EyeballToolFormat =
| "canonical"
| "anthropic"
| "openai"
| "ai-sdk"
| "mcp";EyeballToolFormatMap
Compile-time mapping from a requested format to its emitted tool container.
export interface EyeballToolFormatMap {
canonical: readonly ToolDefinition[];
anthropic: AnthropicToolDescriptor[];
openai: OpenAIFunctionToolDescriptor[];
"ai-sdk": AiSdkToolSet;
mcp: McpToolDescriptor[];
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
ai-sdk | AiSdkToolSet | Yes | No | — |
anthropic | AnthropicToolDescriptor[] | Yes | No | — |
canonical | readonly ToolDefinition[] | Yes | No | — |
mcp | McpToolDescriptor[] | Yes | No | — |
openai | OpenAIFunctionToolDescriptor[] | Yes | No | — |
ExecuteToolOptions
Canonical input and execution controls for tools.execute.
export interface ExecuteToolOptions {
/** Uses the client-level userId when omitted. */
userId?: string;
input: Readonly<Record<string, JsonValue>>;
/** Defaults from the canonical tool's `annotations.async` value. */
mode?: ExecutionMode;
/**
* Stable caller key for retry correlation. When omitted for a mutation, the SDK
* generates a fresh `crypto.randomUUID()` for this invocation. Pass your own key
* when separate calls must replay the same execution.
*/
idempotencyKey?: string;
connectionId?: ConnectionId;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
connectionId | | No | No | — |
idempotencyKey | string | No | No | Stable caller key for retry correlation. When omitted for a mutation, the SDK generates a fresh crypto.randomUUID() for this invocation. Pass your own key when separate calls must replay the same execution. |
input | Readonly<Record<string, JsonValue>> | Yes | No | — |
mode | ExecutionMode | No | No | Defaults from the canonical tool's annotations.async value. |
userId | string | No | No | Uses the client-level userId when omitted. |
RunToolOptions
Execution and polling controls for tools.run.
export interface RunToolOptions
extends Omit<ExecuteToolOptions, "input">,
WaitForExecutionOptions {}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
connectionId | | No | No | — |
idempotencyKey | string | No | No | Stable caller key for retry correlation. When omitted for a mutation, the SDK generates a fresh crypto.randomUUID() for this invocation. Pass your own key when separate calls must replay the same execution. |
mode | ExecutionMode | No | No | Defaults from the canonical tool's annotations.async value. |
pollMs | number | No | No | Milliseconds between polls. Defaults to 500. |
timeoutMs | number | No | No | Total milliseconds before a timeout error. Defaults to 60,000. |
userId | string | No | No | Uses the client-level userId when omitted. |
ExecuteToolCallsOptions
Name-map boundary and execution controls for framework tool-call dispatch.
export interface ExecuteToolCallsOptions {
/** Exact map emitted with the model-facing tool bundle. Unmapped calls are rejected. */
nameMap: ToolNameMap;
/** Uses the client-level userId when omitted. */
userId?: string;
connectionId?: ConnectionId;
mode?: ExecutionMode;
pollMs?: number;
timeoutMs?: number;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
connectionId | | No | No | — |
mode | ExecutionMode | No | No | — |
nameMap | ToolNameMap | Yes | No | Exact map emitted with the model-facing tool bundle. Unmapped calls are rejected. |
pollMs | number | No | No | — |
timeoutMs | number | No | No | — |
userId | string | No | No | Uses the client-level userId when omitted. |
AnthropicToolCall
Anthropic tool_use block accepted by executeToolCalls.
export interface AnthropicToolCall {
type: "tool_use";
id: string;
name: string;
input: unknown;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
id | string | Yes | No | — |
input | unknown | Yes | No | — |
name | string | Yes | No | — |
type | "tool_use" | Yes | No | — |
AnthropicToolResultBlock
Anthropic tool_result block returned by executeToolCalls.
export interface AnthropicToolResultBlock {
type: "tool_result";
tool_use_id: string;
content: string;
is_error?: boolean;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
content | string | Yes | No | — |
is_error | boolean | No | No | — |
tool_use_id | string | Yes | No | — |
type | "tool_result" | Yes | No | — |
OpenAIFunctionToolCall
OpenAI function tool call accepted by executeToolCalls.
export interface OpenAIFunctionToolCall {
id: string;
type: "function";
function: {
name: string;
arguments: string | Readonly<Record<string, JsonValue>>;
};
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
function | { name: string; arguments: string | Readonly<Record<string, JsonValue>>; } | Yes | No | — |
id | string | Yes | No | — |
type | "function" | Yes | No | — |
OpenAICustomToolCall
OpenAI custom tool call represented in the public input union.
export interface OpenAICustomToolCall {
id: string;
type: "custom";
custom: { name: string; input: string };
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
custom | { name: string; input: string; } | Yes | No | — |
id | string | Yes | No | — |
type | "custom" | Yes | No | — |
OpenAIToolCall
OpenAI function or custom tool call accepted by executeToolCalls.
export type OpenAIToolCall = OpenAIFunctionToolCall | OpenAICustomToolCall;OpenAIToolResultMessage
OpenAI tool result message returned by executeToolCalls.
export interface OpenAIToolResultMessage {
role: "tool";
tool_call_id: string;
content: string;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
content | string | Yes | No | — |
role | "tool" | Yes | No | — |
tool_call_id | string | Yes | No | — |
QualifiedToolName
export type QualifiedToolName = `${string}.${string}`;ToolDefinition
export interface ToolDefinition {
/** Exactly `<toolkit>.<canonical-tool>`, for example `gmail.send_email`. */
name: QualifiedToolName;
toolkit: ToolkitSlug;
capability: CapabilitySlug;
/** LLM-facing purpose, selection guidance, exclusions, and consequences. */
description: string;
inputSchema: ObjectSchema202012;
outputSchema?: ObjectSchema202012;
annotations: ToolAnnotations;
version: SemVer;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
annotations | ToolAnnotations | Yes | No | — |
capability | "email" | "calendar_scheduling" | "messaging_chat" | "voice_telephony" | "sms" | "crm" | "erp_accounting" | "social_media_data" | "social_media_publishing" | "file_storage_docs" | "spreadsheets_databases" | "project_management_dev_tools" | "payments_billing" | "ecommerce" | "customer_support" | "web_search_scraping" | "hr_recruiting" | "marketing_ads" | "sign_forms" | "ai_media_utilities" | Yes | No | — |
description | string | Yes | No | LLM-facing purpose, selection guidance, exclusions, and consequences. |
inputSchema | ObjectSchema202012 | Yes | No | — |
name | | Yes | No | Exactly <toolkit>.<canonical-tool>, for example gmail.send_email. |
outputSchema | ObjectSchema202012 | No | No | — |
toolkit | string | Yes | No | — |
version | | Yes | No | — |
ToolNameMap
export interface ToolNameMap {
canonicalToWire: Readonly<Record<QualifiedToolName, string>>;
wireToCanonical: Readonly<Record<string, QualifiedToolName>>;
}| Property | Type | Required | Readonly | Description |
|---|---|---|---|---|
canonicalToWire | Readonly<Record< | Yes | No | — |
wireToCanonical | Readonly<Record<string, | Yes | No | — |