Skip to content

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:

PackageWhat it isUse it if
@nexrall/agentAn ergonomic, stateful runtime — createAgent(), delegate(), resume(), and friendsYou want a working agent in a few minutes and don't need to manage the agent loop's plumbing yourself. Start here.
@nexrall/code-coreThe low-level, stateless primitives @nexrall/agent itself is built onYou'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

sh
npm install @nexrall/agent

Requires 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).

ts
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

MethodWhat 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
ts
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

sh
npm install @nexrall/code-core

Requires 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:

ImportWhat it gives you
@nexrall/code-coreEverything, via the root export.
@nexrall/code-core/agentrunAgentLoop — the main agent loop.
@nexrall/code-core/toolsexecuteTool — the built-in tool executor (file edits, shell commands, search, and more).
@nexrall/code-core/symbolsgetSymbols, getWorkspaceSymbols — a lightweight code-navigation scanner.
@nexrall/code-core/checkpointCheckpointManager — persistent rewind/rollback of file edits.
@nexrall/code-core/commandsloadSlashCommands, expandCommand — custom slash-command support.
@nexrall/code-core/pluginsloadPlugins, pluginHooks, pluginMcpServers — the plugin system.
@nexrall/code-core/permissionsloadSettings, evaluatePermission — the permission rules that decide what needs approval.
@nexrall/code-core/mcpMcpManager — connects to MCP (Model Context Protocol) servers.
@nexrall/code-core/apistreamChat — the low-level streaming chat client.
@nexrall/code-core/typesShared TypeScript types.

Quick start

ts
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):

sh
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

ts
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)

ts
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:

ts
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 json covers almost every scripting need without writing any code at all.
  • Use @nexrall/agent if 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-core directly 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/agent doesn't expose.

Built by Maxrall, Inc.