Agent SDK
The Agent SDK is the same agent loop that powers Nexrall Code (VS Code) and the Nexrall CLI, published as standalone npm packages so you can embed a coding agent inside your own Node.js application, tool, or internal automation, instead of using it through the CLI or the editor extension.
There are two packages, at two different levels:
| Package | What it is | Use it if |
|---|---|---|
@nexrall/agent | An ergonomic, stateful runtime — createAgent(), delegate(), resume(), and friends | You want a working agent in a few minutes and don't need to manage the agent loop's plumbing yourself. Start here. |
@nexrall/code-core | The low-level, stateless primitives @nexrall/agent itself is built on | You're building your own framework-level integration and need full control over every callback, or you need a primitive @nexrall/agent doesn't expose yet |
Who this page is for
This is developer-facing SDK documentation, not something you need for normal day-to-day use of Nexrall. If you just want an AI coding agent in your terminal or editor, see the Nexrall CLI or Nexrall Code for VS Code instead.
@nexrall/agent quick start
npm install @nexrall/agentRequires Node.js ≥ 18. Uses your Nexrall account for authentication — set NEXRALL_TOKEN, or it picks up the same login the CLI/VS Code extension already use (see Authentication below).
import { createAgent } from '@nexrall/agent';
const agent = createAgent({ workDir: process.cwd(), model: 'claude-sonnet-5' });
agent.observe({
onText: (t) => process.stdout.write(t),
onToolUse: (name) => console.error(`[tool] ${name}`),
});
const result = await agent.run('Refactor the auth module to use async/await.');
console.log(result.text);That's it — agent is a stateful object that holds the conversation, its MCP connections, and a checkpoint scope between calls, so a second agent.run(...) continues the same session instead of starting fresh.
What else it can do
| Method | What it's for |
|---|---|
agent.registerAgentType(name, def) | Define a sub-agent as a plain object — no .nexrall/agents/*.md file needed |
agent.registerSkills(skills) | Bundle a reusable skill inside your own npm package |
agent.connectMCP(config) | Connect to MCP servers — pass a workDir or an inline server map |
agent.delegate(req) / agent.spawn(req) | Dispatch a sub-agent (blocking or fire-and-observe), with the same depth/budget/concurrency limits the task tool itself enforces |
agent.resume(id, prompt) | Continue a previously-delegated sub-agent without re-describing the whole job |
agent.rewind(turnId?) | Roll back file edits + conversation to an earlier point |
agent.registerAgentType('reviewer', {
description: 'Reviews code. Read-only.',
tools: ['read_file', 'search_files'],
prompt: 'You are a strict code reviewer...',
});
const review = await agent.delegate({ agent: 'reviewer', prompt: 'Review the latest diff' });
console.log(review.output);
// Continue that same sub-agent later, keeping everything it already read:
const followUp = await agent.resume(review.id, 'Also check the error paths');Sessions are process-lifetime only
delegate()/spawn() return an id you can pass to resume() — but that id is backed by an in-memory registry, by deliberate design (a sub-agent's transcript is unredacted tool output, and persisting it would create a durable copy of material nobody asked to store). It's resumable only within the process that created it, not across a restart. If you need durability, persist agent.messages yourself.
Not implemented yet
agent.connectA2A(...) — for agent-to-agent delegation across organizational boundaries — throws an explicit error today. NAP (the Nexrall Agent Protocol) is still a design document, not shipped code.
See the @nexrall/agent package README for the full API reference.
@nexrall/code-core — the low-level primitives
@nexrall/code-core is what @nexrall/agent itself is built on: a deliberately low-level, stateless API where runAgentLoop() takes a full options object every call, and MCP/checkpoints/sub-agents are separate classes you wire up by hand. Reach for it directly if you're building your own framework-level integration around the agent loop rather than embedding an agent quickly.
Install
npm install @nexrall/code-coreRequires Node.js ≥ 18. Uses your Nexrall account for authentication — the same login the CLI and VS Code extension use (see Authentication below).
What's inside
The package is split into focused sub-modules so you only pull in what you need:
| Import | What it gives you |
|---|---|
@nexrall/code-core | Everything, via the root export. |
@nexrall/code-core/agent | runAgentLoop — the main agent loop. |
@nexrall/code-core/tools | executeTool — the built-in tool executor (file edits, shell commands, search, and more). |
@nexrall/code-core/symbols | getSymbols, getWorkspaceSymbols — a lightweight code-navigation scanner. |
@nexrall/code-core/checkpoint | CheckpointManager — persistent rewind/rollback of file edits. |
@nexrall/code-core/commands | loadSlashCommands, expandCommand — custom slash-command support. |
@nexrall/code-core/plugins | loadPlugins, pluginHooks, pluginMcpServers — the plugin system. |
@nexrall/code-core/permissions | loadSettings, evaluatePermission — the permission rules that decide what needs approval. |
@nexrall/code-core/mcp | McpManager — connects to MCP (Model Context Protocol) servers. |
@nexrall/code-core/api | streamChat — the low-level streaming chat client. |
@nexrall/code-core/types | Shared TypeScript types. |
Quick start
import { runAgentLoop } from '@nexrall/code-core/agent';
import type { AgentLoopOptions } from '@nexrall/code-core';
const messages = [
{
role: 'user',
content: [{ type: 'text', text: 'List the files in src/ and summarize what this project does.' }],
},
];
const options: AgentLoopOptions = {
model: 'claude-sonnet-5', // any model id — see /developers/models
workDir: process.cwd(),
env: { platform: 'node', cwd: process.cwd(), shell: 'bash' },
clientType: 'cli',
mode: 'auto',
onText: (text) => process.stdout.write(text),
onThinking: () => {},
onThinkingDelta: () => {},
onThinkingProgress: () => {},
onToolUse: (name, input) => console.error(`[tool] ${name}`, input),
onToolResult: (name, result) => console.error(`[result] ${name}`, result.error ?? 'ok'),
onInjectedInput: () => {},
onUsage: () => {},
requestPermission: async () => true, // auto-approve every tool call
};
const history = await runAgentLoop(messages, options);
console.log('Done —', history.length, 'messages in the conversation.');The agent streams through the Nexrall API in the background — your code just supplies messages and callbacks; the loop itself handles planning, tool calls, retries, and context management.
Authentication
The agent runs against your Nexrall account. Set a token as an environment variable — the recommended way for anything non-interactive (a script, a server, a CI job):
export NEXRALL_TOKEN=<token>Get a token by signing in once through the Nexrall CLI or the VS Code extension; the token behaves exactly like your normal account (same balance, same permissions) — there is no separate "API-only" tier.
Key options
interface AgentLoopOptions {
model: string; // a model id like 'claude-sonnet-5' | 'gpt-5.4' | 'deepseek-v4-pro'
workDir: string; // the directory the agent reads/edits
mode?: 'auto' | 'ask' | 'edit' | 'plan';
effort?: 'low' | 'medium' | 'high' | 'extra';
nexrallMd?: string; // project-specific instructions, same as CLI's nexrall.md
maxIterations?: number; // default 500, auto-continues to 2000 by default; an explicit value has no upper bound
autoContinue?: boolean; // keep going when mid-task (default: true)
autoCompact?: boolean; // auto-summarize old history near the context limit (default: true)
checkpointManager?: CheckpointManager;
mcpManager?: McpManager;
// Stream callbacks — how you observe what the agent is doing
onText, onThinking, onToolUse, onToolResult, onUsage: (...) => void;
// Called for every tool call that needs a yes/no — return true to allow it
requestPermission: (req: PermissionRequest) => Promise<boolean>;
}mode: 'plan' is enforced at the tool-execution level, not just as an instruction to the model — every write-capable tool is hard-blocked while in Plan mode, the same guarantee both the CLI and VS Code extension rely on.
Checkpoints (rewind)
import { CheckpointManager } from '@nexrall/code-core/checkpoint';
const checkpoints = new CheckpointManager(workDir, sessionId);
checkpoints.beginTurn('refactor auth module', messages.length);
// ... the agent runs and edits files ...
checkpoints.commitTurn();
// Roll back both the files and the conversation to an earlier point:
const result = checkpoints.restore(checkpoints.list()[0].id);If a rewound turn ran shell commands, result.bashCount tells you how many of those side effects were not automatically undone, and result.gitStashHashes gives you a recovery point if it touched a git repo.
Plugins
The same plugin format the CLI and VS Code extension use — a folder of custom commands, sub-agents, and hooks — is loadable directly:
import { loadPlugins, pluginHooks, pluginMcpServers } from '@nexrall/code-core/plugins';
const plugins = loadPlugins(process.cwd());See Plugins for the full plugin format.
Which one should you use?
- Use the CLI if you just want to run the agent from a script or CI step —
nex --output-format jsoncovers almost every scripting need without writing any code at all. - Use
@nexrall/agentif you're embedding an agent in your own application and want the ergonomic, stateful API —createAgent(),delegate(),resume()— without wiring up the loop's plumbing yourself. This is the right default for most integrations. - Use
@nexrall/code-coredirectly if you're building your own framework-level integration — a custom UI, a different automation runner, or a product that needs full control over every callback and permission decision that@nexrall/agentdoesn't expose.