Docs
Node Adapter
NodeAgent runs against real files: point it at a working directory and it gets the full file toolset plus a Bash tool that runs sandboxed and can escalate to the host shell with approval. Build CLIs, servers, bots, and scripts.
npm install @nanocodana/nodejs @ai-sdk/anthropic aiimport { NodeAgent } from '@nanocodana/nodejs'
import { anthropic } from '@ai-sdk/anthropic'
const agent = NodeAgent({
model: anthropic('claude-sonnet-5'),
workingDirectory: process.cwd(),
needsApproval: ['Write', 'Edit', 'MultiEdit', 'Delete'],
})
const result = await agent.stream({
messages: [{ role: 'user', content: 'Add a CHANGELOG.md summarizing recent commits.' }],
})Default tools#
The Node agent ships with Read, Write, Edit, MultiEdit, Delete, Glob, Grep, LS, TodoWrite, WebFetch, and a Bash tool that runs in a sandbox and can escalate to the host shell (with approval). The full list, with behavior notes, is in Built-in Tools.
The working directory#
workingDirectory is the root for every file tool — paths the model uses are resolved against it, and the agent can't wander outside. Skills are auto-discovered beneath it too, from .agents/skills/ and .claude/skills/.
The rule of thumb: this adapter is for files on a real disk — your laptop, a server, or a serverless function's own filesystem. If the files live anywhere else (a database, blob storage, a remote sandbox), that's core.
Search: ripgrep when possible, JS everywhere else#
Grep picks the best available engine at construction, automatically. Installing @nanocodana/nodejs brings real ripgrep along as an optionalDependency (npm fetches just the ~4 MB binary for your platform), and the agent resolves in order:
- the bundled
@vscode/ripgrepbinary, - a system
rgon PATH, - a zero-dependency JS search — ignore-aware (honors
.gitignore, skipsnode_modules, build output, and binary files) and capped.
A missing binary can only make searches slower, never break the agent — environments that skip optional dependencies or install scripts land safely on the JS engine. To force a specific engine, override the tool (entries in tools replace built-ins by name):
import { NodeAgent, createNodeGrepTool, createRipgrepTool } from '@nanocodana/nodejs'
const cwd = process.cwd()
const agent = NodeAgent({
model,
workingDirectory: cwd,
tools: { Grep: createNodeGrepTool(cwd) }, // force the JS engine
// tools: { Grep: createRipgrepTool(cwd) }, // force ripgrep
})The Bash sandbox#
Shell commands run in a virtual sandbox by default — fast, contained, and free of side effects on your machine. When the model genuinely needs the host (installing a dependency, running your test suite), it requests escalation with host: true, which always requires approval regardless of your needsApproval config.
Size#
Bundled, a Node agent is 3.58 MB (1.02 MB gzipped) — or a 387 kB entry chunk with code splitting, since each shell command loads on first use. That's what reaches production.
On disk, node_modules is bigger — 141 MB — because the shell brings wasm runtimes it loads on demand: a compiled CPython, SQLite, a JS interpreter. That's a build-time cost, not a deployed one, and it's payload rather than code: 80 of the ~83 commands are pure JavaScript under 2 MB. If it matters, --omit=optional takes it to 131 MB, and deleting just-bash/vendor saves another 10 MB unless you set python: true.