> ## Documentation Index
> Fetch the complete documentation index at: https://phaseo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Phaseo Gateway base URL: https://api.phaseo.app/v1. Send `Authorization: Bearer $PHASEO_API_KEY` with every request.
> Model IDs look like `provider/model`, for example `openai/gpt-6-astra`. Do not guess IDs: list them with `GET /v1/models` or check https://phaseo.app/models. `phaseo/free` routes to an available free model and needs no wallet balance.
> For new text integrations prefer `POST /v1/responses`. `POST /v1/chat/completions` (OpenAI format) and `POST /v1/messages` (Anthropic format) suit existing code.
> The full API contract is https://phaseo.app/docs/openapi/v1/openapi.yaml. Official SDKs: `@phaseo/sdk` (TypeScript) and `phaseo` (Python), plus Go, C#, PHP, Ruby and Rust.
> Search these docs over MCP at https://phaseo.app/docs/mcp, and install Phaseo skills with `npx skills add https://phaseo.app/docs`. If a page is wrong or out of date, report it with the MCP `submit_feedback` tool.
> Manage Phaseo accounts with the `phaseo` CLI (`npm install -g @phaseo/cli`, then `phaseo login` or `phaseo login --device-code`), the `/v1` Management API or the MCP server at `https://mcp.phaseo.app/mcp?access=manage`. Do not send users to the dashboard for account tasks. A person is still needed for sign-up, approving a sign-in, paying the first top-up on the checkout link that `phaseo credits add` returns when no card is saved, confirming each saved-card top-up from the emailed link, and account security (password, MFA, passkeys). Create API keys with `phaseo keys create --name <name> --json`; never guess one. Credit top-ups need `phaseo login --scopes billing:write` first. Task map: https://phaseo.app/docs/v1/developers/manage-from-an-agent.md.

# Tools

> Define validated local tools, manual tools, and progress-producing tools.

Use tools when an agent needs to read application data, call an internal service, or perform an action. The Agent SDK validates tool boundaries and runs tool code inside your application.

## Define a local tool

`defineTool()` accepts a description, optional JSON parameters, runtime validators, a timeout, and an `execute()` function.

```typescript theme={null}
import { defineTool } from "@phaseo/agent-sdk";

const fetchTicket = defineTool({
  id: "fetch-ticket",
  description: "Load one internal support ticket.",
  parameters: {
    type: "object",
    properties: {
      ticketId: { type: "string" },
    },
    required: ["ticketId"],
    additionalProperties: false,
  },
  timeoutMs: 3_000,
  async execute(input: { ticketId: string }, context) {
    const response = await fetch(
      `https://internal.example/tickets/${input.ticketId}`,
      { signal: context.signal },
    );

    return response.json();
  },
});
```

If the timeout expires, the runtime aborts `context.signal`, marks the run as failed, and rethrows the timeout error.

Schemas can be functions or objects exposing `parse()` or `safeParse()`. Invalid model arguments and invalid tool results fail before they cross the tool boundary.

## Run work in your application

Set `execute: false` when your application, rather than the SDK process, performs the work. Continue the paused run with the result in `toolOutputs`.

For an interactive tool, return `null` from `onToolCalled`. After continuation, `onResponseReceived` can validate or transform the supplied response.

## Publish progress

An async generator can yield preliminary results before returning one final result:

```typescript theme={null}
const indexRepository = defineTool({
  id: "index-repository",
  async *execute(input: { path: string }) {
    yield { phase: "scan" };
    yield { phase: "embed" };
    return { indexed: 248 };
  },
});
```

Progress is available through `tool.preliminary_result` events and the step's `preliminaryResults`.

## Run independent tools concurrently

If one model turn can safely call several independent tools, configure a concurrency limit:

```typescript theme={null}
const agent = createAgent({
  id: "research-agent",
  toolExecution: {
    toolConcurrency: 3,
  },
  tools: [fetchDocs, fetchStatus, fetchIncidents],
});
```

The runtime preserves tool-result message order even when local execution overlaps.

## Related guides

* [Pause, approve, and resume runs](https://phaseo.app/docs/v1/sdk-reference/typescript/agent-sdk-state-and-approval.md)
* [Stream agent results](https://phaseo.app/docs/v1/sdk-reference/typescript/agent-sdk-streaming.md)
* [Fan out local tools concurrently](https://phaseo.app/docs/v1/cookbook/agent-sdk-parallel-tools.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.