SDKs & Tooling

Chidori ships as a single Rust binary. There are two SDKs — a TypeScript SDK (npm) and a Python SDK (pure stdlib, no deps) — both pure HTTP clients to a running chidori serve. Tools live in .ts files next to your agents. This page covers what you install and how the pieces fit together.

Project layout

A typical Chidori project:

my-project/
├── agents/             # .ts agent files
│   ├── summarizer.ts
│   └── webhook.ts
├── prompts/            # Jinja templates
│   └── research.jinja
├── tools/              # .ts tool files
│   └── search.ts
└── examples/
    └── legacy-starlark/   # archived .star agents

The runtime looks for agents in agents/, tools in tools/, and prompts in prompts/ relative to the project root. Legacy .star agents are archived under examples/legacy-starlark/.

The CLI

chidori run    [--input key=value]... [--stream] [--trace] [--replay session.json]
chidori check 
chidori tools [--dir ]...
chidori serve  [--port 8080]
chidori demo
chidori trace    
chidori snapshot 

Install the runtime with cargo install chidori (or cargo build from source).

Input formats for run:

  • --input key=value — string value
  • --input key=@file.txt — read the value from a file
  • --input '{"key": "value"}' — JSON object merged into inputs

Provider environment variables:

  • ANTHROPIC_API_KEY — use Anthropic directly (claude-* models)
  • OPENAI_API_KEY — use OpenAI directly (gpt-*, o1-*, o3-*)
  • LITELLM_API_URL + LITELLM_API_KEY — use a LiteLLM proxy (or any OpenAI-compatible endpoint) as a catch-all

Defining tools

A tool is a .ts module that exports tool metadata — a ToolDefinition with a name, description, and a JSON Schema for its parameters — alongside export async function run(args, chidori). The metadata is what the model sees for function-calling; run is what executes.

tools/search.ts

export const tool = {
  name: "web_search",
  description: "Search the web and return results.",
  parameters: {
    type: "object",
    properties: {
      query:       { type: "string" },
      maxResults:  { type: "number", default: 5 },
    },
    required: ["query"],
  },
}

export async function run(args, chidori) {
  const response = await chidori.http("https://api.search.example/search", {
    query: { q: args.query, limit: args.maxResults ?? 5 },
  })
  return response.results
}

tools/analyze.ts

export const tool = {
  name: "analyze",
  description: "Run heavy analysis via external service.",
  parameters: {
    type: "object",
    properties: { data: { type: "object" } },
    required: ["data"],
  },
}

export async function run(args, chidori) {
  return chidori.http("http://localhost:9000/analyze", {
    method: "POST",
    body: { data: args.data },
  })
}

For tools that need native libraries, wrap an external service over HTTP — it keeps the tool surface simple and side effects visible in the call log. MCP-backed remote tools are also supported.

List registered tools:

chidori tools --dir tools/

The TypeScript SDK

The TypeScript SDK is published to npm and is a pure HTTP client to a running chidori serve.

import { AgentClient, Checkpoint } from "chidori";

const client = new AgentClient("http://localhost:8080");

// Run an agent — live LLM calls
const session = await client.run({ document: "Rust is great." });
console.log(session.output);   // { summary: "...", actionItems: "..." }
console.log(session.status);   // "completed"

// Save and replay
await session.checkpoint().save("session.json");
const replayed = await client.replay(await Checkpoint.load("session.json"));

// List sessions on the server
for (const s of await client.listSessions()) {
  console.log(s.id, s.status);
}

The Python SDK

The Python SDK is pure stdlib — no pip install, no native bindings, no dependencies. It's the same HTTP client surface, talking to a running chidori serve.

from chidori import AgentClient, Checkpoint

client = AgentClient("http://localhost:8080")

# Run an agent — live LLM calls
session = client.run({"document": "Rust is great."})
print(session.output)   # {"summary": "...", "action_items": "..."}
print(session.status)   # "completed"

# Save and replay
checkpoint = session.checkpoint()
checkpoint.save("session.json")

cp       = Checkpoint.load("session.json")
replayed = client.replay(cp)
assert replayed.output == session.output

# Iterate over many documents
for doc in documents:
    s = client.run({"document": doc})
    s.checkpoint().save(f"checkpoints/{s.id}.json")

# List sessions on the server
for s in client.list_sessions():
    print(s["id"], s["status"])

The Rust runtime

If you need to embed Chidori in a larger Rust service, the runtime is a library crate. The chidori CLI binary is a thin wrapper around it. See the Rust API docs for the RuntimeContext and HostFunction traits if you want to add new host functions or swap the LLM provider layer.

Output format

Agent output is always JSON on stdout — whatever your agent function returns, serialized:

  • Objects → JSON objects
  • Arrays → JSON arrays
  • Strings → JSON strings
  • Numbers → JSON numbers
  • Booleans → JSON booleans
  • null / undefined → JSON null

Traces and diagnostics go to stderr, so you can pipe stdout into jq cleanly:

chidori run agents/summarizer.ts --input document=@notes.txt | jq '.summary'

Was this page helpful?