Skip to content

createAgentTools

The ergonomic entry point. It resolves a config once and returns an AgentTools object with listTools() and callTool(). This is the high-level API; the core API exposes the same behavior unwrapped.

Signature

ts
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.

ts
import { createAgentTools } from "@clarvis/agent-tools";

const tools = createAgentTools({ workspaceRoot: process.cwd() });

AgentTools

ts
interface AgentTools {
  readonly config: ServerConfig;
  listTools(): ToolInfo[];
  callTool(name: string, args?: Record<string, unknown>): Promise<DispatchResult>;
}
MemberTypeDescription
configServerConfigThe 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

ts
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:

ts
interface DispatchResult {
  isError: boolean;
  text: string;
}
  • On success (isError: false), text is the tool's output, already bounded to maxOutputBytes. It is plain text for every tool except bash, whose success text is a JSON object { exit_code, stdout, stderr, signal, timed_out } — a non-zero exit is still a success.
  • On failure (isError: true), text is a JSON error envelope. An unknown tool name — or a mutating tool while readOnly is set — comes back as isError with code not_found.

Example

ts
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

Released under the MIT License.