---
title: Built-in Tools
description: The default and opt-in tools eve provides, including glob, grep, and sleep.
---

# Built-in Tools



eve provides a default tool set for every agent and additional tools you can add with one file. Each default occupies the same `agent/tools/<name>.ts` slot you would author yourself, so an authored definition replaces it and `disableTool()` removes it. Use this page to review what the model can call, opt into more capabilities, or override and disable defaults. For custom tools, see [Tools](../tools).

## Default tools

Default tools require no imports. The exact set depends on the agent and session, and the harness advertises only the tools available to the current session.

### Disable optional default tools

Optional default tools are enabled unless you set `defaultTools: false` in `agent/agent.ts`:

```ts title="agent/agent.ts"
import { defineAgent } from "eve";

export default defineAgent({
  defaultTools: false,
  model: "openai/gpt-5.4",
});
```

This turns off the optional defaults described below. Add back only the tools the agent needs with the command in each tool's section. Existing files under `agent/tools/` remain available, including same-name replacements such as `agent/tools/bash.ts`.

`connection_search` and `connection_execute` stay available when the agent has connections because they provide access to connection tools.

### `bash`

`bash` runs shell commands in the agent's [sandbox](../sandbox).

```sh
eve add tool/bash
```

```ts title="agent/tools/bash.ts"
export { default } from "eve/tools/bash";
```

Override its description, approval policy, or executor by wrapping the exported definition:

```ts title="agent/tools/bash.ts"
import { defineTool } from "eve/tools";
import { bash } from "eve/tools/bash";

export default defineTool({
  ...bash,
  description: "Run approved project maintenance commands.",
  async execute(input, ctx) {
    console.info("Running sandbox command", input.command);
    return bash.execute(input, ctx);
  },
});
```

Disable only `bash`:

```ts title="agent/tools/bash.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `read_file`

`read_file` reads text files from the sandbox with line-numbered output. It accepts absolute paths and paths beginning with `$HOME/`.

```sh
eve add tool/read_file
```

```ts title="agent/tools/read_file.ts"
export { default } from "eve/tools/read_file";
```

Override it:

```ts title="agent/tools/read_file.ts"
import { defineTool } from "eve/tools";
import { readFile } from "eve/tools/read_file";

export default defineTool({
  ...readFile,
  description: "Read project files from the sandbox.",
});
```

Disable it:

```ts title="agent/tools/read_file.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `write_file`

`write_file` writes complete files in the sandbox. It enforces read-before-write and stale-read detection, and accepts absolute paths and paths beginning with `$HOME/`.

```sh
eve add tool/write_file
```

```ts title="agent/tools/write_file.ts"
export { default } from "eve/tools/write_file";
```

Override it:

```ts title="agent/tools/write_file.ts"
import { defineTool } from "eve/tools";
import { writeFile } from "eve/tools/write_file";

export default defineTool({
  ...writeFile,
  description: "Write approved project files in the sandbox.",
  async execute(input, ctx) {
    if (!input.filePath.startsWith("/workspace/")) {
      throw new Error("write_file is limited to /workspace");
    }
    return writeFile.execute(input, ctx);
  },
});
```

Disable it:

```ts title="agent/tools/write_file.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `web_fetch`

`web_fetch` fetches URLs from the app runtime. It follows up to ten redirects and checks every destination for SSRF safety. Non-success responses return plain text with the response body when available.

```sh
eve add tool/web_fetch
```

```ts title="agent/tools/web_fetch.ts"
export { default } from "eve/tools/web_fetch";
```

Override it:

```ts title="agent/tools/web_fetch.ts"
import { defineTool } from "eve/tools";
import { webFetch } from "eve/tools/web_fetch";

export default defineTool({
  ...webFetch,
  description: "Fetch approved public documentation URLs.",
  async execute(input, ctx) {
    const hostname = new URL(input.url).hostname;
    if (hostname !== "docs.example.com") {
      throw new Error("web_fetch is limited to docs.example.com");
    }
    return webFetch.execute(input, ctx);
  },
});
```

Disable it:

```ts title="agent/tools/web_fetch.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `web_search`

`web_search` uses provider-managed web search and appears only for supported model providers. AI Gateway models use Exa by default; direct provider models use their native search implementation.

```sh
eve add tool/web_search
```

```ts title="agent/tools/web_search.ts"
export { default } from "eve/tools/web_search";
```

Override the provider-managed configuration for AI Gateway:

```ts title="agent/tools/web_search.ts"
import { webSearch } from "eve/tools/web_search";

export default webSearch({ provider: "parallel" });
```

Replace provider-managed search with an authored implementation:

