Documentation

The NanoAgent handbook

NanoAgent is an AI coding agent that works directly inside a repository while respecting local permissions, approval prompts, and workspace policy. It runs as a desktop app, the nanoai terminal command, a VS Code extension, a Visual Studio extension, and an ACP-compatible editor server. This is the full handbook for installation, daily use, safety controls, integration, automation, and advanced customization.

Install

Desktop app

Download the latest release for your platform:

PlatformDownload
Windows x64Installer
Linux x64Zip
Linux arm64Zip
macOS x64Zip
macOS arm64Zip

Release downloads are published at:

https://github.com/rizwan3d/NanoAgent/releases/latest

New release assets include SHA256SUMS beside the downloads. The release pipeline verifies every checksum matches its asset before publishing, and GitHub release workflows also generate artifact attestations that establish SLSA build provenance for the checksummed assets. For manual downloads, compare the published SHA256 hash with your downloaded file before running it. To verify provenance with GitHub CLI, run gh attestation verify path/to/asset -R rizwan3d/NanoAgent.

CLI

Install with the release installer.

Curl

curl -fsSL https://raw.githubusercontent.com/rizwan3d/NanoAgent/master/scripts/install.sh | bash

Windows PowerShell

irm https://raw.githubusercontent.com/rizwan3d/NanoAgent/master/scripts/install.ps1 | iex

NPM

npm install -g nanoai-cli

pnpm

pnpm add -g nanoai-cli

bun

bun add -g nanoai-cli

The installers show step status and download progress when run in an interactive terminal. Set NANOAGENT_NO_PROGRESS=1 to keep output compact in CI logs. Restart your terminal if nanoai is not found immediately after installation.

The release workflows also pack the NanoAgent library and publish it to NuGet.org for every v* tag release. The CLI is distributed only as a release installer, not as a NuGet package.

The CLI install scripts verify the archive checksum against SHA256SUMS, or the SHA256 digest from GitHub release metadata, before extraction. Checksum verification is mandatory — installation fails if the checksum cannot be validated.

First run & provider setup

Start NanoAgent:

nanoai

NanoAgent will guide you through provider setup:

  1. Choose a setup type: subscription account, API key provider, OpenAI-compatible provider, or local provider.
  2. Choose a provider from the matching submenu when needed.
  3. Enter an API key, sign in with ChatGPT Plus/Pro, Claude Pro/Max, or GitHub Copilot, enter a custom compatible base URL, or use a local provider default.
  4. Let NanoAgent discover available models.
  5. Open a desktop workspace or use the current terminal directory.
  6. Start a new section or resume an existing one.

In terminal runs, --provider-auth-key <key> can supply the provider API key when onboarding asks for it.

Headless / preseeded setup

If you already know the provider settings you want, skip the interactive onboarding by setting NANOAGENT_PROVIDER, NANOAGENT_MODEL, NANOAGENT_THINKING, optional NANOAGENT_REASONING, and NANOAGENT_API_KEY before the first run. NanoAgent treats that as a complete headless setup and saves it as the active provider profile.

PowerShell example

$env:NANOAGENT_PROVIDER="openrouter"
$env:NANOAGENT_MODEL="poolside/laguna-m.1:free"
$env:NANOAGENT_THINKING="on"
$env:NANOAGENT_REASONING="high"
$env:NANOAGENT_API_KEY="PASTE_NEW_ROTATED_KEY_HERE"

nanoai -p "Say hello in one short line"

Bash example

export NANOAGENT_PROVIDER="openrouter"
export NANOAGENT_MODEL="poolside/laguna-m.1:free"
export NANOAGENT_THINKING="on"
export NANOAGENT_REASONING="high"
export NANOAGENT_API_KEY="PASTE_NEW_ROTATED_KEY_HERE"

nanoai -p "Say hello in one short line"

If NanoAgent detects incomplete local provider setup, it asks whether to reconfigure. Choose reconfigure when a previous setup was interrupted or credentials were not saved. If provider validation fails after setup, NanoAgent offers to run onboarding again.

Use /onboard in an active desktop or terminal session to re-run provider setup later. You can also use /setting provider or the /setting picker. The command opens setup-type and provider submenus, supports every provider listed below, and switches the active session to the validated provider and selected default model.

When a newer NanoAgent release is available, startup can ask whether to update now or skip. One-shot prompt runs do not show the startup update prompt.

Provider options

GroupProviderCredentialNotes
SubscriptionOpenAI ChatGPT Plus/ProBrowser sign-inOAuth with local callback port 1455.
SubscriptionAnthropic Claude Pro/MaxBrowser sign-inOAuth with local callback port 53692.
SubscriptionGitHub CopilotBrowser device sign-inGitHub device-code login. Leave the Enterprise URL/domain prompt blank for github.com.
API keyOpenAIAPI keyUses the OpenAI API.
API keyAnthropicAPI keyUses the Anthropic OpenAI-compatible endpoint.
API keyGoogle AI StudioAPI keyUses the OpenAI-compatible Gemini endpoint.
API keyOpenRouterAPI keyUses the OpenRouter OpenAI-compatible endpoint.
API keyKilo CodeAPI keyUses Kilo's OpenRouter-compatible gateway.
API keyCerebrasAPI keyUses the Cerebras OpenAI-compatible endpoint.
API keyGroqAPI keyUses the Groq OpenAI-compatible endpoint.
API keyDeepSeekAPI keyUses the DeepSeek OpenAI-compatible endpoint at https://api.deepseek.com/.
API keyOllama CloudAPI keyUses Ollama's hosted native chat and tags APIs.
OpenAI-compatibleOpenAI-compatible providerBase URL + API keyUse for local or third-party compatible APIs.
LocalOllamaNoneLocal OpenAI-compatible endpoint at http://127.0.0.1:11434/v1.
LocalLM StudioBase URL + API keyLeave the base URL empty to use http://127.0.0.1:1234/v1.

