---
sidebar_position: 9
title: Core tools
---

# Core tools skill

Baseline local capabilities — file read/write, directory listing, shell execution, URL opening, async wait. The equivalent of what Cursor or Claude Code gets natively.

- **ID:** `core-tools`
- **Runs in-process** — no MCP spawn

Most Claude/Cursor/Codex nodes get these tools by default from their agent strategy — you usually don't need to opt in explicitly. Add it to the `skills` array only if you're running a node where the strategy hasn't already wired them up (e.g. some custom strategies).

## Tools provided

| Tool | What it does |
|---|---|
| `read_file` | Read a UTF-8 file. Max 256 KB; larger files return an error |
| `write_file` | Write content to a file, creating parent directories as needed |
| `list_directory` | List entries in a directory; directories suffixed with `/` |
| `run_command` | `execSync` a shell command. 30s timeout, 64 KB stdout cap, captures stderr |
| `open_url` | Open a URL in the default browser (uses `open`/`start`/`xdg-open`). Rejects non-http(s) URLs |
| `wait` | Sleep for N seconds (1–300). Respects `context.options.signal` for cancellation |

## Setup

None. The skill has no env keys, no auth, no external dependencies.

## Use in an agent

```js
import { WorkflowAgent, WorkflowGraph } from '@zibby/core';
import { SKILLS } from '@zibby/skills';

export class RepoInspector extends WorkflowAgent {
  buildGraph() {
    const graph = new WorkflowGraph();
    graph.addNode('inspect', {
      agent: 'claude',
      skills: [SKILLS.CORE_TOOLS],
      prompt: (state) => `cd into ${state.repoPath}. List the top-level directory,
      then read package.json and report the dependency graph at one level deep.`,
    });
    return graph;
  }
}
```

All paths are resolved against `context.options.workspace` (the node's working directory) — relative paths are safe to pass.

## Output example

`list_directory` returns a newline-separated string:

```
package.json
node_modules/
src/
README.md
```

`run_command`:

```
on main
nothing to commit, working tree clean
```

`open_url`:

```json
{ "ok": true, "opened": "https://zibby.dev" }
```

## Implementation notes

`resolve()` returns `null` — there is no MCP server. The strategy dispatches tool calls in-process via `handleToolCall(name, args, context)`. `wait` is the only async handler and polls the abort signal every 500 ms so the run can cancel mid-sleep.

`run_command` shells out with `execSync` and captures stdout. Long-running commands hit the 30s timeout — for builds or test runs use the dedicated `runner` or `test-runner` skills instead.
