Ratel Docs
Features

SDKs

Two first-party SDKs, TypeScript and Python, over one Rust core. In-process, no infra, no API key.

Ratel ships two first-party SDKs that bundle the same Rust core (ratel-ai-core), @ratel-ai/sdk for TypeScript / Node and ratel-ai for Python. The API is mirrored across both.

Everything runs in-process: no external vector DB or embedding service, no API key, nothing to deploy. BM25 needs no embeddings; semantic and hybrid retrieval opt into a local embedding model, downloaded once on first use and cached.

The wedge today is tool selection. Register your tools (or ingest an upstream MCP server) into a ToolCatalog; a BM25 index ranks them so the model sees the handful that matter for the current turn, reached through two self-service tools, search_capabilities and invoke_tool, instead of the full list.

Use the toggle to switch languages; your choice follows you across every page.

Install

npm install @ratel-ai/sdk or pip install ratel-ai — versions, extras, native targets, and Ratel Local live on the Install page.

Register a catalog, hand the agent two tools

ToolCatalog pairs each tool's metadata with an executable handler. searchCapabilitiesTool / invokeToolTool (snake_case in Python) are the capability tools: they let your agent search the catalog and invoke anything in it. Wire them into any framework.

from ratel_ai import ToolCatalog, ExecutableTool, search_capabilities_tool, invoke_tool_tool

catalog = ToolCatalog()
catalog.register(
    ExecutableTool(
        id="read_file",
        name="read_file",
        description="Read a file from local disk.",
        input_schema={"properties": {"path": {"type": "string"}}},
        output_schema={"properties": {"contents": {"type": "string"}}},
        execute=lambda args: {"contents": open(args["path"]).read()},
    )
)

# The full catalog stays out of context; the agent reaches it via these two.
search = search_capabilities_tool(catalog)  # id == "search_capabilities"
invoke = invoke_tool_tool(catalog)          # id == "invoke_tool"
import { ToolCatalog, searchCapabilitiesTool, invokeToolTool } from "@ratel-ai/sdk";
import { readFile } from "node:fs/promises";

const catalog = new ToolCatalog();
catalog.register({
  id: "read_file",
  name: "read_file",
  description: "Read a file from local disk.",
  inputSchema: { properties: { path: { type: "string" } } },
  outputSchema: { properties: { contents: { type: "string" } } },
  execute: async ({ path }) => ({ contents: await readFile(path, "utf8") }),
});

// The full catalog stays out of context; the agent reaches it via these two.
const search = searchCapabilitiesTool(catalog); // id === "search_capabilities"
const invoke = invokeToolTool(catalog);         // id === "invoke_tool"

Need only ranking, no execution? Use ToolRegistry (metadata-only BM25 index) and dispatch calls yourself. Both layers are covered in the language references below.

Full reference

The per-language pages document the full shipped API of ratel-ai/ratel: every class, capability tool, and telemetry hook, with mirrored snippets in both languages.

End-to-end examples

Runnable agents that wire a catalog into a real framework, with a BM25 pre-filter plus the search_capabilities / invoke_tool capability tools:

On this page