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; the ratel() factory and
framework adapters are TypeScript-only today.
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) once — ratel() in TypeScript, a ToolCatalog in Python; 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
The catalog pairs each tool's metadata with an executable handler. In TypeScript,
ratel() creates the core and r.modelTools() hands back the capability tools; in Python
you build them from a ToolCatalog with search_capabilities_tool / invoke_tool_tool.
They let your agent search the catalog and invoke anything in it. Wire them into any
framework.
import asyncio
from ratel_ai import ToolCatalog, ExecutableTool, search_capabilities_tool, invoke_tool_tool
catalog = ToolCatalog()
asyncio.run(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 { ratel } from "@ratel-ai/sdk";
import { readFile } from "node:fs/promises";
const r = ratel();
await r.tools.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.
// (modelTools() also returns get_skill_content, for skills.)
const { search_capabilities, invoke_tool } = r.modelTools();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.
TypeScript SDK
@ratel-ai/sdk: the ratel() core, the ToolCatalog/ToolRegistry layer under it, capability tools, MCP ingestion, telemetry.
Python SDK
ratel-ai: the same catalog and capability-tool API, idiomatic Python.
End-to-end examples
Runnable agents that wire a catalog into a real framework — via an official adapter or a hand-rolled capability-tool loop:
examples/ai-sdk, Vercel AI SDK via@ratel-ai/vercel-ai-sdk(ToolLoopAgent+prepareStep)examples/mastra, Mastra via@ratel-ai/mastra(recallProcessor()input processor)examples/pydantic-ai, Pydantic AIexamples/mcp-chat, REPL ingesting an upstream MCP server viaregisterMcpServer