# Tools

The tool catalog that a runtime gives its agents: built-in tools, registered Rust tools, providers, and how each tool reaches the model.

`Tools::builder()` returns a `ToolsBuilder`. A catalog starts with the workspace, web search, and image generation tools, and `without_defaults` removes them. Registered tools default to `ToolExposure::CodeModeOnly`, so the model calls them from Code Mode cells.

```rust
use nanocode::{Nanocode, Tools};

// 1. Register one #[tool] function and no built-in tools
let tools = Tools::builder()
    .without_defaults()
    .tool(checked_sum)
    .build()?;

// 2. Give the catalog to every agent of the runtime
let runtime = Nanocode::builder().tools(tools).build_async().await?;
```

## Signature

```rust
// A built catalog, and the builder that makes it
impl Tools {
    pub fn builder() -> ToolsBuilder;
    pub fn into_builder(self) -> ToolsBuilder;
}

impl ToolsBuilder {
    pub fn build(self) -> Result<Tools, ToolsBuildError>;
}
```

## Builder Methods

### tool

```rust
// Registers a tool with the catalog exposure
pub fn tool<T: Tool + 'static>(self, tool: T) -> Self
```

Registers a tool, such as a [`#[tool]`](/docs/api/rust/tool-macro) function or a [`FunctionTool`](/docs/api/rust/FunctionTool).

```rust
// Adds two tools
let tools = Tools::builder().tool(checked_sum).tool(inventory).build()?;
```

### tool_with_exposure

```rust
// Registers a tool with its own exposure
pub fn tool_with_exposure<T: Tool + 'static>(
    self,
    tool: T,
    exposure: ToolExposure,
) -> Self
```

Registers a tool with an exposure that overrides the catalog exposure.

```rust
use nanocode::tools::ToolExposure;

// Offers this tool to the model directly as well
let tools = Tools::builder()
    .tool_with_exposure(checked_sum, ToolExposure::DirectAndCodeMode)
    .build()?;
```

### exposure

* **Type:** `ToolExposure`
* **Default:** `ToolExposure::CodeModeOnly`

Sets the exposure of the built-in tools and of every registered tool without its own exposure.

```rust
use nanocode::tools::ToolExposure;

// Offers every tool as a direct function call
let tools = Tools::builder()
    .exposure(ToolExposure::DirectAndCodeMode)
    .build()?;
```

### add

```rust
// Installs a tool source, such as WorkspaceTools
pub fn add<S: ToolSource>(self, source: S) -> Self
```

Installs a tool or a tool source. A `WorkspaceTools` source enables the workspace tools for a directory, and a second one fails `build`. `WorkspaceTools` exists only on native targets.

```rust
use nanocode::tools::WorkspaceTools;

// Runs the workspace tools in a checkout
let tools = Tools::builder()
    .add(WorkspaceTools::new("/srv/app"))
    .build()?;
```

### without_defaults

```rust
// Removes the workspace, web search, and image generation tools
pub const fn without_defaults(self) -> Self
```

Turns off every built-in tool. `workspace`, `web_search`, and `image_generation` turn each one on or off.

```rust
// Keeps web search only
let tools = Tools::builder()
    .without_defaults()
    .web_search(true)
    .build()?;
```

### workspace

* **Type:** `bool`
* **Default:** `true`

Turns the workspace tools on or off. These are the shell and file tools that run in the runtime workspace.

```rust
// Removes the shell and file tools
let tools = Tools::builder().workspace(false).build()?;
```

### web_search

* **Type:** `bool`
* **Default:** `true`

Turns the provider's web search tool on or off.

```rust
// Removes web search
let tools = Tools::builder().web_search(false).build()?;
```

### image_generation

* **Type:** `bool`
* **Default:** `true`

Turns the provider's image generation tool on or off.

```rust
// Removes image generation
let tools = Tools::builder().image_generation(false).build()?;
```

### code_mode_host

```rust
// Runs Code Mode cells in a host
pub fn code_mode_host(self, host: impl CodeModeHost) -> Self
```

Runs Code Mode cells in `host` instead of the embedded engine, for example a remote socket transport. `builder.code_mode_host` on [`Nanocode`](/docs/api/rust/Nanocode#buildercode_mode_host) applies the same host to the runtime catalog.

```rust
// Executes cells on a remote hand
let tools = Tools::builder()
    .code_mode_host(transport.into_host())
    .build()?;
```

### working_directory

> [!NOTE]
> `working_directory`, `default_shell`, `process_environment`, `provider`, and `remote_http_client` exist only on native targets.

* **Type:** `impl Into<Arc<str>>`

Sets the directory that workspace tools start in. An empty value fails `build`.

```rust
// Starts shell commands in the crate directory
let tools = Tools::builder()
    .working_directory("/srv/app/crates/core")
    .build()?;
```

### default_shell

* **Type:** `impl Into<Arc<str>>`

Sets the shell that the shell tool runs. An empty value fails `build`.

```rust
// Runs commands with bash
let tools = Tools::builder().default_shell("/bin/bash").build()?;
```

### process_environment

* **Type:** `impl IntoIterator<Item = (K, V)>`

Adds environment variables for the processes that tools start. `K` and `V` convert into `OsString`.

```rust
// Disables color in tool output
let tools = Tools::builder()
    .process_environment([("NO_COLOR", "1")])
    .build()?;
```

### provider

```rust
// Adds tools that a provider discovers at runtime
pub fn provider<P: DynamicToolProvider + 'static>(
    self,
    provider: P,
) -> Self
```

Adds a dynamic tool provider, such as an MCP client. `shared_provider` takes an `Arc<dyn DynamicToolProvider>`.

```rust
// Adds an MCP provider to the catalog
let tools = Tools::builder().provider(mcp_provider).build()?;
```

## ToolExposure

Where the model can call a tool. The enum is `nanocode::tools::ToolExposure`.

| Variant             | Behavior                                                            |
| ------------------- | ------------------------------------------------------------------- |
| `CodeModeOnly`      | The default. Code Mode cells call the tool as `tools.<name>(...)`.  |
| `DirectAndCodeMode` | The model calls the tool directly, and Code Mode cells call it too. |
| `DirectOnly`        | The model calls the tool directly only.                             |
| `Hidden`            | The catalog registers the tool, but the model cannot call it.       |

```rust
use nanocode::tools::ToolExposure;

// Registers a tool that only the host uses
let tools = Tools::builder()
    .tool_with_exposure(audit_log, ToolExposure::Hidden)
    .build()?;
```

## Errors

### ToolsBuildError

`build` returns a `ToolsBuildError`. The variants include `DuplicateName` for a name registered twice, `BuiltInName` for a name that an enabled built-in tool uses, `ReservedName`, `EmptyName`, and `DuplicateSource` for a second workspace source.

```rust
use nanocode::tools::ToolsBuildError;

// Registering the same tool twice fails
match Tools::builder().tool(checked_sum).tool(checked_sum).build() {
    Err(ToolsBuildError::DuplicateName(name)) => {
        eprintln!("{name} is registered twice")
    }
    other => drop(other?),
}
```