```ts title="agent/tools/web_search.ts"
import { defineTool } from "eve/tools";

export default defineTool({
  description: "Search the internal documentation index.",
  inputSchema: { type: "object" },
  async execute(input) {
    return { results: [], query: input };
  },
});
```

Disable it:

```ts title="agent/tools/web_search.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `agent`

`agent` delegates a subtask to a fresh copy of the root agent. It is root-only, and each call is a [task](/docs/tools/tasks): the call returns a receipt, and the child's reply arrives later as the task's result. The child receives the root's instructions, tools, connections, and sandbox, but starts with fresh conversation history and [state](./state). See [Subagents](../subagents).

```sh
eve add tool/agent
```

```ts title="agent/tools/agent.ts"
export { default } from "eve/tools/agent";
```

An authored tool at `agent/tools/agent.ts` replaces the framework behavior. Re-export the definition above to restore direct root-copy delegation, export another tool such as `agentRouter()` to change the model-facing behavior, or disable the slot. `agentRouter()` runs each call as a [task](/docs/tools/workflows#run-calls-as-tasks-task), which adds `task_wait` and `task_cancel`:

```ts title="agent/tools/agent.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `load_skill`

`load_skill` pulls an on-demand [skill](../skills)'s instructions into the current turn. It appears only when the agent declares skills and adds no execution surface by itself.

```sh
eve add tool/load_skill
```

```ts title="agent/tools/load_skill.ts"
export { default } from "eve/tools/load_skill";
```

Override it:

```ts title="agent/tools/load_skill.ts"
import { defineTool } from "eve/tools";
import { loadSkill } from "eve/tools/load_skill";

export default defineTool({
  ...loadSkill,
  description: "Load instructions for an available skill.",
});
```

Disable it:

```ts title="agent/tools/load_skill.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

### `connection_search`

`connection_search` and `connection_execute` give the model every tool from the agent's [connections](../connections) without adding each tool to the model's tool list. eve adds both when the agent has a static connection or a dynamic connection resolver, even when `defaultTools` is `false`, so there is no add command.

* `connection_search({ query?, connection?, signIn?, limit?, offset? })` returns matching tools with their connection, name, description, and a TypeScript signature rendered from the tool's schemas. Omit `query` to list every tool, or pair it with `connection` to list one connection's tools. A plain search never asks the user to sign in. For a connection the user has not signed in to, the result tells the model that sign-in is needed before its tools can be listed: the connection appears under `unavailable` with `requiresSignIn: true` and an error that points to `signIn: true`. Tools from the other connections are still returned.
* `connection_search({ connection, signIn: true, query? })` asks the user to sign in to that one connection when they have not yet, then returns its matching tools. Without `connection` it fails, so the user is asked about one service at a time.
* `connection_execute({ connection, tool, input })` checks `input` against the tool's input schema, calls the tool, and returns its result. When the connection needs the user's authorization, it also asks the user to sign in and the call parks until sign-in completes. The stream reports the call as a nested action named `<connection>__<tool>`, such as `linear__list_issues`, whose `parentCallId` is the `connection_execute` call id.

The definitions of both tools never change during a session. eve lists connection names and descriptions in append-only context messages rather than in the system prompt, so finding a tool, signing in, or resolving a dynamic connection keeps the cached prompt prefix.

The tools cannot be replaced or disabled. The compiler rejects an authored `agent/tools/connection_search.ts`, `agent/tools/connection_execute.ts`, or `agent/tools/connection_tools.ts`. An agent without connections has neither tool.

### `task_wait` and `task_cancel`

eve adds `task_wait` and `task_cancel` when the agent has a tool that runs its calls as [tasks](/docs/tools/tasks): any agent tool, including the built-in `agent` tool, declared subagents, and remote agents, or a tool such as `agentRouter()`, the `workflow` tool, or an authored workflow tool that defines `task(input, ctx)` or `serve(receive, ctx)`. There is no add command, and the tools are not workflow tools. Both names are reserved: the compiler rejects an authored `agent/tools/task_wait.ts` or `agent/tools/task_cancel.ts`.

* `task_wait({ timeoutSeconds? })` parks the turn until any task has a result, a new message arrives, or `timeoutSeconds` pass, and returns at once when a result is already waiting. While it waits, the stream reports `turn.waiting` for the open turn. Results arrive in a `<task_result>` message right after it returns. Waiting never stops a task.
* `task_cancel({ taskId })` stops a task's current work and says so, or says the task had no work to stop when it already finished or is an idle [resumable task](/docs/tools/workflows#resumable-tasks-serve). An id that names no task fails with `UNKNOWN_TASK`. A resumable task stays available after a cancel.

Review these tools before production use. Disable, wrap, restrict, or require approval for any tool that can access the filesystem, network, shell, or sensitive data.

You can also add the opt-in framework tools described below.

## Opt-in framework tools

These framework-provided tools are not added by default. Add only the ones the agent needs.

### `ask_question`

`ask_question` lets the model ask the user one question, then waits for the answer. The model can offer two or three options, each with a label and a short description, and the user can always type their own answer instead. Channels render the options as native UI, such as Slack select menus. Without the tool, the model can still ask in its reply text and the user answers with their next message. See [Human-in-the-loop](/docs/human-in-the-loop). Add it:

```sh
eve add tool/ask_question
```

```ts title="agent/tools/ask_question.ts"
import { askQuestion } from "eve/tools/ask_question";

