Skip to main content
Tools use the Vercel AI SDK tool() helper with Zod schemas. OpenHarness ships a set of built-in tools that you can use as-is, compose, or replace entirely.

Filesystem Tools

Create filesystem tools by passing a provider to the factory function:
import { createFsTools, NodeFsProvider } from "@openharness/core";

const fsTools = createFsTools(new NodeFsProvider());
This returns the following tools:
ToolDescription
readFileRead file contents (supports line offset/limit for large files)
writeFileWrite content to a file (creates parent directories automatically)
editFileFind-and-replace within a file
listFilesList files and directories (optionally recursive, paginated for large listings)
grepRegex search across files (automatically skips node_modules, .git, paginated for large match sets)
deleteFileDelete a file or directory

Bash Tool

The bash tool runs arbitrary shell commands via bash -c:
import { createBashTool, NodeShellProvider } from "@openharness/core";

const { bash } = createBashTool(new NodeShellProvider());
Features:
  • Configurable timeout (default 30s, max 5min)
  • Automatic output truncation for large results
  • Captures both stdout and stderr with exit code

Using Tools with an Agent

Pass tools directly to the agent constructor:
const agent = new Agent({
  name: "dev",
  model: openai("gpt-5.4"),
  tools: { ...fsTools, bash },
});
You can selectively include tools — for example, a read-only agent:
const readOnlyAgent = new Agent({
  name: "explore",
  model: openai("gpt-5.4"),
  tools: {
    readFile: fsTools.readFile,
    listFiles: fsTools.listFiles,
    grep: fsTools.grep,
  },
});

Providers

The provider interface decouples tool logic from the runtime environment. The built-in NodeFsProvider and NodeShellProvider work in Node.js, but you can implement the interfaces for other environments:
  • Virtual filesystems for testing
  • E2B sandboxes for isolated execution
  • Cloudflare Workers for edge deployment
  • Daytona for managed dev environments

FsProvider Interface

interface FsProvider {
  readFile(path: string): Promise<string>;
  writeFile(path: string, content: string): Promise<void>;
  exists(path: string): Promise<boolean>;
  stat(path: string): Promise<FileStat>;
  readdir(path: string): Promise<DirEntry[]>;
  mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;
  remove(path: string, options?: { recursive?: boolean }): Promise<void>;
  rename(oldPath: string, newPath: string): Promise<void>;
  resolvePath(path: string): string;
}

ShellProvider Interface

interface ShellProvider {
  exec(
    command: string,
    options?: {
      timeout?: number;
      cwd?: string;
      env?: Record<string, string>;
    }
  ): Promise<ShellResult>;
}
The built-in NodeFsProvider includes safety guards like file size limits and binary file detection. NodeShellProvider captures exit code, stdout, and stderr with output size limits.

Todo Tools

Create session-scoped todo tools with a pluggable store:
import { createTodoTools, InMemoryTodoStore } from "@openharness/core";

const todoStore = new InMemoryTodoStore();
const todoTools = createTodoTools({
  sessionId: "chat-123",
  store: todoStore,
});
This returns:
ToolDescription
todowriteReplace the current todo list with an updated ordered list
todoreadRead the current todo list for the session
Todo items use typed statuses (pending, in_progress, completed, cancelled) and priorities (high, medium, low). If priority is omitted, it defaults to medium. When used with sessionEventsToUIStream(), successful todowrite calls emit a data-oh:todo.updated part so UI integrations can update without parsing raw tool output.