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

# Tool calling

> Expose Caesar search and read as generic function tools in any model runtime that supports tool calls.

Any tool-calling runtime can use Caesar with two functions: `web_search` and `web_fetch`. The same tool names appear in the [MCP server](/clients/mcp/remote) and [AI SDK tools](/clients/sdks/ai-sdk).

## TypeScript dispatcher

```bash theme={"system"}
npm install caesar-search
```

```ts theme={"system"}
import { Caesar } from "caesar-search";

const caesar = new Caesar(); // reads CAESAR_API_KEY

export const caesarTools = [
  {
    name: "web_search",
    description: "Search the web with Caesar and return ranked results with doc_id values.",
    input_schema: {
      type: "object",
      properties: {
        query: { type: "string" },
        max_results: { type: "integer", minimum: 1, maximum: 50 },
        response_format: { type: "string", enum: ["compact", "standard", "full"] },
      },
      required: ["query"],
    },
  },
  {
    name: "web_fetch",
    description: "Read a Caesar doc_id or URL as clean markdown.",
    input_schema: {
      type: "object",
      properties: {
        target: { type: "string" },
        query: { type: "string" },
        max_chars: { type: "integer", minimum: 1, maximum: 50000 },
        start_char: { type: "integer", minimum: 0 },
      },
      required: ["target"],
    },
  },
];

export async function runCaesarToolCall(call: {
  name: string;
  input: Record<string, unknown>;
}) {
  if (call.name === "web_search") {
    const query = String(call.input.query);
    const maxResults = Number(call.input.max_results ?? 8);
    const responseFormat = String(call.input.response_format ?? "compact");

    return caesar.search(query, {
      maxResults,
      verbosity: responseFormat as "compact" | "standard" | "full",
    });
  }

  if (call.name === "web_fetch") {
    const target = String(call.input.target);
    return caesar.read(target, {
      query: call.input.query ? String(call.input.query) : undefined,
      maxChars:
        call.input.max_chars === undefined
          ? undefined
          : Number(call.input.max_chars),
      startChar: Number(call.input.start_char ?? 0),
    });
  }

  throw new Error(`unknown tool: ${call.name}`);
}
```

Adapt the schema wrapper (`input_schema`, `parameters`, or similar) to your model runtime, but keep the inner field names snake\_case. Those names match the API and reduce translation errors.

## Python dispatcher

```bash theme={"system"}
pip install caesar-search
```

```python theme={"system"}
from typing import Any

from caesar_search import Caesar

client = Caesar()  # reads CAESAR_API_KEY


def run_caesar_tool_call(name: str, arguments: dict[str, Any]) -> Any:
    if name == "web_search":
        return client.search(
            str(arguments["query"]),
            max_results=int(arguments.get("max_results", 8)),
            verbosity=str(arguments.get("response_format", "compact")),
        ).model_dump()

    if name == "web_fetch":
        max_chars = arguments.get("max_chars")
        return client.read(
            str(arguments["target"]),
            query=arguments.get("query"),
            max_chars=int(max_chars) if max_chars is not None else None,
            start_char=int(arguments.get("start_char", 0)),
        ).model_dump()

    raise ValueError(f"unknown tool: {name}")
```

## Feedback

Tool-calling loops often stop after the model produces an answer. If you can observe which result the agent used, close the loop:

```ts theme={"system"}
await caesar.feedback("result_helpful", {
  searchId: search_id,
  docId: doc_id,
});
```

## For agents

* Use `response_format: "compact"` for initial searches. Request `standard` or `full` only when you need passages or capture provenance.
* Pass `doc_id` from `web_search` into `web_fetch`. Prefer it over reusing the URL when you have it.
* Preserve `search_id` until the task is done so feedback can be attributed to the right ranked list.
* Do not expose API keys as tool arguments. Configure `CAESAR_API_KEY` in the runtime environment.