export default askQuestion();
```

`ask_question` is a [workflow tool](/docs/tools/workflows) that calls `ctx.ask()`. The model receives `{ status: "answered", answer }`, where `answer` is the chosen option's label or the user's own words. A plain follow-up message answers the question too when it is the only pending question. When other questions are also pending, a message does not answer any of them: `ask_question` withdraws its question, resolves as `{ interrupted: true }`, which the model reads as `Stopped early because a new message arrived.`, and the model reads the message next. In a session that cannot request input, such as a scheduled run, the result is `{ status: "unavailable" }` and the model continues on its own judgment. Remove the file to remove the tool.

### `glob`

`glob` finds sandbox files by glob pattern. Add it:

```sh
eve add tool/glob
```

```ts title="agent/tools/glob.ts"
export { default } from "eve/tools/glob";
```

Customize it by wrapping the framework definition:

```ts title="agent/tools/glob.ts"
import { defineTool } from "eve/tools";
import { glob } from "eve/tools/glob";

export default defineTool({
  ...glob,
  description: "Find project files by glob pattern.",
});
```

Remove the file to remove the tool. `disableTool()` is unnecessary because `glob` is not added by default.

### `grep`

`grep` searches sandbox file contents with a regular expression. Add it:

```sh
eve add tool/grep
```

```ts title="agent/tools/grep.ts"
export { default } from "eve/tools/grep";
```

Customize it by wrapping the framework definition:

```ts title="agent/tools/grep.ts"
import { defineTool } from "eve/tools";
import { grep } from "eve/tools/grep";

export default defineTool({
  ...grep,
  description: "Search project files with a regular expression.",
});
```

Remove the file to remove the tool. `disableTool()` is unnecessary because `grep` is not added by default.

### `no_reply`

`no_reply` ends the turn without a reply. Use it when a scheduled check finds nothing to report, or when an action the agent already took is the whole answer. The model calls it with an optional `{ reason }`, which stays in the session history and traces and is never sent. The turn completes without a final message, so channels and schedule sends post nothing, and later turns see that the agent chose to stay quiet. Add it:

```sh
eve add tool/no_reply
```

```ts title="agent/tools/no_reply.ts"
import { noReply } from "eve/tools/no_reply";

export default noReply();
```

`no_reply` is a `defineTool` tool with [`endsTurn: true`](/docs/tools#end-the-turn-after-a-tool-call), so the turn ends only when no other tool runs in the same step. Only root sessions receive it. Slack clears the thread status when the turn completes. Remove the file to remove the tool.

### `sleep`

`sleep` pauses and durably resumes the current turn. The model calls it with `{ seconds }`; the wait does not hold an application runtime open. Concurrent calls run in parallel, and the turn resumes after the longest wait. A steering message, the default for a new message, ends the wait early: `sleep` returns `{ interrupted: true }`, which the model reads as `Stopped early because a new message arrived.`, followed by the message. Add it:

```sh
eve add tool/sleep
```

```ts title="agent/tools/sleep.ts"
import { sleep } from "eve/tools/sleep";

export default sleep();
```

Customize it by wrapping the framework definition:

```ts title="agent/tools/sleep.ts"
import { defineWorkflowTool } from "eve/tools";
import { sleep } from "eve/tools/sleep";

export default defineWorkflowTool({
  ...sleep(),
  description: "Pause before checking an external operation again.",
});
```

Remove the file to remove the tool. `disableTool()` is unnecessary because `sleep` is not added by default.

## What to read next

* [Tools](../tools): define your own tools, gate them on approval, and shape their output with `toModelOutput`
* [Dynamic capabilities](../guides/dynamic-capabilities): generate the tool set per session with `defineDynamic`
* [Sandbox](../sandbox): configure the sandbox used by shell and file tools
* [Subagents](../subagents): declare specialists that the model can delegate to


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)