Quickstart
Install @ratel-ai/sdk, create the ratel() core, register your tools and prompt playbooks, and hand any agent loop the three capability tools.
This is the TypeScript path. Python reader? Start at the Python quickstart. Rather not write the integration yourself? Point your coding agent at the skills suite.
Ratel is framework-agnostic: everything the SDK hands you is a plain executable tool (metadata plus an execute handler) that plugs into any agent loop. This page shows the two ways in: starting from scratch and migrating an existing agent.
Before you start
Use Node.js 20 or newer. Nothing on this page calls a model, so no API key is needed.
How it works
Everything starts with ratel(): one core holding a tool catalog and a skill catalog. Register each of your tools once on r.tools, pairing its metadata (id, description, JSON schemas) with the handler that runs it; register Markdown playbooks on r.skills, ranked in their own corpus.
The agent reaches both through the three capability tools from r.modelTools(): search_capabilities (find tools and skills by description), invoke_tool (run a tool by id), and get_skill_content (load a skill's body), so the full catalog never enters the prompt. How the pieces fit per turn is covered in Architecture.
Start from scratch
Create a project and install the SDK
mkdir ratel-quickstart && cd ratel-quickstart
npm init -y
npm pkg set type=module
npm install @ratel-ai/sdk
npm install --save-dev tsxRequirements, prebuilt targets, and optional packages are on Install.
Register a tool and a skill
Create index.ts. Tools carry their metadata and handler; skills carry a description and a Markdown body:
import { ratel } from "@ratel-ai/sdk";
const r = ratel();
await r.tools.register({
id: "get_weather",
name: "get_weather",
description: "Get the current weather for a city.",
inputSchema: {
type: "object",
properties: {
city: { type: "string", description: "City name" },
},
required: ["city"],
},
outputSchema: {
type: "object",
properties: {
city: { type: "string" },
temperatureC: { type: "number" },
condition: { type: "string" },
},
required: ["city", "temperatureC", "condition"],
},
execute: async ({ city }) => ({
city,
temperatureC: 24,
condition: "sunny",
}),
});
await r.skills.register({
id: "weather-briefing",
name: "weather-briefing",
description: "How to report the weather: temperature first, then condition.",
body: "## Weather briefing\nAnswer in one sentence: temperature first, then the condition. No filler.",
});
// The three capability tools are the only tools your agent needs to see.
// Always all three — the set never depends on registration order.
const { search_capabilities, invoke_tool, get_skill_content } = r.modelTools();Run the discovery loop by hand
Append the exact calls a model makes at runtime, then run the file:
console.log(await search_capabilities.execute({ query: "weather in Rome" }));
console.log(await invoke_tool.execute({ toolId: "get_weather", args: { city: "Rome" } }));
console.log(await get_skill_content.execute({ skillId: "weather-briefing" }));npx tsx index.tsThree results, no model key involved:
search_capabilitiesreturns two independently-ranked buckets:get_weatherundertools,weather-briefingunderskills. Neither schema nor body entered any prompt to get there.invoke_toolruns the handler and returns its result untouched:{ city: "Rome", temperatureC: 24, condition: "sunny" }.get_skill_contentreturns the playbook:{ body: "## Weather briefing\n…" }.
The full result shapes and error contract are on Progressive disclosure tools.
Hand the loop to your agent
Using the Vercel AI SDK or Mastra? r.adaptTo(...) gives the same core a framework-shaped view through an official adapter — see Framework integrations.
Anywhere else, each capability tool is a plain ExecutableTool: { id, name, description, inputSchema, outputSchema, execute }. Map those fields onto your framework's tool type (a few lines), add the three tools to the agent's tool list, and tell it to search before answering:
Find tools and playbooks with search_capabilities. Run tools with invoke_tool.
When a skill matches, load it with get_skill_content and follow it.Host-driven ranking is there too: await r.recall(query) returns the canonical search_capabilities result (or null on no match) without going through the model. More on Use the discovery tools.
Migrate an existing agent
A migration changes where capabilities live, not your model or business logic. Start with one workflow, prove it still behaves the same, then repeat.
| Existing asset | After migration |
|---|---|
| Tool IDs, schemas, and handlers | Register once on r.tools; keep authorization and side effects in the handler. |
| Conditional runbooks and examples | Register on r.skills; load only when relevant. |
| Identity, safety, universal policy, output rules, and runtime context | Keep in the core prompt. |
| Model and agent loop | Keep both; reuse the loop's prompt and tool seams. |
Find the integration points
Find where your process creates long-lived dependencies and where each request builds the model's tool list. Create the ratel() core at startup; change the model-facing list at the request boundary.
Register an existing tool
Tool definitions leave the repeated model request, not your code. Preserve the ID, schema contract, handler, authorization, permissions, and side effects. Convert framework-native schemas to JSON Schema at this boundary.
// Before: the schema is sent to the model on every request
const toolsForEveryRequest = { issue_refund: existingRefundTool };
// After: the same contract is registered once at startup
const r = ratel();
await r.tools.register({
id: "issue_refund",
name: "issue_refund",
description: "Issue an approved refund for an order.",
inputSchema: issueRefundInputSchema,
outputSchema: issueRefundOutputSchema,
execute: issueRefund, // the existing handler
});Register each tool in this workflow the same way — r.tools.register is variadic, so a batch is one call. During a gradual migration, leave unmigrated tools in the old list and remove each migrated definition from it.
Extract an on-demand skill
Keep instructions and runtime context that must govern every turn in the core prompt. Move only conditional guidance, such as the refund workflow, into a self-contained skill:
// Before: the refund workflow is sent on every turn
const instructions = [
CORE_PROMPT,
SAFETY_POLICY,
OUTPUT_RULES,
RUNTIME_CONTEXT,
REFUND_RUNBOOK,
].join("\n\n");
// After: everything except the runbook stays in the core prompt
const coreInstructions = [
CORE_PROMPT,
SAFETY_POLICY,
OUTPUT_RULES,
RUNTIME_CONTEXT,
].join("\n\n");
await r.skills.register({
id: "refund-runbook",
name: "refund-runbook",
description: "Check refund eligibility, obtain approval, then issue the refund.",
tools: ["issue_refund"],
body: REFUND_RUNBOOK,
});The description says when to load the skill. Its tools list surfaces issue_refund beside the matched playbook.
Rewire and verify the agent
Add the discovery policy to the core prompt, then hand the agent the capability tools at the request boundary:
const discoveryInstructions = `
Find tools and playbooks with search_capabilities. Run tools with invoke_tool.
When a skill matches, load it with get_skill_content and follow it.
`.trim();
const instructions = [coreInstructions, discoveryInstructions].join("\n\n");
const capabilityTools = r.modelTools();The capability tools are plain ExecutableTool values; Framework integrations has the official adapters and the hand-rolled recipe.
A refund request should now follow this path:
search_capabilitiesreturnsrefund-runbookandissue_refund.get_skill_contentloads the eligibility and approval steps.invoke_toolcalls the unchangedissueRefundhandler.- The agent answers from the tool result.
Before migrating the next workflow, verify the skill ranks, its declared tool appears, the handler receives the same arguments, and the initial request excludes the full catalog and refund runbook.
Let a coding agent do the migration
The skills suite ships skills for Claude Code, Cursor, Codex, and
similar: ratel-integrate plans this migration for your codebase, and
ratel-decompose-prompt splits the system prompt into skills.
Next steps
Framework integrations
Official adapters for the Vercel AI SDK and Mastra, and the recipe for any other loop.
Skillset
Coding-agent skills that assess your codebase and apply this integration for you.
Register tools
The anatomy of an executable tool, the full r.tools surface, and ranking without execution.
Register skills
The full skill-catalog surface: tags, declared tools, and how skills rank.
Install
Install @ratel-ai/sdk: requirements, prebuilt native targets, optional packages, and the embedding model download.
Register tools
Define executable tools, register a batch in one r.tools.register call, search and invoke through the guarded handle, and drop to the shared ToolCatalog or ToolRegistry underneath.