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

# Tools

> Let a Lume model call a function in your application.

A tool is a function your application knows how to run. You describe it on the request. The model can answer in text, or it can ask you to call that function. You run it, send the result back, and the model writes the reply.

Chat Completions and Messages both do this. The tool description is different on each API. The examples use `lume-3.5`.

## Chat Completions

`POST /v1/chat/completions` needs the scope `chat:completions`. Each tool has `type` set to `function`. You can send up to 64 tools. A function name matches `^[A-Za-z0-9_-]{1,64}$`, and each function schema can be at most 16,384 bytes.

`tool_choice` is `none`, `auto`, `required`, or one named function. `parallel_tool_calls` is a boolean. Leave `tool_choice` out and the model decides.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.overcontrolgroup.com/v1/chat/completions \
    -H "Authorization: Bearer $OVERCONTROL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "lume-3.5",
      "max_tokens": 256,
      "messages": [
        {"role": "user", "content": "What is the temperature in Lisbon?"}
      ],
      "tools": [
        {
          "type": "function",
          "function": {
            "name": "get_temperature",
            "description": "Get the temperature for a city.",
            "parameters": {
              "type": "object",
              "properties": {
                "city": {"type": "string"}
              },
              "required": ["city"]
            }
          }
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import os
  from openai import OpenAI

  client = OpenAI(
      api_key=os.environ["OVERCONTROL_API_KEY"],
      base_url="https://api.overcontrolgroup.com/v1",
  )

  response = client.chat.completions.create(
      model="lume-3.5",
      max_tokens=256,
      messages=[{"role": "user", "content": "What is the temperature in Lisbon?"}],
      tools=[
          {
              "type": "function",
              "function": {
                  "name": "get_temperature",
                  "description": "Get the temperature for a city.",
                  "parameters": {
                      "type": "object",
                      "properties": {"city": {"type": "string"}},
                      "required": ["city"],
                  },
              },
          }
      ],
  )

  print(response.choices[0].message.tool_calls)
  ```
</CodeGroup>

When the model wants the function, `finish_reason` is `tool_calls` and `message.content` is null. `function.arguments` is a JSON string, not an object.

```json theme={null}
{
  "id": "chatcmpl_0123456789abcdef0123456789abcdef",
  "object": "chat.completion",
  "created": 1789430400,
  "model": "lume-3.5",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_0123456789abcdef",
            "type": "function",
            "function": {
              "name": "get_temperature",
              "arguments": "{\"city\":\"Lisbon\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 40,
    "completion_tokens": 12,
    "total_tokens": 52
  }
}
```

Run the function, then send the conversation back with the assistant message and a tool result:

```json theme={null}
{"role": "tool", "tool_call_id": "call_0123456789abcdef", "content": "18"}
```

The next completion is the reply your user sees. On a stream, that same call finishes with `finish_reason` `tool_calls`, and the arguments arrive in `delta.tool_calls`.

Older clients can still send `functions` and `function_call`. A tool call then comes back as `message.function_call`, and `finish_reason` is `function_call`. New code should use `tools`.

The response includes `X-Request-Id`.

## Messages

`POST /v1/messages` needs `messages:create` and `anthropic-version: 2023-06-01`. A client tool has a `name`, a `description`, and an `input_schema`. Leave `type` out, or set it to `custom`. `strict: true` is rejected. `strict: false` is ignored.

Server-side tools, including web search, code execution, and MCP tools, are rejected. A tool whose only job is to search other tools is rejected too.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.overcontrolgroup.com/v1/messages \
    -H "x-api-key: $OVERCONTROL_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "lume-3.5",
      "max_tokens": 256,
      "tools": [
        {
          "name": "get_temperature",
          "description": "Get the temperature for a city.",
          "input_schema": {
            "type": "object",
            "properties": {
              "city": {"type": "string"}
            },
            "required": ["city"]
          }
        }
      ],
      "messages": [
        {"role": "user", "content": "What is the temperature in Lisbon?"}
      ]
    }'
  ```

  ```python Python theme={null}
  import os
  from anthropic import Anthropic

  client = Anthropic(
      api_key=os.environ["OVERCONTROL_API_KEY"],
      base_url="https://api.overcontrolgroup.com",
  )

  message = client.messages.create(
      model="lume-3.5",
      max_tokens=256,
      tools=[
          {
              "name": "get_temperature",
              "description": "Get the temperature for a city.",
              "input_schema": {
                  "type": "object",
                  "properties": {"city": {"type": "string"}},
                  "required": ["city"],
              },
          }
      ],
      messages=[{"role": "user", "content": "What is the temperature in Lisbon?"}],
  )

  print(message.content)
  ```
</CodeGroup>

A tool call is a content block, and `stop_reason` is `tool_use`. `input` is an object.

```json theme={null}
{
  "type": "tool_use",
  "id": "toolu_0123456789abcdef",
  "name": "get_temperature",
  "input": {"city": "Lisbon"}
}
```

Send the result on the next user message:

```json theme={null}
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_0123456789abcdef",
      "content": "18"
    }
  ]
}
```

The result has to refer to a `tool_use` from an earlier assistant turn. On a stream, the arguments arrive as `input_json_delta` events. [Streaming](/text/streaming) lists those events.

## Next

<CardGroup cols={2}>
  <Card title="Streaming" icon="wave-pulse" href="/text/streaming">
    Read a tool call as it is written.
  </Card>

  <Card title="Structured outputs" icon="braces" href="/text/structured-outputs">
    Ask for JSON text instead of a function call.
  </Card>
</CardGroup>


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