Quickstart
Install @ratel-ai/sdk, put your tools and prompt playbooks in Ratel catalogs, 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 a ToolCatalog: register each of your tools once, pairing its metadata (id, description, JSON schemas) with the handler that runs it. A SkillCatalog holds Markdown playbooks the same way, ranked in their own corpus.
The agent reaches both through the three capability tools — 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@0.4.0
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 {
SkillCatalog,
ToolCatalog,
getSkillContentTool,
invokeToolTool,
searchCapabilitiesTool,
} from "@ratel-ai/sdk";
const catalog = new ToolCatalog();
catalog.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",
}),
});
const skills = new SkillCatalog();
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.
// Construct them after registering, so the skills bucket is advertised.
const search = searchCapabilitiesTool(catalog, skills); // id: "search_capabilities"
const invoke = invokeToolTool(catalog); // id: "invoke_tool"
const load = getSkillContentTool(skills); // id: "get_skill_content"Run the discovery loop by hand
Append the exact calls a model makes at runtime, then run the file:
console.log(await search.execute({ query: "weather in Rome" }));
console.log(await invoke.execute({ toolId: "get_weather", args: { city: "Rome" } }));
console.log(await load.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.
Hand the loop to your agent
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 anywhere), 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.Ready-made wiring — the Vercel AI SDK adapter and per-turn assembly — is on Framework integrations. Production agents usually add a top-K pre-filter next to the capability tools; that pattern is 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 in ToolCatalog; keep authorization and side effects in the handler. |
| Conditional runbooks and examples | Register in SkillCatalog; 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 catalogs 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 catalog = new ToolCatalog();
catalog.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. 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");
const skills = new SkillCatalog();
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. After both catalogs are populated, build the three Ratel capability tools and adapt them 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 = [
searchCapabilitiesTool(catalog, skills),
invokeToolTool(catalog),
getSkillContentTool(skills),
];The capability tools are plain ExecutableTool values. Framework integrations shows the adapter and the production top-K turn assembler.
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
Ready-made wiring for the Vercel AI SDK — and the recipe for any other loop.
Skills suite
Coding-agent skills that assess your codebase and apply this integration for you.
Register tools
The anatomy of an executable tool, the full ToolCatalog surface, and ranking without execution.
Register skills
The full SkillCatalog surface: tags, declared tools, and how skills rank.