Secrets are stored through platform credential storage where supported. ChatGPT Plus/Pro, Claude Pro/Max, and GitHub Copilot sign-in store refreshable account credentials locally.

Desktop workflow

The desktop app is built around workspaces, sections, chat, and controls.

Workspaces

Open a local folder to make it the active workspace. NanoAgent remembers recent workspaces so you can return later.

Sections

A section is a saved local conversation thread tied to a workspace. Sections preserve conversation history, active model, profile, thinking mode, plan state, and session state when available. Use separate sections for a feature, a bug fix, a review, and planning.

Conversation

Type a prompt and let NanoAgent inspect, plan, edit, run commands, or ask for approval depending on the active profile and permissions. Type / in the desktop prompt to open command suggestions; use Up/Down and Enter to choose a command, or Shift+Enter for multiline input.

Start input with ! to run the rest as a local shell command directly, for example !dotnet test. Direct shell input is treated as user-entered terminal work and does not ask the agent for a tool approval. Start input with !! to run the rest as a background terminal whose output streams live, for example !!dotnet watch. Manage these background terminals with /terminals.

Controls

  • Refresh session state.
  • Switch model.
  • Configure budget controls from a local workspace file or a cloud API.
  • Toggle thinking mode.
  • Switch profile.
  • View help, model picker, permissions, and rules.
  • Add permission overrides.
  • Undo or redo tracked file edits.

Budget controls

Budget controls are disabled by default. They become active only after you enable them with /budget local or /budget cloud, or when a .nanoagent/budget-controls.*.json file already exists in the active workspace. While disabled, no usage is recorded, no tracking file is created, and provider requests are never blocked; /budget status reports Disabled.

Budget controls can run in local mode or cloud mode. Local mode asks for the monthly budget USD, alert threshold percent, and input, cached-input, and output prices per 1M tokens, then creates and updates .nanoagent/budget-controls.local.json in the active workspace. Cloud mode asks for the budget API URL and auth key; the URL is saved with user settings and the key is stored through the platform credential store. In the terminal, use /budget, /budget local, /budget cloud, or /budget status.

Cloud budget APIs use Authorization: Bearer <auth-key>. GET returns the current budget state:

{
  "monthlyBudgetUsd": 100,
  "spentUsd": 25.5,
  "alertThresholdPercent": 80
}

POST receives only the tokens consumed by the last LLM call, adds that delta to the backend usage database, and returns the updated budget state with the same JSON shape as GET:

{
  "inputTokens": 1234,
  "cachedInputTokens": 250,
  "outputTokens": 600
}

Terminal workflow

Interactive mode

nanoai

Interactive mode opens the terminal UI with conversation history, live activity, prompts, and status.

One-shot prompt

nanoai "Find risky changes in this branch"

Prompt from standard input

git diff --stat | nanoai --stdin --profile review

Resume a session

When you exit, NanoAgent prints a session resume command. You can also resume directly:

nanoai --session <session-guid>

CLI options

OptionDescription
--acpRun an Agent Client Protocol server over stdin/stdout for compatible editors and tools.
--interactiveStart the terminal UI explicitly.
--stdinRead one-shot prompt text from standard input.
--jsonWrite one-shot prompt or command output as a JSON object.
-y, --yesApprove promptable tool requests for this run while preserving explicit deny rules.
-p, --prompt <text>Run one prompt and print the response.
--provider-auth-key <key>Use this key when provider API-key onboarding asks for a credential.
--session <id>Resume an existing session.
--section <id>Compatibility alias for --session.
--profile <name>Start with a profile.
--thinking <on|off>Start with thinking on or off.
-h, --helpShow CLI help.

Terminal input & keys

The interactive terminal UI adds keyboard controls for editing, navigating history, queueing work, and interrupting a running turn.

Queue prompts and commands

You no longer have to wait for the current turn to finish before lining up the next request. When NanoAgent is busy or streaming, pressing Enter queues the prompt or slash command instead of rejecting it. Queued items run automatically, in order, as soon as the active turn completes.

  • The busy status line shows how many requests are waiting, for example … - 2 queued.
  • A summary line under the input reports the queue depth and reminds you that F4 removes the newest queued item.
  • Press F4 while busy to drop the most recently queued submission.
  • Queued slash commands run only when NanoAgent is ready; commands that are unavailable while working stay queued until the turn finishes.

Interrupt a running or stuck turn

While a turn is running, the footer shows Esc: interrupt and Esc again: abandon.

  • Press Esc once to request a graceful interrupt. The status changes to Interrupting and NanoAgent cancels the active turn so the backend can stop cleanly.
  • Press Esc again if the turn does not stop promptly to abandon it locally. NanoAgent detaches from the turn, returns to Ready, and ignores any late output that arrives from the abandoned turn. Any queued submissions then start.

Edit and scroll

  • Ctrl+A selects all input text so you can replace or delete a draft in one step. Selected text is highlighted, and typing, Backspace, or Delete replaces the selection.
  • Auto-scroll pauses automatically when you scroll up to read earlier conversation history, so new streamed output does not yank you back to the bottom. Scrolling back to the bottom resumes auto-scroll.

Tab-complete file and directory paths

After a ! or !! shell command and a space, Tab completes file and directory paths from the workspace, the same way a normal terminal does. For example, !cat ./sr then Tab completes the typed path component while preserving the directory portion exactly as you typed it. Because shell commands usually take more arguments after a path, completing a path does not submit the command — it only fills in the path so you can keep typing. Completing a directory appends a trailing / so you can drill in further.

Terminal commands

