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

# TOOL IMPLEMENTATIONS

> Decide what a model gets back when it calls one of your tools

A tool implementation decides how each call to a [tool](/guides/agents/tools) is answered. A tool only describes a function: its name, its parameters, and the shape of its output. An implementation supplies the output a model reads when it calls that tool during synthesis or evaluation. Create an implementation for every tool that a job attaches.

Each implementation serves exactly one tool. A tool can have several implementations, for example a lookup table for fast deterministic tests and an endpoint for real outputs. A job picks at most one implementation per tool.

***

## HOW TOOL IMPLEMENTATIONS WORK

When a model calls a tool during a job, Oumi passes the call to the implementation that the job attached for that tool. The implementation produces one of two results:

* **An output.** The model reads it as the tool's answer. If the tool declares an output schema, Oumi checks the output against it.
* **A refusal.** The tool rejects the call in its own words, for example a lookup table with no matching row or an endpoint that answers with a 4xx status. The model reads the refusal message as the tool's answer and decides what to do next.

Implementations are immutable. After you create one, you can change only its display name and, for an endpoint, its credential. To change anything else, create a new implementation. In the web app, the `Duplicate` action prefills a new implementation from an existing one.

To add an implementation, open the tool's detail page and click `Create implementation` in the **Implementations** section. For every field, default, and constraint of each type, see the [tool implementation schema](/reference/schema/tool-implementations).

***

## CHOOSING A TYPE

Answer these questions in order and stop at the first yes:

1. Does the tool already exist as a real service that you can reach over HTTP or MCP? Use **endpoint**. It returns real outputs, so prefer it when it is available.
2. Does the tool ask the user something, such as a clarifying question, a confirmation, or a short choice? Use **interactive**.
3. Are all of the tool's outputs known in advance and few enough to list? Use **lookup**.
4. Otherwise, use **simulated**.

| Type | Who answers the call | Cost | Best for |
| - | - | - | - |
| **Endpoint** | Your HTTPS service, over plain HTTP or MCP | Whatever your service costs | Real outputs from a real system |
| **Interactive** | The simulated user in the conversation | Billed with the user model | Questions the agent puts to the user |
| **Lookup** | A fixed table of input and output rows | Free, deterministic | A closed catalog or record set |
| **Simulated** | A hosted model, guided by a persona you write | Billed as inference | Tools with open-ended outputs that you have no service for |

### ENDPOINT

An endpoint implementation forwards each call to your service at a public HTTPS URL. It speaks one of two protocols:

* **HTTP** sends one request per call. You choose the method. `POST`, `PUT`, and `PATCH` send the arguments as the JSON body. `GET` and `DELETE` send them as query parameters. `POST` is the default.
* **MCP** calls your service as an MCP server over Streamable HTTP.

