createAgentTools
The ergonomic entry point. It resolves a config once and returns an
AgentToolsobject withlistTools()andcallTool(). This is the high-level API; the core API exposes the same behavior unwrapped.
Signature
function createAgentTools(options: AgentToolsOptions): AgentTools;options is the same object accepted by resolveConfig — only workspaceRoot is required. Passing an invalid config (missing/nonexistent workspace, or an out-of-range limit) throws a StartupError synchronously.
import { createAgentTools } from "@clarvis/agent-tools";
const tools = createAgentTools({ workspaceRoot: process.cwd() });AgentTools
interface AgentTools {
readonly config: ServerConfig;
listTools(): ToolInfo[];
callTool(name: string, args?: Record<string, unknown>): Promise<DispatchResult>;
}| Member | Type | Description |
|---|---|---|
config | ServerConfig | The fully-resolved, frozen config (see Configuration). |
listTools | () => ToolInfo[] | The advertised surface for the active config — respects readOnly. |
callTool | (name, args?) => Promise<DispatchResult> | Validate args, run the tool, bound the output, serialize any error. Defaults args to {}. |
The object is a thin wrapper: listTools() calls listTools(config) and callTool() calls dispatch(name, args, config) from the core API.
ToolInfo
interface ToolInfo {
name: string;
description: string;
inputSchema: Record<string, unknown>; // JSON Schema
}What listTools() returns for each tool. inputSchema is a JSON Schema you can hand directly to a model's tool-use / function-calling API. See The tools for each tool's schema.
DispatchResult
callTool / dispatch never throw for tool-level problems — they always resolve to a DispatchResult:
interface DispatchResult {
isError: boolean;
text: string;
}- On success (
isError: false),textis the tool's output, already bounded tomaxOutputBytes. It is plain text for every tool exceptbash, whose successtextis a JSON object{ exit_code, stdout, stderr, signal, timed_out }— a non-zero exit is still a success. - On failure (
isError: true),textis a JSON error envelope. An unknown tool name — or a mutating tool whilereadOnlyis set — comes back asisErrorwith codenot_found.
Example
import { createAgentTools } from "@clarvis/agent-tools";
const tools = createAgentTools({ workspaceRoot: process.cwd(), readOnly: true });
for (const tool of tools.listTools()) {
console.log(tool.name, "→", tool.description);
}
const res = await tools.callTool("grep", { pattern: "createAgentTools", output_mode: "content" });
console.log(res.isError ? JSON.parse(res.text) : res.text);See also
- Configuration — the
AgentToolsOptionsandServerConfigshapes - The tools — inputs, output, and errors for each tool
- Core API —
dispatch/listTools/ the registry behind this factory - Embed it in an agent loop — the intended usage pattern