CommandDescription
/helpList commands and usage.
/budget [status|local|cloud]Show or configure budget controls.
/configShow provider, model, profile, thinking mode, reasoning effort, and reasoning-output behavior.
/modelsChoose the active model with the arrow-key picker.
/use <model>Switch directly to a model id.
/onboardRe-run provider onboarding through setup-type and provider submenus, then switch the active session.
/profile <name>Switch the active profile.
/thinking [on|off]Show or set simple thinking mode.
/reasoning [show|<none|minimal|low|medium|high|xhigh|max>]Show or set provider reasoning effort.
/tooloutput [compact|full|auto]Toggle whether tool results print complete output or a compact preview. auto follows the active profile.
/permissionsShow permission summary and override guidance.
/rulesShow effective permission rules in evaluation order.
/setting […]Open the settings picker or jump directly to a settings area (model, profile, thinking, provider, budget, workspace, permissions, tools, summary).
/allow <tool-or-tag> [pattern]Add a session allow override.
/deny <tool-or-tag> [pattern]Add a session deny override.
/mcpShow MCP servers, custom tool providers, and dynamic tools.
/terminals [stop <id>|stop all]List or stop background terminals for the current session.
/init [recommended|minimal|custom]Choose and initialize workspace-local NanoAgent files.
/update [now]Check for updates. Use /update now to install without another prompt.
/undoRoll back the most recent tracked edit transaction.
/redoRe-apply the most recently undone edit transaction.
/exitExit the interactive shell.

Terminal utility commands also include /clear, /ls, and /read <file>.

Custom slash commands