See [Build an endpoint](#build-an-endpoint) for the full request and response contract.

### INTERACTIVE

An interactive implementation hands each call to the simulated user who drives the conversation. The user's reply becomes the tool's output. Use it for tools that get a quick reply from the user, not for tools that fetch data. It has no configuration of its own, but it has two requirements:

* Add a [simulated user](/guides/agents/simulated-users) to any job that attaches it, in the job's **User Model** section.
* The tool's output schema must fit one short reply. It must be an object with exactly one string property, and it cannot require any other property. A tool with no output schema also works. Oumi rejects an interactive implementation for any other schema.

### LOOKUP

A lookup implementation holds a table of rows. Each row has an `input`, the tool arguments it matches, and an `output`, the value it returns. A call whose arguments match a row's `input` returns that row's `output`. A call that matches no row is refused, so the model reads an error instead of an output. Each input must be unique, and the table needs at least one row.

### SIMULATED

A simulated implementation sends each call to a hosted model, which invents a plausible output. You write a **tool persona** that tells the model how the tool behaves: its response style, how realistic its values are, and how it handles edge cases. Do not repeat the tool's name, description, parameters, or output schema in the persona. Oumi gives these to the model already.

Pick a capable model. A weak model simulates tools poorly. Two options are on by default:

* **Guided decoding** constrains the generated output to the tool's output schema. Turn it off when the schema is so large that constraining it is slow or unsupported. Oumi still checks the output against the schema after generation.
* **Cache repeated calls** returns the earlier result when a call repeats the same arguments, instead of simulating it again.

Every simulated call is a model call and is billed as inference.

***

## BUILD AN ENDPOINT

This section describes what your service receives and what it must return.

### REQUESTS

Oumi sends one request per tool call to your `endpointUrl`. With the HTTP protocol, each request carries two headers:

| Header | Value |
| - | - |
| `X-Oumi-Call-Id` | Identifies this call |
| `X-Oumi-Session-Id` | Groups the calls that belong to one conversation |

`POST`, `PUT`, and `PATCH` send the tool arguments as the JSON request body. `GET` and `DELETE` send them as query parameters. With `GET` or `DELETE`, every argument must be a scalar or an array of scalars, and no argument can share a name with a query parameter already in `endpointUrl`. Oumi repeats the key once for each item in an array and leaves out an argument that is null or an empty array. Oumi rejects an implementation whose tool has parameters that cannot be sent this way.

If you set a credential, Oumi sends it in one header. A bearer credential is sent as `Authorization: <scheme> <token>`. An API key credential is sent on its own in the header you name.

### RESPONSES

Oumi reads the whole response body as the tool's output, so return JSON that matches the tool's output schema. If your service wraps its answer in an envelope, declare that envelope as the tool's output schema. An empty body, such as a `204` response, is a null output.

How Oumi treats the status code:

* **2xx:** the body is the tool's output.
* **4xx, except 408 and 429:** the tool refused the call. The model reads the status and the first 200 characters of the body as the tool's answer, so return a short, readable reason.
* **408, 429, 5xx, timeouts, and unreachable hosts:** the endpoint failed to answer. During a job, the model reads a fixed message that says the tool could not be run.

A response that is not valid JSON, is larger than 1 MiB, or does not match the tool's output schema also counts as a failure. Oumi does not follow redirects.

### MCP

With the MCP protocol, Oumi sends each call as one stateless JSON-RPC `tools/call` request over Streamable HTTP, with no `initialize` handshake. The request names the tool by its tool name, carries the arguments, and puts the session ID under `_meta` as `ai.oumi/sessionId`. Your server may answer with JSON or with a server-sent event stream.

* If the result includes `structuredContent`, Oumi uses it as the tool's output. Otherwise, Oumi joins the result's text content blocks into a string.
* A result with `isError: true` is a refusal. The model reads its text content as the tool's answer.
* A JSON-RPC error or a non-2xx status is a failure, not a refusal.

### ADDRESS AND TIMEOUT RULES

* The URL must use HTTPS, and its host must resolve to a public address. Oumi checks this when you create the implementation.
* `timeoutSeconds` sets how long Oumi waits for one call, from 1 to 120 seconds. The default is 30.

***

## MANAGE CREDENTIALS

Credentials are write-only. Reads return the authentication type, the scheme or header name, and a `stubbedToken` that shows at most the first and last four characters of the token. The full token never appears in a response.

Only endpoint implementations have a credential. You can rotate it at any time without creating a new implementation, and the new credential applies from the next job onward. For the request, see [Update request](/reference/schema/tool-implementations#update-request).

***

## TEST AN IMPLEMENTATION

Run a few calls through a new implementation before you use it in a job. Try success cases, each use case you expect, failures, and empty inputs. Testing matters most for simulated implementations: adjust the persona and test again until the outputs look right. A fix here is cheaper than a fix after a full job.

> [!WARNING]
>
> Running a test requires a valid payment card on file for your organization.

A test returns the tool's output, or its refusal message when the tool refuses the call. Read a refusal and fix the arguments or the table. Do not retry an endpoint test unchanged, because each test sends a real call to your service and the first call may already have had its effect.

You cannot test an interactive implementation, because only the simulated user in a job answers its calls. For the request and response fields, see [Execute request](/reference/schema/tool-implementations#execute-request).

***

## USE IMPLEMENTATIONS IN A JOB

A model in a synthesis or evaluation job can call only the tools whose implementations you attach to that job. To attach them, follow the steps for [synthesis](/guides/synthesis/how-it-works#add-tools-and-a-simulated-user) or [evaluations](/guides/evaluations/running#add-tools-and-a-simulated-user).


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