Skip to content

Embed it

Embed the runtime

@arcturn/core is the same event-driven agent the arcturn CLI is built on — one Agent per session, one AgentEvent stream out. No terminal required.

agent.ts
import { createAgent } from "@arcturn/core";
import { createClient, requireModel } from "@arcturn/ai";
import { createDefaultTools } from "@arcturn/tools";

const llm = createClient(); // resolves API keys from the environment
const { tools } = createDefaultTools({ cwd: process.cwd() });

const agent = createAgent({
  llm,
  model: requireModel("anthropic/claude-sonnet-4-5"),
  systemPrompt: "You are a focused, careful coding agent.",
  tools,
  cwd: process.cwd(),
  sessionDir: ".arcturn/sessions", // omit for an unpersisted, in-memory agent
  permissions: { mode: "default" },
});

await agent.prompt("Add input validation to the signup handler");
console.log(agent.finalText());

What you get

Everything the terminal agent has, as a library.

There is no separate embedding API. The TUI, the HTTP server and --output-format json are all just different consumers of the same Agent.

The agent loop and steering

One Agent per session, options in and events out. agent.prompt() resolves when the model stops calling tools; steer() injects text mid-run.

The same permission engine

PermissionEngine with rules, scopes and modes, wired from code — plus a PermissionRequester callback for your own UI, and the plan-mode exit gate.

Sessions that branch

JsonlSessionStore or MemorySessionStore behind one SessionStore interface: resume a branch, fork from an older entry, force compaction.

Custom tools

A JSON-Schema definition and an execute contract, with an abort signal, a permission callback and an incremental progress channel in context.

Sub-agents and MCP bridging

Delegate to child agents whose whole event stream re-publishes on the parent, and bridge MCP server tools into ordinary Tool objects.

VCR record/replay and cost

Record a cassette of stream events and tool results, replay it hermetically, and read per-turn usage and cost off the same stream.

The event stream

One subscription, every event.

Subscribe once and you have what the TUI renders, what the server forwards, and what the CLI prints as NDJSON — the same union, in the same order.

const off = agent.subscribe((event) => {
  if (event.type === "toolEnd") {
    console.log(event.result.isError ? "✗" : "✓", event.toolCallId);
  }
});
// off() to unsubscribe

agent.on("runEnd", (event) => {
  switch (event.reason) {
    case "completed":
      break; // normal
    case "aborted":
      break; // agent.abort() was called, or the external signal fired
    case "error":
      console.error(event.errorMessage); // model, provider, or a thrown hook
      break;
  }
});
arcturn -p '…' --output-format json
{"type":"turnStart","turn":1}
{"type":"toolCallStart","toolCallId":"tc_1","toolName":"grep","input":{"pattern":"TODO"}}
{"type":"toolCallEnd","toolCallId":"tc_1","result":{"content":[{"type":"text","text":"…"}]}}
{"type":"runEnd","reason":"completed"}

Runs never reject. agent.prompt() resolves when the model stops calling tools, the run is aborted, or a runtime error occurs — the outcome always arrives as a terminal runEnd event instead, so failure handling lives in one place. Listener exceptions are swallowed by the agent: one bad subscriber can never break a run.

Package map

Eleven packages, split by concern.

The runtime is split by concern and each piece has its own dependency surface — @arcturn/types, core, index and protocol carry no external runtime dependencies at all.

@arcturn/types
Zero-dependency shared contracts (messages, events, tools, permissions, sessions, protocol)
@arcturn/ai
Unified multi-provider LLM streaming client with model catalog and retry
@arcturn/core
Agent runtime: event loop, steering, sessions, compaction, permissions, sub-agents
@arcturn/tools
Built-in tools: read, write, edit, bash (+background), grep, glob, ls, fetch
@arcturn/mcp
Model Context Protocol client bridge
@arcturn/tui
Terminal UI library with differential rendering
@arcturn/index
Token-optimized code index and BM25 semantic search
@arcturn/protocol
NDJSON wire protocol for server mode
@arcturn/server
WebSocket server exposing agent sessions to remote clients
@arcturn/evals
Task-level eval harness: real coding tasks with programmatic assertions
arcturn
The interactive coding agent, workflow engine, and agent-org runtime

Every turn counts.

The SDK docs start where this page stops: every option, every event, and a worked custom tool.