> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
title: Tools
description: Give agents typed callable actions for APIs, code execution, search, and provider-hosted capabilities.
last_verified: 2026-06-09
---

Tools give your agent the ability to take actions: call an API, run code, or search the web. The agent decides when to call a tool based on the conversation, runs it, then loops back with the result until it has a final answer.

---

## Custom tools

Define a tool with the `@tool` decorator. The SDK reads your type hints and docstring to build the JSON schema the model uses to call it correctly.

```python
from agnt5 import Agent
from agnt5.context import Context
from agnt5.tool import tool

@tool
async def get_weather(ctx: Context, city: str) -> str:
    """Get the current weather for a city.

    Args:
        city: Name of the city to check.
    """
    # call your weather API here
    return f"Sunny, 22°C in {city}"

agent = Agent(
    name="assistant",
    model="openai/gpt-4o-mini",
    instructions="You help users with weather queries.",
    tools=[get_weather],
)

result = await agent.run("What is the weather in Paris?")
print(result.output)
```

**Things to know**

- The first parameter must be `ctx: Context` (injected automatically, not exposed to the model).
- Every other parameter becomes a field the model can fill in. Type hints (`str`, `int`, `bool`, `list`) and docstring `Args:` descriptions are used to build the schema.
- Sync functions are wrapped in a thread pool automatically.
- The tool is registered globally at import time and can be reused across agents.

`@tool` decorator options:

| Parameter | Type | Default | Description |
|---|---|---|---|
| `name` | `str` | function's `__name__` | How the tool appears to the model |
| `description` | `str` | first line of docstring | What the model reads to decide when to call this tool |
| `confirmation` | `bool` | `False` | Reserved for future human-approval flow |

---

## Inspecting tool calls

After `agent.run()`, `result.tool_calls` lists every tool the agent invoked during its loop.

```python
result = await agent.run("What is the weather in Paris?")

print(result.output)      # final answer
print(result.tool_calls)  # [{"name": "get_weather", "arguments": '{"city": "Paris"}', "iteration": 1}]
```

---

## Agents as tools

Pass another `Agent` directly in the `tools` list. The SDK wraps it automatically. The calling agent invokes it like any other tool and gets the specialist's response back before continuing its own reasoning.

```python
from agnt5 import Agent

lookup_agent = Agent(
    name="lookup",
    model="openai/gpt-4o-mini",
    instructions="You look up factual information and return concise answers.",
)

orchestrator = Agent(
    name="orchestrator",
    model="openai/gpt-4o-mini",
    instructions="Use lookup to find information, then summarize it for the user.",
    tools=[lookup_agent],   # auto-wrapped as ask_lookup
)

result = await orchestrator.run("What is the capital of Japan?")
print(result.output)
```

---

## Sandbox tools

`sandbox_tools()` returns four ready-made tools that give your agent a persistent code execution workspace. The sandbox state is shared across all tool calls within a single agent run. The agent can write a file, run it, and read the output in sequence.

```python
from agnt5 import Agent, sandbox_tools

agent = Agent(
    name="coder",
    model="openai/gpt-4o-mini",
    instructions=(
        "You are a coding assistant. Use sandbox_execute_code to run code, "
        "sandbox_write_file to save files, and sandbox_read_file to inspect results. "
        "Always verify your code works by running it before returning the answer."
    ),
    tools=sandbox_tools(),
)

result = await agent.run("Calculate the first 10 fibonacci numbers in Python")
print(result.output)
```

The four tools:

| Tool | What it does |
|---|---|
| `sandbox_execute_code` | Run code and return stdout, stderr, and exit code. Supports `python`, `javascript`, and `bash` |
| `sandbox_write_file` | Write a file to the sandbox workspace |
| `sandbox_read_file` | Read a file from the sandbox workspace |
| `sandbox_list_files` | List files in the workspace, optionally recursive |

---

## Built-in tools

Built-in tools run entirely on the provider's infrastructure. You enable them and the provider handles execution. Results are already included in the model's response; no local code runs.

```python
from agnt5 import Agent
from agnt5.lm import BuiltInTool

agent = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions=(
        "You are a research assistant. Always use web_search to find current "
        "information, never answer from training knowledge alone."
    ),
    built_in_tools=[BuiltInTool.WEB_SEARCH],
)

result = await agent.run("Who won the most recent Formula 1 championship?")
print(result.output)
```

Available built-in tools:

| Tool | What it does | Provider |
|---|---|---|
| `BuiltInTool.WEB_SEARCH` | Live web search with cited results | OpenAI, Anthropic |
| `BuiltInTool.CODE_INTERPRETER` | Run code in a provider-hosted sandbox | OpenAI only |
| `BuiltInTool.FILE_SEARCH` | Search over files uploaded to the provider | OpenAI only |
| `BuiltInTool.WEB_FETCH` | Fetch the content of a specific URL | Anthropic only |

You can mix built-in tools with custom tools on the same agent:

```python
from agnt5 import Agent, sandbox_tools
from agnt5.lm import BuiltInTool

agent = Agent(
    name="assistant",
    model="openai/gpt-4o-mini",
    instructions="Search the web for information and run code when needed.",
    built_in_tools=[BuiltInTool.WEB_SEARCH],
    tools=sandbox_tools(),
)
```

---

## MCP tools

Use [Model Context Protocol](/docs/build/mcp.md) when a tool already exists in an external MCP server. `MCPClient` connects to the server, discovers tools, and returns AGNT5 `Tool` objects that you pass to an agent.

```python
from agnt5 import Agent
from agnt5.mcp import MCPClient

mcp = MCPClient(id="repo-tools")
mcp.add_streamable_http_server("deepwiki", "https://mcp.deepwiki.com/mcp")
await mcp.connect()

agent = Agent(
    name="repository_researcher",
    model="openai/gpt-4o-mini",
    instructions="Use available tools to answer questions about code repositories.",
    tools=mcp.get_tools(),
)
```

See [Model Context Protocol](/docs/build/mcp.md) for transports, direct tool calls, and exposing AGNT5 primitives as an MCP server.

---

## Human-in-the-loop tools

Two built-in tool classes let an agent pause and wait for a human response before continuing. Both require a workflow context because execution must durably suspend while waiting.

```python
from agnt5 import Agent, workflow, WorkflowContext
from agnt5.tool import AskUserTool, RequestApprovalTool

@workflow
async def agent_with_hitl(ctx: WorkflowContext, task: str) -> dict:
    agent = Agent(
        name="assistant",
        model="openai/gpt-4o-mini",
        instructions=(
            "Ask the user for clarification when the request is ambiguous. "
            "Always request approval before making any changes."
        ),
        tools=[AskUserTool(ctx), RequestApprovalTool(ctx)],
    )
    result = await agent.run(task, context=ctx)
    return {"response": result.output}
```

| Tool | Behaviour |
|---|---|
| `AskUserTool(ctx)` | Agent calls `ask_user` with a question. Workflow pauses until the user types a response |
| `RequestApprovalTool(ctx)` | Agent calls `request_approval` with an action description. Workflow pauses and shows Approve / Reject to the user |