Project commands live in .nanoagent/commands/*.md. User commands live in ~/.nanoagent/commands/*.md. Subdirectories create namespaces with :, so .nanoagent/commands/review/security.md is available as /review:security. Each command file can include front matter:

---
name: security-review
description: Review changed files for security risks
args: ["scope"]
---

Review $scope for authentication, injection, secrets, unsafe deserialization, and permission bypasses.
Return findings by severity.

Run commands with any arguments after the name:

/security-review latest diff
/fix-tests NanoAgent.Tests
/release-check v0.0.16

Use $ARGUMENTS for the full argument string, or name positional arguments in args and reference them as $scope or ${scope}. Project commands override user commands with the same name. Built-in command names are reserved.

Press F2 in the terminal UI to choose the active model with the arrow-key picker. Type / to open command suggestions, then use Up/Down and Enter to choose. Start input with ! to run the rest as a local shell command directly, for example !git status --short.

Tool runtime settings

Workspace agent-profile.json can tune tool timeouts and background terminal retention:

{
  "Application": {
    "Tools": {
      "httpClientTimeoutSeconds": 0,
      "mcpRequestTimeoutSeconds": 0,
      "acpRequestTimeoutSeconds": 0,
      "agentOrchestrationTimeoutSeconds": 0,
      "defaultTimeoutSeconds": 180,
      "maxConcurrentBackgroundTerminalsPerSession": 4,
      "completedBackgroundTerminalTtlSeconds": 300,
      "toolOutput": "compact"
    }
  }
}

A value of 0 keeps the existing default behavior for each timeout setting. Set toolOutput to full/complete for full tool output or compact/preview for the capped preview; a per-agent profile's toolOutput front matter overrides it, and /tooloutput overrides both for the current session. Completed background terminals remain readable until completedBackgroundTerminalTtlSeconds expires; running background terminals are stopped when the NanoAgent process exits.

VS Code extension

NanoAgent includes a VS Code extension in NanoAgent.VsCode. It opens a NanoAgent chat view in the auxiliary bar and starts the local NanoAgent ACP process with nanoai --acp. Run nanoai once before using the extension so provider onboarding, credentials, and the default model are already configured.

Install from the Visual Studio Marketplace:

ext install rizwan3d.nanoagent

Marketplace item: marketplace.visualstudio.com/items?itemName=rizwan3d.nanoagent. GitHub releases also publish an installable NanoAgent.VsCode-<version>.vsix asset.

Extension commands

CommandPurpose
NanoAgent: Open ChatOpen the NanoAgent chat view.
NanoAgent: New ChatFocus the chat view for a new prompt.
NanoAgent: StartStart the local NanoAgent ACP process.
NanoAgent: StopStop the local NanoAgent ACP process.
NanoAgent: RestartRestart the local NanoAgent ACP process.
NanoAgent: Send SelectionSend the active editor selection as context.
NanoAgent: Explain SelectionAsk NanoAgent to explain the active selection.
NanoAgent: Send Current FileSend the full current editor file as context.
NanoAgent: Review Current FileAsk for a review of the current file.
NanoAgent: Review Git DiffAsk for a review of the current workspace Git diff.
NanoAgent: Plan ChangesPrefill a planning prompt.
NanoAgent: Apply Suggested ChangesAsk NanoAgent to apply the previous suggested change.
NanoAgent: Open LogsShow extension logs.
NanoAgent: Open SettingsOpen the extension settings surface.

Extension settings

SettingDefaultPurpose
nanoagent.commandnanoaiCommand used to start NanoAgent.
nanoagent.args["--acp"]Arguments passed to the NanoAgent CLI.
nanoagent.workingDirectoryworkspace rootWorking directory for the NanoAgent process.
nanoagent.autoStartfalseStart NanoAgent automatically when VS Code starts.
nanoagent.logLevelinfoExtension log level.

Build & package locally

cd NanoAgent.VsCode
npm ci
npm run lint
npm run package
npm run package:vsix

The package command creates an installable .vsix. Install a local package with:

code --install-extension nanoagent-<version>.vsix

Visual Studio extension

NanoAgent includes a Visual Studio extension in NanoAgent.VS. It opens a tool window inside Visual Studio and starts the local NanoAgent CLI over ACP. Before first use:

  • Install the NanoAgent CLI so nanoai.exe is available on PATH, or set an explicit CLI path in the NanoAgent Visual Studio options page.
  • Run nanoai once and complete provider onboarding.

Local build

Build the VSIX from a Developer PowerShell for Visual Studio:

msbuild NanoAgent.VS/NanoAgent.VS.csproj /restore /p:Configuration=Release /p:DeployExtension=false

The package is written to NanoAgent.VS/bin/Release/NanoAgent.VS.vsix.

ACP editor integration

NanoAgent can run as an Agent Client Protocol server:

nanoai --acp

ACP mode speaks line-delimited JSON-RPC on stdin/stdout, so compatible editors and tools can create NanoAgent sessions, send prompts, cancel active turns, and receive assistant message, plan, and tool progress updates. ACP does not open a network listener — it communicates only over the local child process stdin/stdout streams created by the host editor or tool.

Example editor server configuration:

{
  "agent_servers": {
    "NanoAgent": {
      "command": "nanoai",
      "args": ["--acp"]
    }
  }
}

To require ACP authentication, set a process-level token with either NANOAGENT_ACP_AUTH_TOKEN or a workspace profile:

{
  "Application": {
    "Acp": {
      "authenticationToken": "replace-with-a-long-random-token"
    }
  }
}

When an ACP authentication token is configured, initialize returns "authMethods": ["token"]. The client must then call authenticate with {"token":"..."} before sending session/new, session/load, session/prompt, or session/close. If no token is configured, authMethods is empty and authenticate is rejected instead of returning a misleading success response.

ACP mode currently supports one active NanoAgent session per process. It merges ACP client mcpServers with NanoAgent's user and workspace MCP configuration for that ACP session only, so editor-provided MCP tools do not become global configuration.

Review automation (CI)

NanoAgent includes copy-paste CI examples for GitHub, GitLab, and Bitbucket. Each example installs NanoAI from the latest release using the same curl installer command shown in the CLI install section, computes the pull request or merge request diff, runs the workspace pr-reviewer profile in read-only mode, stores review artifacts, and posts a top-level review comment when platform credentials are configured.

  • Always copy .nanoagent/agents/pr-reviewer.md with the CI files so the review profile is available.
  • GitHub: copy .github/workflows/nanoai-review.yml and .github/nanoai-github-review.sh.
  • GitLab: copy .gitlab-ci.yml and .gitlab/nanoai-gitlab-review.sh.
  • Bitbucket: copy bitbucket-pipelines.yml and .bitbucket/nanoai-bitbucket-review.sh.
  • GitHub and GitLab draft pull requests are skipped.
  • Review artifacts are uploaded from artifacts/nanoai-review and retained for 14 days.

Required repository secret: NANOAGENT_API_KEY. Platform posting credentials:

PlatformVariable
GitHub ActionsUses the built-in GITHUB_TOKEN through GH_TOKEN.
GitLab CIGITLAB_TOKEN or NANOAI_GITLAB_TOKEN with permission to create merge request notes.
Bitbucket PipelinesBITBUCKET_ACCESS_TOKEN, or BITBUCKET_USERNAME plus BITBUCKET_APP_PASSWORD.

Optional repository variables:

VariableDefaultPurpose
NANOAGENT_PROVIDERopenaiopenai, openai-compatible, google-ai-studio, anthropic, anthropic-claude-account, github-copilot, openrouter, kilo-code, cerebras, groq, ollama, or ollama-cloud.
NANOAGENT_MODELgpt-5.4Preferred model id for the review run.
NANOAGENT_BASE_URLemptyRequired only when NANOAGENT_PROVIDER is openai-compatible.
NANOAGENT_THINKINGoffon or off.
NANOAGENT_REASONINGemptynone, minimal, low, medium, high, xhigh, or max.

The GitHub workflow uses pull_request_target so it can comment with the repository token. It checks out the trusted base branch version of NanoAgent, fetches the PR head only to compute a diff, and runs the CLI from trusted code. GitLab and Bitbucket examples run in their native merge request or pull request pipeline contexts and post comments through their REST APIs.

Codebase indexing

NanoAgent includes a local codebase index for repository-wide discovery. The codebase_index tool can:

  • status: show whether the index exists, when it was built, and whether files are new, changed, or deleted.
  • build: refresh the index, reusing unchanged files and updating changed files incrementally.
  • search: rank likely relevant files for a natural-language, symbol, path, or behavior query.
  • list: show indexed file paths.

NanoAgent computes and caches lightweight local embeddings for files, refreshing incrementally when the index is searched or rebuilt, and respecting ignore files such as .gitignore. The cache lives at:

.nanoagent/cache/codebase-index.json

The cache does not store full file contents. It stores per-file metadata such as path, length, hash, language, line count, symbols, and the local embedding vector used for ranking. Search snippets are read from current workspace files when results are returned. Indexing respects .gitignore, .nanoagent/.nanoignore, and built-in exclusions for generated or local runtime directories such as .git/, node_modules/, bin/, obj/, .nanoagent/cache/, .nanoagent/logs/, and .nanoagent/sessions/.

Use codebase_index for broad discovery first, then use file_read, text_search, or code_intelligence to verify exact behavior before editing.

Manual index updates

/index
/index update
/index status
/index rebuild
/index list
/index list 50

Automatic index updates

NanoAgent can refresh the index automatically after each conversation turn completes, so the next prompt sees an up-to-date index. This runs after the assistant response and all tool calls finish, reuses unchanged files, updates changed files incrementally, and never fails the completed turn on a failed refresh. This is disabled by default. Enable it in user-level or workspace-level .nanoagent/agent-profile.json:

{
  "codebaseIndex": {
    "autoUpdateAfterTask": true
  }
}

Providers & models

NanoAgent stores a provider profile locally and discovers models from that provider when possible. Use the terminal F2 or /models picker, /use <model>, or the desktop model control to switch models. The active model is stored with the local configuration and section state. If a preferred model is unavailable, NanoAgent falls back to a discovered model when possible.

Thinking mode

/thinking on
/thinking off

Reasoning effort vs thinking mode

thinking controls whether NanoAgent enables provider reasoning behavior where supported and whether provider-approved reasoning summaries are shown in the UI. reasoningEffort controls how much reasoning work NanoAgent asks the model to spend.

  • /thinking on shows supported reasoning output.
  • /thinking off hides reasoning output.
  • /reasoning high asks the provider for deeper reasoning.
  • /reasoning none disables reasoning where the provider supports disabling it.

Supported normalized reasoning effort values:

none
minimal
low
medium
high
xhigh
max

If thinking is on and no explicit reasoning effort is set, NanoAgent asks supported providers for their default reasoning depth, which is usually mapped to medium.

Provider reasoning mapping

ProviderRequest shapeNotes
OpenCode Zenreasoning.effort for Responses, reasoningEffort in OpenCode configCamelCase in OpenCode config files; Responses-style payloads for Zen Responses models.
OpenAIreasoning_effort (chat-completions) or reasoning: { effort, summary } (Responses)Raw reasoning stays hidden; only provider-approved summaries are shown.
Anthropic Claudethinking plus output_config.effort, or manual budget_tokens fallbackAdaptive thinking for Claude 4 families, manual budget fallback for older Claude models.
DeepSeekreasoning_content in responses; optional reasoning_effort where supportedNanoAgent never replays prior reasoning_content back to DeepSeek.
GeminithinkingConfig.thinkingLevel or thinkingConfig.thinkingBudgetGemini 3-style and Gemini 2.5-style models differ.
xAI Grok & other OpenAI-compatiblereasoning_effort or Responses-compatible reasoning.effort when supportedCapability depends on the upstream provider and model.
OpenRouterUnified reasoning objectSupports effort mapping and safe replay of provider-approved reasoning metadata.

NanoAgent keeps final answers separate from reasoning output. When thinking output is disabled, NanoAgent still shows the final answer and suppresses reasoning blocks.

Profiles & subagents

Profiles shape how NanoAgent behaves.

ProfileModeEdit behaviorBest for
buildPrimaryAllows edits under permissionsImplementation, fixes, tests, build loops.
planPrimaryRead-onlyInvestigation and implementation plans.
reviewPrimaryRead-onlyFindings-first code review.
generalSubagentAllows edits under permissionsBounded delegated implementation work.
exploreSubagentRead-onlyFast codebase discovery.

Switch profiles:

/profile build
/profile plan
/profile review

Invoke a subagent for one turn:

@explore How does authentication work?
@general Update the parser tests for this narrow case.

Primary agents can also use agent_delegate for one focused handoff or agent_orchestrate for several coordinated subtasks. Orchestration is useful when multiple read-only investigations can run independently or when implementation tasks can be split into clear file scopes.

Primary profiles (build, plan, and review) can use the ask_question tool to ask you a question and wait for your answer before continuing. It supports multiple-choice options, multi-select, and free-form text, and works in the interactive terminal, one-shot CLI runs, and ACP editors that support permission or text prompts. In a non-interactive run with no available user, the tool returns gracefully so the agent continues with its best judgment instead of failing the turn.

Built-in profile prompt overrides

Create one of these files to replace only that built-in profile's prompt for a workspace:

.nanoagent/agents/build.md
.nanoagent/agents/plan.md
.nanoagent/agents/review.md
.nanoagent/agents/general.md
.nanoagent/agents/explore.md

NanoAgent reads the markdown body as the active profile prompt, redacts secret-looking values, and reloads it for conversation turns like .nanoagent/SystemPrompt.md. For built-in profile names, NanoAgent keeps the built-in mode, enabled tools, and permission behavior, so a custom plan.md prompt still stays read-only.

Permissions & sandboxing

NanoAgent evaluates every sensitive action through permission policy.

Permission modes

ModeMeaning
AllowThe action can proceed.
AskNanoAgent prompts for approval.
DenyThe action is blocked.

Sandbox modes

ModeMeaning
ReadOnlyNo file writes or unsafe shell mutation.
WorkspaceWriteWorkspace-scoped writes are allowed under policy.
DangerFullAccessUnrestricted execution when explicitly configured or approved.

Shell sandboxing depends on the operating system. Linux uses bubblewrap when available. macOS uses sandbox-exec. Platforms without a supported OS sandbox runner fail closed for restricted shell modes unless the user approves escalation or configures full access.

Session overrides

/allow bash "<command-pattern>"
/deny bash "<command-pattern>"

Overrides are session-scoped. For durable policy, edit configuration.

Example permission policy

{
  "Application": {
    "Permissions": {
      "auto_approve_all_tools": false,
      "file_read": "Allow",
      "file_write": "Ask",
      "file_delete": "Ask",
      "shell_default": "Ask",
      "shell_safe": "Allow",
      "network": "Ask",
      "memory_write": "Ask",
      "mcp_tools": "Ask",
      "shell": {
        "allow": {
          "commands": [
            "your-build-command",
            "your-test-command"
          ]
        },
        "deny": {
          "commands": [
            "dangerous-command-pattern",
            "network-installer-pattern"
          ]
        }
      }
    }
  }
}

shell_safe controls the mode applied to the command patterns you list under shell.allow.commands; NanoAgent does not ship a built-in shell command allow catalog. The network shortcut applies to built-in webfetch tools, including web_search and headless_browser. headless_browser renders pages through an installed Chromium-family browser such as Microsoft Edge, Google Chrome, or Chromium.

Auto-approve all tools

For trusted workspaces, you can disable approval prompts for all tools:

{
  "Application": {
    "Permissions": {
      "auto_approve_all_tools": true
    }
  }
}

This keeps workspace path checks, profile restrictions, sandbox-mode restrictions, and built-in deny rules active. Use explicit rules or shortcut settings when you need to override a specific deny policy. Memory writes still require approval by default through the memory policy, even in workspaces that auto-approve general tools.

Workspace files

Run /init. NanoAgent asks which starter files to add:

  • Recommended: core config, ignores, repo memory templates, runtime folders, and inactive agent/skill templates.
  • Minimal: core config, README, and ignore files only.
  • Custom: asks for each optional group, including the advanced inactive SystemPrompt.md.template.

You can skip the picker with /init recommended, /init minimal, or /init custom. The recommended preset creates:

.nanoagent/
  agent-profile.json
  README.md
  .gitignore
  .nanoignore
  agents/
  skills/
  cache/
  memory/
    architecture.md
    conventions.md
    decisions.md
    known-issues.md
    test-strategy.md
    lessons.jsonl
  logs/

AGENTS.md

Place AGENTS.md or .agent/AGENTS.md in the workspace for persistent project instructions. NanoAgent adds them to the model context after secret redaction.

.nanoagent/SystemPrompt-Append.md

Create this file when you want to append workspace-specific base rules to NanoAgent's configured default system prompt. This keeps the normal base behavior intact and adds your extra instructions before the active profile prompt, workspace instructions, skills, memory, and session state.

.nanoagent/SystemPrompt.md

Create this file to replace NanoAgent's base system prompt for that workspace. NanoAgent always prepends its identity header before the custom file content, then appends the active profile prompt, workspace instructions, skills, memory, and session state as usual. If both SystemPrompt.md and SystemPrompt-Append.md exist, SystemPrompt.md wins and the append file is ignored. Use .nanoagent/agents/<profile>.md when you want to replace the active profile prompt while keeping the same base system prompt. Built-in profile names are build, plan, review, general, and explore.

.nanoagent/.nanoignore

Use .nanoignore to exclude paths from NanoAgent file tools. It supports gitignore-style patterns including comments, negation, directory rules, *, ?, **, and character classes. Common exclusions:

.env
.env.*
secrets.*
[Bb]in/
[Oo]bj/
node_modules/
.git/
.nanoagent/cache/
.nanoagent/logs/
.nanoagent/memory/*.jsonl

Team memory

NanoAgent stores structured team memory as ordinary markdown files:

.nanoagent/memory/
  architecture.md
  conventions.md
  decisions.md
  known-issues.md
  test-strategy.md

These files are repo-scoped memory that your team can inspect, diff, and version-control. That is much safer than hidden memory because every durable note can go through normal code review and repository history.

  • architecture.md: major components, boundaries, data flow, and integration points.
  • conventions.md: coding, naming, formatting, review, and workflow conventions.
  • decisions.md: durable technical decisions, context, and consequences.
  • known-issues.md: known bugs, limitations, risky areas, and workarounds.
  • test-strategy.md: expected test layers, important commands, and validation guidance.

NanoAgent loads non-empty team memory files into the model context as durable project context, skipping untouched scaffold templates. Treat them as starting context, then verify against current files and fresh tool output when correctness matters.

Use the repo_memory tool to list, read, or update these documents. Writes require memory approval by default and are blocked in read-only profiles, planning phase, and read-only sandbox mode. Direct writes to .nanoagent/memory/* through file editing tools also receive the memory_write permission tag so they cannot silently bypass memory approval.

Lesson memory

NanoAgent stores reusable workspace lessons in .nanoagent/memory/lessons.jsonl. Lessons help NanoAgent avoid repeating local mistakes. When lesson memory is enabled for a workspace, NanoAgent can inject relevant lessons into prompts automatically, and automatic tool-failure observation can turn repeated failures and their later fixes into reusable lessons. Memory is local, redacted by default, and write operations require approval unless policy is changed.

Skills & custom agents

Workspace skills

Skills are task-specific playbooks loaded only when relevant. Supported layouts:

.nanoagent/skills/dotnet/SKILL.md
.nanoagent/skills/code-review.md

Example:

---
name: dotnet
description: Use for .NET build, test, package, and project-file work.
---
Prefer repo-native `dotnet build` and `dotnet test` commands.
Inspect the relevant `.csproj` before changing package references.
Keep package and target framework changes narrowly scoped.

Custom agents

Custom agents live in .nanoagent/agents/*.md. Example:

---
name: code-reviewer
mode: subagent
description: Read-only reviewer for bugs, regressions, edge cases, and missing tests.
editMode: readOnly
shellMode: safeInspectionOnly
toolOutput: full
tools:
  - code_intelligence
  - directory_list
  - file_read
  - search_files
  - shell_command
  - text_search
---
Review the requested code or change set with a findings-first posture.

The optional toolOutput key sets the default rendering for tool results while the profile is active. Omit it to fall back to the Application.Tools.toolOutput default in agent-profile.json (or the compact default if that is also unset). /tooloutput overrides this for the current session, and /tooloutput auto reverts to the profile or configured default. (The legacy fileOutput key is still accepted as an alias.)

If front matter is omitted, NanoAgent derives the name from the file name and uses conservative defaults. If a workspace agent file uses a built-in profile name such as build or review, NanoAgent treats it as a prompt override for that built-in profile rather than adding a duplicate profile — the markdown body is customizable, but the built-in profile's mode, tool set, and permission behavior are preserved.

MCP servers

NanoAgent can load MCP servers from user-level and workspace-level agent-profile.json files. ACP clients can also supply session-scoped mcpServers; those entries are merged after user and workspace config and are visible in /mcp only for that ACP session. Example:

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp"],
      "startupTimeoutSeconds": 20,
      "toolTimeoutSeconds": 45,
      "defaultToolsApprovalMode": "prompt",
      "env": {
        "MY_ENV_VAR": "MY_ENV_VALUE"
      }
    }
  }
}

Supported transports:

  • Stdio: command, args, env, envVars, cwd.
  • Streamable HTTP: url, bearerTokenEnvVar, httpHeaders, envHttpHeaders.

Use enabledTools and disabledTools to filter exposed tools. Use /mcp to inspect loaded MCP servers, custom tool providers, and dynamic tools.

Custom tools

NanoAgent can expose user-defined process tools from agent-profile.json. A custom tool can be written in any language that can read JSON from stdin and write text or JSON to stdout. Configured tools are exposed to the model as custom__<name>. mcpServers and customTools can be configured in the same profile; NanoAgent loads both sets together and exposes MCP tools as mcp__* plus custom tools as custom__*. Example:

{
  "customTools": {
    "word_count": {
      "description": "Count words in provided text.",
      "command": "python",
      "args": [".nanoagent/tools/word_count.py"],
      "cwd": ".",
      "approvalMode": "prompt",
      "timeoutSeconds": 15,
      "schema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Text to count."
          }
        },
        "required": ["text"],
        "additionalProperties": false
      }
    }
  }
}

NanoAgent sends this JSON to the process on stdin:

{
  "toolName": "custom__word_count",
  "configuredName": "word_count",
  "arguments": {
    "text": "hello world"
  },
  "session": {
    "id": "session-id",
    "workspacePath": "/path/to/workspace",
    "workingDirectory": "."
  }
}

The process can print plain stdout, which is treated as a successful text result, or a structured response:

{
  "status": "success",
  "message": "Counted words.",
  "data": {
    "words": 2
  },
  "renderText": "2 words"
}

Use status: "error" for execution errors or status: "invalid_arguments" for argument validation failures. Relative cwd and relative command paths are resolved against the workspace root. Custom tools default to approval prompts; use permission rules or approvalMode: "auto" only for tools you trust.

Memory, audit & hooks

Tool audit

Tool audit logging is disabled by default. When enabled, NanoAgent writes completed tool-call records to .nanoagent/logs/tool-audit.jsonl.

Workspace policy

Configure memory and audit behavior in .nanoagent/agent-profile.json:

{
  "memory": {
    "requireApprovalForWrites": true,
    "allowAutoFailureObservation": true,
    "allowAutoManualLessons": false,
    "redactSecrets": true,
    "maxEntries": 500,
    "maxPromptChars": 12000,
    "disabled": false
  },
  "toolAudit": {
    "enabled": false,
    "redactSecrets": true,
    "maxArgumentsChars": 12000,
    "maxResultChars": 12000
  }
}

Lifecycle hooks

Hooks run local automation around NanoAgent actions. A hook receives JSON on standard input and selected NANOAGENT_* environment variables. Example:

{
  "Application": {
    "Hooks": {
      "enabled": true,
      "defaultTimeoutSeconds": 30,
      "maxOutputCharacters": 12000,
      "rules": [
        {
          "name": "check-write",
          "events": ["before_file_write", "after_file_write"],
          "command": "scripts/check-write.ps1",
          "pathPatterns": ["src/**", "NanoAgent/**"]
        },
        {
          "name": "shell-failure",
          "event": "after_shell_failure",
          "command": "scripts/on-shell-failure.ps1",
          "shellCommandPatterns": ["dotnet test*", "npm test*"]
        }
      ]
    }
  }
}

Supported hook events include task, tool, file, shell, web, memory, permission, and delegation lifecycle events.

Code intelligence (LSP)

code_intelligence discovers language servers from built-in definitions, the current workspace, and optional user or workspace profile overrides.

  • Run code_intelligence with action: "servers_status" to inspect supported languages, detected servers, missing servers, cached health, and install hints.
  • In the interactive CLI, use /lsp for the same registry view. Use /lsp refresh to bypass cached detection, or /lsp file <path> to inspect candidates for one file.
  • Built-in detection checks workspace-local bins such as node_modules/.bin and common Python virtualenv script folders before falling back to PATH.
  • Server selection is deterministic: higher priority wins, then NanoAgent falls back through remaining detected servers in stable key order.
  • Rename stays preview-only. Code-intelligence actions remain read-only.

Example status request:

{
  "action": "servers_status",
  "refresh": true
}

Profile overrides live in user-level or workspace-level .nanoagent/agent-profile.json under languageServers. Example override:

{
  "languageServers": {
    "python-pyright": {
      "language": "Python",
      "name": "Pyright",
      "command": ".nanoagent/tools/pyright-langserver.cmd",
      "args": ["--stdio"],
      "languageId": "python",
      "fileExtensions": [".py"],
      "priority": 250
    }
  }
}

Supported languageServers fields: command, args, enabled, fileExtensions, initializationOptions, installHint, language, languageId, name, priority.

Setup examples

  • TypeScript/JavaScript — install vtsls or typescript-language-server: npm install -g @vtsls/language-server typescript
  • Python — install basedpyright-langserver, pyright-langserver, or pylsp: pip install basedpyright or pip install python-lsp-server
  • C# — install csharp-ls: dotnet tool install --global csharp-ls
  • Rust — install rust-analyzer: rustup component add rust-analyzer
  • Go — install gopls: go install golang.org/x/tools/gopls@latest
  • C/C++ — install clangd via your platform package manager or LLVM distribution so clangd is on PATH.

Privacy & local data

Stays local

  • Workspace files stay on your machine.
  • Configuration is local.
  • Sections are stored locally.
  • Codebase index cache is stored locally.
  • Team memory and lesson memory are stored locally.
  • Optional audit logs are stored locally.
  • Secrets are stored through platform credential storage where supported.

Sent to the configured provider when needed

  • User prompts.
  • System and workspace instructions.
  • Relevant file excerpts.
  • Tool outputs.
  • Conversation context.
  • Model and tool schemas.

NanoAgent redacts common secret patterns before storing or displaying tool output, memory, audit records, logs, conversation history, session state, workspace instructions, and errors. Redaction is pattern-based and should not be treated as a full data-loss-prevention system.

Troubleshooting

nanoai is not found

Restart the terminal after installation. If it still fails, verify that the install directory is on PATH.

Provider setup is incomplete

Run nanoai and choose to reconfigure. This can happen when setup was cancelled after provider config was saved but before the secret was stored.

Provider validation fails after onboarding

Choose to re-run onboarding when NanoAgent offers it. If the same provider still fails, check the credential, account access, selected provider base URL, and network connectivity.

Updating NanoAgent

Run /update to check for a newer release. Run /update now to install the latest release immediately, then restart NanoAgent.

ChatGPT Plus/Pro sign-in does not complete

Check that port 1455 is available and that the browser callback URL opens locally. Sign-in requires network access and a valid account with access to the selected model.

Claude Pro/Max sign-in does not complete

Check that port 53692 is available and that the browser callback URL opens locally. Sign-in requires network access and a valid Claude Pro or Max account.

GitHub Copilot sign-in does not complete

Check that the device-code page opened, enter the displayed code, and verify that your GitHub account has Copilot access. For GitHub Enterprise, enter only the Enterprise URL or domain when prompted; leave it blank for github.com.

No models are listed

Check the provider credential, provider account access, network connectivity, and custom provider base URL. For compatible providers, the base URL must be absolute and use HTTP or HTTPS. For Ollama, make sure ollama serve is running and at least one model is installed. For LM Studio, make sure the local server is started, at least one model is loaded, and the API key matches your LM Studio server settings. For Ollama Cloud, check that the API key has access to the hosted models you expect to use.

A command is denied

Run /permissions and /rules to see active policy. You can approve the prompt, add a session override with /allow, or update configuration.

Shell sandboxing fails on Windows

Foreground shell commands in read-only and workspace-write modes use the Windows sandbox runner. If a restricted command still fails, inspect %APPDATA%\NanoAgent\.sandbox\sandbox.log, rerun the Windows sandbox setup if prompted, and verify the working directory still exists. Restricted pseudo-terminal sessions and restricted background terminals are not wired to the Windows sandbox runner yet; those requests fail closed — rerun without pty, use a foreground command, or approve sandbox escalation only when you trust the command.

The agent cannot read a file

Check that the path is inside the workspace and not excluded by .nanoagent/.nanoignore or default secret-protection rules.

Undo did not revert a shell side effect

Undo/redo only covers tracked file edit transactions. It does not revert arbitrary shell command side effects, package installs, generated files, external tools, or network actions.

NuGet SDK (.NET)

The NanoAgent package on NuGet.org provides the core libraries and application services behind NanoAgent — the same core that powers the desktop app, the nanoai terminal command, and the editor extensions. Add the package to drive the coding agent from your own application — an app builder, a server, a bot, or automation — without implementing the interactive console UI. The release workflows pack and publish the package for every v* tag release. If you want the end-user command-line experience instead, install the nanoai CLI from the release installers; the CLI is not distributed as a NuGet package.

Install

dotnet add package NanoAgent

Or add a reference directly in your .csproj:

<PackageReference Include="NanoAgent" Version="*" />

The package targets net10.0, so your project needs a .NET SDK compatible with net10.0. Pin Version to a specific release for reproducible builds instead of using *.

Embed the SDK

The NanoAgent.Sdk namespace lets you drive the coding agent from your own application without the interactive console UI. Configure a provider and model with the fluent builder, then run turns and subscribe to progress events. Provider credentials are held in memory only — embedding the SDK never touches the machine-wide NanoAgent configuration.

using NanoAgent.Sdk;

await using NanoAgentClient client = NanoAgentClient.CreateBuilder()
    .UseAnthropic(apiKey, "claude-opus-4-8")   // or UseOpenAi / UseOllama / UseOpenAiCompatible / ...
    .WithWorkspace("/path/to/repo")
    .AutoApproveTools()                          // for trusted / sandboxed automation
    .Build();

// Surface progress in your UI (final answer is still returned from RunTurnAsync).
client.AssistantMessageChunkReceived += (_, e) => Console.Write(e.Text);
client.ToolCallsStarted += (_, e) => Console.WriteLine($"Running {e.ToolCalls.Count} tool(s)...");
client.StatusMessage   += (_, e) => Console.WriteLine($"[{e.Severity}] {e.Message}");

await client.InitializeAsync();
ConversationTurnResult result = await client.RunTurnAsync("Build a TODO app");
Console.WriteLine(result.ResponseText);

Extend with your own tools and services

Register custom tools the agent can call, attach MCP servers, and override or add any dependency-injection service:

NanoAgentClient client = NanoAgentClient.CreateBuilder()
    .UseAnthropic(apiKey)
    .AddTool(new MyDeployTool())                 // custom ITool the agent can call
    .AddMcpServer(new BackendMcpServerConfiguration("docs") { Url = "https://..." })
    .ConfigureServices(services => { /* override or add any DI service */ })
    .Build();

The CLI and desktop apps continue to use the same core through their existing entry points; the SDK is an additive layer on top.

The SDK runs the agent in-process. Permission policy, sandbox modes, and built-in deny rules still apply — review Permissions & sandboxing before calling AutoApproveTools() or granting an embedded agent write or shell access in a host application.

Build from source

Requirements

  • .NET SDK compatible with net10.0.
  • Node.js 20 or newer for the VS Code extension.
  • Visual Studio 2022 or newer on Windows for NanoAgent.VS.
  • Platform toolchains needed by your target desktop/CLI build.

Commands

dotnet restore NanoAgent.CrossPlatform.slnx
dotnet build NanoAgent.CrossPlatform.slnx
dotnet test NanoAgent.Tests/NanoAgent.Tests.csproj
dotnet pack NanoAgent/NanoAgent.csproj -c Release

VS Code extension commands:

cd NanoAgent.VsCode
npm ci
npm run lint
npm run package
npm run package:vsix

Visual Studio extension command:

msbuild NanoAgent.VS/NanoAgent.VS.csproj /restore /p:Configuration=Release /p:DeployExtension=false

Main projects

ProjectPurpose
NanoAgentCore application, domain, infrastructure, tools, providers, storage.
NanoAgent.CLITerminal UI and one-shot CLI.
NanoAgent.DesktopDesktop app.
NanoAgent.VSVisual Studio extension that hosts NanoAgent inside a tool window.
NanoAgent.VsCodeVS Code extension that drives NanoAgent through ACP mode.
NanoAgent.TestsTest suite.

License

NanoAgent is licensed under the Apache License 2.0. See the LICENSE file in the repository.

Looking for the source, releases, or to file an issue? Visit the NanoAgent GitHub repository.

Ship with an agent that keeps you in control.

Local-first. Reviewable. Open source under Apache-2.0.