Nakode is a provider-neutral agent server for orchestration, continuity, and execution. It owns the workspace runtime and canonical session state while replaceable frontends provide the interface. The included TUI is one thin client, not the application authority.
Nakode is experimental and under active development.
Developers and coding agents can drive the real TUI controls and renderer through the deterministic JSON Lines TUI evaluation harness. Alternative interfaces can use the same native server through the generated API and SDK; the TUI is one renderer of server-owned semantic state. Background clients can read a bounded scalar session status inventory through one SDK query without keeping a renderer or transcript subscription alive.
Use prepare_image to inspect or explicitly crop/downscale conversation images, then select their references in nakode_agent.image_references. Images accompany the first delegated task and remain visible after transcript restoration. Public SDK clients use GetSessionImage and Delegate. See usage, limits and provider constraints.
Native tool sessions on Linux/macOS can use return_image({"path":"relative/image.png"})
to attach an existing workspace image to the assistant transcript. This is not image generation.
The tool requires filesystem-read permission and accepts PNG, JPEG, GIF and WebP, up to 5 MiB
per image, eight images and 20 MiB per turn. Nakode retains the bytes in native-session history
and exposes them through public transcript artifacts; deleting the source file does not remove
the retained reply. Image bytes are not echoed into provider tool-result text. Compatibility
harness adapters are not guaranteed to expose this native tool. Image-input support still
belongs to the selected model. Prompt input may contain images without text.
The background Nakode service manages every session, turn, queue, provider, tool, artifact, setting, and orchestration run. It performs all operations and mutations, persists canonical state, and continues active work without an attached client.
nakode is that service. Run it directly:
nakode start # background, returns once it accepts connections
nakode run # foreground until Ctrl-C
nakode status # version, process, endpoint, capabilities, log path
nakode status --json
nakode logs -f # tail the captured service log
nakode restart
nakode stopstart and stop are safe to repeat: an already-running service reports that
it is running rather than starting a second one, and stopping a stopped service
succeeds. restart starts a stopped service as well as replacing a running one.
One installation-wide service owns the endpoint, provider registry, credentials, transports, and persistence for every session. Working directories and filesystem/tool access remain properties of individual sessions and are supplied by the frontend creating them, never by lifecycle CLI flags.
Remote client access is opt-in and additive to the private Unix endpoint:
nakode remote enable --bind 10.0.0.8:7342 --endpoint executor.example:7342
nakode restart # applies listener or credential changes
nakode remote check --endpoint executor.example:7342
nakode remote descriptor --endpoint executor.example:7342
nakode remote regenerate-key --endpoint executor.example:7342
nakode remote rotate-credentials --endpoint executor.example:7342
nakode remote disable # restart removes the TCP listenerenable is idempotent: reruns preserve the stable server ID, API key, and TLS certificate while
repairing enablement or changing the bind address. regenerate-key revokes only the bearer key;
rotate-credentials replaces both key and pinned certificate. Both require a service restart.
check performs a real pinned-TLS and authenticated GetServerInfo call and rejects API/server-ID
mismatch. A wildcard bind needs a separate reachable --endpoint in enrollment output.
The descriptor contains a random 256-bit bearer key and pinned self-signed TLS identity; handle it as a secret. The installation keeps a stable server ID across key regeneration. Remote frontends use the same nakode.v1 service, including read-only InspectWorkspacePath for server-side canonical path and Git placement checks. A workspace request of ~ or ~/… resolves against the Nakode service runtime user's authoritative home on the execution host; failures name the resolved server path and filesystem cause. Nakode remains the sole session, provider, tool, persistence, lifecycle, and resumability authority.
After installation, Nakode preserves an already-current singleton, restarts it only when it is stale and quiescent, and retires quiescent legacy per-workspace services. Legacy services with active work are left running and reported rather than killed.
The interactive terminal client is one frontend over that service. It derives the new session's working directory from its own current directory:
cd /path/to/project
nakode --tuiThe earlier nakode service <action> spellings still work. Each prints a
deprecation notice on standard error naming its replacement, then does the work.
Every frontend—including the built-in TUI—only:
- obtains authoritative state through the generated SDK;
- maps user intent to distinct typed SDK methods; and
- renders that state while retaining only ephemeral presentation concerns such as drafts, focus, selection, scrolling, viewport, and device integration.
Frontends never open Nakode's database, connect directly to providers, execute
tools, reduce provider events, or decide session and queue policy. This is a
hard project boundary: a new capability must be implemented in the server,
exposed through proto/nakode/v1/nakode.proto, represented in the SDK, and only
then rendered by clients. See Building a Nakode frontend
and the SDK architecture.
Nakode brings agentic coding work into a single terminal experience:
- Run coding agents against a local workspace.
- Inspect and edit files, search code, run commands, and track task progress.
- Stream responses, reasoning, plans, tool activity, and diffs as work happens.
- Resume saved sessions and continue long-running work.
- Queue follow-up prompts, interrupt active work, and switch models.
- Delegate bounded investigations to independently tracked agents, including parallel research across providers.
- Carry work between providers with an explicit continuity handoff instead of claiming that private model context can be transferred.
The longer-term direction is a provider-neutral orchestration and continuity layer where logical work can span multiple agents, models, and providers. That includes richer delegation and review workflows and durable project memory. These are product goals, not all current features.
Nakode currently supports:
- OpenAI Codex
- Claude
- Devin
- Cursor
- Kimi For Coding
- GLM Coding Plan (z.ai)
Providers are disabled on a fresh installation. Start Nakode, open
/providers, and sign in to the providers you want to use. Press F2 to browse
and select from their available models. Provider details can independently enable a model filter and
select exact provider/model IDs from a searchable, scrollable catalogue. Filtering defaults off.
When enabled it changes ordinary model discovery only: exact persisted or explicitly requested IDs
remain addressable, and stale selected IDs remain visible rather than being substituted. A filter
whose selection no longer matches any discovered model (for example an enabled filter with an
empty selection) fails open and shows the provider's full catalogue, since silently hiding every
discovered model is never the intent of a selection that selects nothing.
Nakode does not require the separate Codex, Devin, Kimi, or z.ai applications. OpenAI
Codex sign-in uses the normal browser OAuth flow by default and returns to Nakode through
a localhost callback; Nakode then persists and refreshes the OAuth credential. Embedders
can retain device-code authentication by explicitly calling
BackendConfig::with_device_code_authentication. Claude
uses the official Claude Agent SDK and the login managed by an installed Claude Code
CLI; install Claude Code and run claude auth login before connecting Claude in
/providers. Claude requires Node.js 18 or newer plus npm. Nakode stores only an
external-login marker, not Claude OAuth credentials; Claude Code continues to own its
configuration and keychain entries. Agent SDK activity is subject to Anthropic's current
subscription eligibility, usage limits, and third-party application policies. Cursor uses
its local TypeScript SDK and requires Node.js 22.13 or newer plus npm. Cursor, Kimi, and GLM
setup in /providers includes an API-key field and a link to the provider's API-key
dashboard. Kimi requires a Kimi Coding Plan
API key; Moonshot Platform API keys are a separate product and are not
interchangeable. GLM requires a z.ai GLM Coding Plan
API key and uses the plan's dedicated Coding API endpoint; Team Plan members must
use their Team Plan key. No single provider defines Nakode's workflow or session
model.
Nakode requires Git and Rust 1.88 or newer. Source is hosted on GitHub. Install Nakode with this command:
mkdir -p "$HOME/.nakode" && \
git clone https://github.com/QuillDev/nakode.git "$HOME/.nakode/src" && \
"$HOME/.nakode/src/install.sh"This keeps the managed source checkout in ~/.nakode/src and installs the
nakode executable to ~/.local/bin. If that directory is not already in your
PATH, the installer prints the line to add to your shell profile. Do not run
Nakode or the entire installer through sudo; provider sign-in uses your normal
desktop account.
Update the checkout, rebuild Nakode, and replace the installed executable with:
nakode updatenakode update retargets a recognized Cursor Origin or non-canonical GitHub
remote to https://github.com/QuillDev/nakode.git, then runs
git pull --ff-only in the managed source checkout and that checkout's
install.sh. The checkout is $NAKODE_HOME/src when NAKODE_HOME is set,
or $HOME/.nakode/src otherwise. An explicit --prefix must be absolute;
--no-activation leaves running-service activation to the supervisor (and is
also accepted as --supervisor-owned). nakode --update remains supported as
a convenience alias with the default installation options.
For local development in another checkout, ./install.sh --debug reuses the
development build for much faster iteration, at the cost of a larger and less
optimized installed executable. Run ./install.sh --help for system and
custom-prefix options.
To return Nakode to a clean, first-run session state:
nakode purge-unsafeThe command prints a warning and then asks for confirmation with a
default-negative [N/y] prompt. Only an explicit y or Y proceeds; an empty
line, n, end-of-input, and any unrecognized answer abort without changing
anything. This is deliberately interactive and has no force or bypass flag, so
it cannot be scripted by accident.
On confirmation it first stops every discoverable workspace service through its lifecycle socket, so each server terminates its own provider children, shell processes, delegated runs, and frontend transports before persistence is touched. Stale socket sets left by a dead server are removed. It then deletes every logical session, delegated orchestration run, agent turn, and native runtime history — including orphaned histories from dead or partially initialized sessions that ordinary close-first deletion cannot clear.
Provider credentials, provider enablement, default-model preferences, global add-on configuration such as web and memory settings, installed providers, and repository contents are outside the purge boundary and survive it. The command reports what it removed and reports failures instead of claiming success, and running it again on an already-clean install is a no-op.
Open a terminal in the project and start the TUI. Each invocation creates a new logical session rooted at that current directory:
cd /path/to/project
nakode --tuiThen use /settings to manage general preferences, agents, models, providers,
and optional add-ons. The settings menu is searchable. /providers, /agents,
and /models remain available as direct shortcuts.
Sub-agent archetypes are global to the user rather than tied to a project workspace. Nakode stores
them as TOML files under $NAKODE_HOME/agents; when NAKODE_HOME is unset it defaults to
~/.nakode, so the ordinary catalogue is ~/.nakode/agents. Every workspace loads the same
catalogue.
A definition names the archetype (slug, description), what it is told (system_prompt,
first_message), and how it runs: model, fallback_models, fast_mode, and an optional
reasoning_effort. Effort belongs to the model that runs at it, so reasoning_effort is refused
without a model and refused when that model does not offer the level named. Omit it and the
delegated run uses the model's own default level, which is what every definition written before the
field means — nothing on disk needs editing. fast_mode = true is an affirmative request available
only when the discovered model advertises it. false does not request a slow tier; it leaves ordinary
provider behaviour unchanged. An inherited or fallback model is checked after it resolves, before
Nakode projects options onto the delegated session.
CreateSession.initial_instructions is stored separately from accepted user prompts in logical
session metadata. Pending-session recovery restores the creation-time instructions, and logical
provider transitions preserve them. A new logical session clears the previous session's client
instructions. Legacy rows without this metadata remain absent: Nakode does not infer instructions
from old user messages or silently rewrite transcript history. Provider-native resume continues to
use that adapter's persisted context.
New delegations require a concise, task-specific title (1–120 characters) separate from the full
assignment. The native nakode_agent tool and compatibility delegation tool require title;
DelegateRequest.title and the SDK delegation methods carry it to the server. The CLI requires
--title, for example:
nakode agent repo-explorer --session-id SESSION_ID \
--title 'Audit session persistence' --task 'Trace session creation and report persistence gaps.'The server validates and persists the title independently of the objective and exposes it as
RunState.title. Legacy runs retain an absent title; continuation runs inherit their source title.
An explicit CreateSession.title also remains the logical session title instead of being replaced
by its first prompt. Callers using the updated delegation API must supply titles; old calls without
one are rejected rather than assigned a task-derived title.
Owner-defined definitions additionally carry ownership and availability, canonical capability/tool
allow and deny lists, a tool profile (none, read_only, command_runner, bounded_watcher, or
custom), task/output contracts, bounded lifecycle values, fallback policy, and delegation/parent
attribution policy. Shipped built-ins are visible but immutable. Nakode validates these fields against
its live provider/model catalogue, persists create/update/rename atomically, and remains the sole
runtime authority; unavailable choices are reported rather than silently replaced. Native Codex,
Devin, GLM, and Kimi sessions receive an authoritative Nakode builtin-tool allowlist, while Claude
applies the equivalent SDK allowlist and permission hook. Empty custom policy retains compatibility
with definitions written before policy fields existed.
Catalogue changes are loaded without restarting the installation-wide service. After installing a Nakode binary whose public protocol changed, the installer refreshes a quiescent stale singleton and retires quiescent legacy per-workspace services. Active legacy services remain available until their work finishes.
slug = "code-reviewer"
description = "Reviews changes for correctness"
model = "openai-codex/gpt-5.6-sol"
reasoning_effort = "high" # omit for the model's own defaultUse --agents PATH or NAKODE_AGENTS=PATH to override the catalogue. Absolute paths are used as
written; relative paths resolve under Nakode home, not under the current workspace. Nakode does not
automatically import existing workspace-local .nakode/agents directories; move wanted definitions
into the global directory or point --agents at an absolute compatibility directory.
Nakode can append user-specific guidance to every newly created native agent
session. By default it looks in the platform configuration directory for
personalities.toml and an optional SOUL.md (for example,
~/.config/nakode/ on Linux). It never creates either file.
personalities.toml supports a global default and provider-qualified,
per-model overrides:
default = """
Be warm, direct, and explain important tradeoffs.
"""
[models]
"openai-codex/gpt-5.4" = """
Prefer terse answers and make implementation decisions confidently.
"""
"zai-coding/glm-4.7" = """
Show a short plan before changing code.
"""An exact model entry replaces the default personality for that model. Models
without an entry use default. Empty values are ignored. Model keys must use
the canonical provider/model form.
SOUL.md describes who the agent is—identity, enduring preferences, and style
controls. Nakode has one configured Soul, not one per model or workspace. When
present, it is always appended independently of the selected personality,
including for delegated agents. Owner-facing clients can read and atomically
save this exact file through GetSoul / SaveSoul; saves use the last-read
digest so conflicts remain explicit. The default is the platform Nakode config
directory's SOUL.md; --soul PATH / NAKODE_SOUL selects the same singleton
at another path.
Personality and Soul content is snapshotted when a Nakode logical session is
created, and that snapshot is reused by its primary and delegated provider
sessions. A successful API save is therefore visible to newly created logical
sessions through the installation-wide service; already-running and resumed
sessions retain the instructions they started with. Personality and Soul are
followed by a protected runtime boundary, so owner content cannot replace
security, tool-policy, delegation-limit, objective-mismatch, or run-attribution
requirements. Direct file edits do not mutate materialized session snapshots;
/reload remains the explicit way to refresh one.
Use --personalities PATH / NAKODE_PERSONALITIES and --soul PATH /
NAKODE_SOUL to select other files. Relative explicit paths are resolved from
the workspace. Explicit paths must exist at startup; the default files are
optional, and SaveSoul can deliberately create the missing default file.
Sent image attachments render inline when Nakode detects Kitty, WezTerm, Ghostty,
iTerm2, Sixel, or another protocol supported by ratatui-image. Configure the
default under /settings → Add-ons → Terminal images:
- Automatic uses terminal hints and a capability query.
- On always attempts the capability query, which is useful through tmux or SSH.
- Off keeps attachment labels without probing.
The NAKODE_TERMINAL_IMAGES=auto|on|off environment variable remains available
as a per-launch override.
Nakode records aggregate inference and tool telemetry inside each local native session. Inspect recent usage without exposing prompts, reasoning, tool arguments, tool output, session titles, or credentials:
nakode diagnostics
nakode diagnostics --days 30 --provider openai-codex --sessions 40
nakode diagnostics --days 30 --json > nakode-usage.jsonThe report includes daily provider usage, reported input/cached/uncached/output tokens, inference rounds, compactions, retries, tool calls, failures, output sizes, runtime, and the highest-input sessions. JSON output is intended for longitudinal analysis. Token and cache values are available only when the provider reports them; cached tokens may still count toward provider subscription or rate limits even when an API pricing plan discounts them.
Long-running turns remain unrestricted. Nakode emits non-blocking transcript warnings after every 25 active inference rounds, when an inference request succeeds only after provider retries, and when the same tool fails three times and then at each additional five-failure milestone in one turn. These warnings are informational and never interrupt the agent.
Canonical transcript entries optionally retain the stable provider ID and qualified model ID active
when their turn began. Native runtime history and delegated-run SQLite persistence restore that immutable
origin, and TranscriptEntryView plus protobuf fields 9 (provider_id) and 10 (model_id) expose it to
SDK clients. Legacy and provider compatibility history without trustworthy origin leaves both fields
absent; consumers must not infer them from a current selection or display/model-name parsing.
The public TranscriptPage keeps explicit paged history at 128 entries and 512 KiB, while the live
session snapshot projects up to 256 entries and 1 MiB so inspection clients receive materially more
recent history without removing a bounded API edge. Newest-page snapshots also project the latest
owner entry independently and expose the exact number of omitted Tool/Diff entries carrying that
owner turn ID. Historical pages omit both current-turn fields; unrelated omitted rows never contribute
to the count. Entry bodies, audits, redaction and truncation retain their existing bounds.
For installation, service-user configuration, safe validation, and maintenance, see Linux provisioning. Recorded VPS diagnostics and sandbox repairs are in Visual tools on headless hosts.
Nakode's portable runtime can expose a browser tool when a browser add-on is
enabled under /settings → Add-ons → Web browsing. Browsing is disabled by default and
neither backend is required to run Nakode:
- agent-browser runs the optional open-source
agent-browserexecutable on the local machine. Install and configure it separately, then select it in Nakode. If the executable is missing, only browser calls fail. - Firecrawl uses Firecrawl's hosted search and scrape API. Select Firecrawl and enter an API key in settings. The key is stored in Nakode's protected local application database.
Changes apply to the portable browser tool without restarting Nakode. Provider or tool functionality unrelated to web browsing remains available when either add-on is absent or disabled.
The vision tool analyzes workspace images using its own configured provider/model.
Under /settings → Add-ons → Vision, select a model and its reasoning
effort. The picker uses that model's advertised values; vision does not inherit
the calling agent's effort or fast mode. Existing installations retain low until
changed. Saved effort applies to subsequent vision calls without restarting the
server.
Headless integrations can use the public SelectModel operation with the Vision
target and reasoning options, or UpdateSettings with a vision model and optional
reasoning_effort. See vision provisioning
for compatibility and deployment details. The browser tool returns text; capture
screenshots separately before passing them to vision.
Nakode can expose provider-neutral memory_search and memory_store tools through
Mnemosyne. Memory is disabled by
default and writes occur only when an agent explicitly calls memory_store; Nakode
does not ingest transcripts automatically.
Install Mnemosyne with its stdio MCP support in an isolated Python environment:
uv tool install 'mnemosyne-memory[mcp]'Then open /settings → Add-ons → Memory, select Mnemosyne, confirm
the executable, and choose the Mnemosyne bank used for global user memory.
By default Nakode stores Mnemosyne banks under Nakode home (NAKODE_HOME,
defaulting to ~/.nakode), instead of inheriting Mnemosyne's application-wide
default directory. Set Data directory explicitly to override this location.
Semantic embeddings remain optional and can be installed with mnemosyne-memory[mcp,embeddings].
Nakode supervises local MCP processes and stores memories in Mnemosyne's SQLite
data directory.
Nakode manages a deterministic project bank for each workspace; project-bank names
are internal and are not user settings. Every memory_store call must explicitly
select project or global scope. memory_search searches both scopes by default,
while allowing a caller to narrow a query to one scope.
Memory tools are currently available to the portable-tool runtimes used by Codex, Devin, Kimi, and GLM. Cursor continues to work normally but does not receive these tools. Disabling memory, clearing a required field, or removing the executable removes the tools on the next inference request without affecting other providers.
Nakode discovers portable Agent Skills from these directories, with workspace-local skills taking precedence when names overlap:
<workspace>/.agents/skills/<skill-name>/SKILL.md~/.agents/skills/<skill-name>/SKILL.md
Reference a discovered skill anywhere in a prompt with /skill:<skill-name>.
Nakode offers discovered names in composer completion and attaches the selected
skill instructions to that turn while keeping the original prompt unchanged in
the visible transcript. SKILL.md is the operational entrypoint. Every other
Markdown file below the same skill directory is automatically catalogued as a
component; references/github/checks.md is exposed as component name
references/github/checks with that exact file path. Non-Markdown files and
nested SKILL.md entrypoints are not components.
read_skill returns JSON with this shape:
{
"skill_instructions": "Read skill_content first ... load components with read_skill_component ...",
"skill_content": "<complete SKILL.md>",
"components": [
{"file_path": "references/github/checks.md", "component_name": "references/github/checks"}
]
}Component bodies are not injected eagerly. Load one by exact advertised name
with read_skill_component({"name":"code-review","component_name":"references/github/checks"}).
This keeps optional reference material out of model context while ensuring the
agent never searches package directories or guesses a path.
Only a component outside the skill directory needs an explicit frontmatter
entry, for example ../shared-review/policy.md. External declarations must
resolve to a Markdown component under the same installed skills catalogue, are
exposed with an owner-qualified component name such as shared-review/policy,
and can be loaded only when that owning skill is also advertised to the session.
Absolute paths, catalogue escapes, SKILL.md imports, symlink escapes, missing
files, and unreadable components reject the skill instead of exposing arbitrary
filesystem content. Discovery order and JSON component order are deterministic,
and canonical identity de-duplicates aliases and directory cycles.
Skill publishers should include a bounded immutable id in YAML frontmatter
(for example, id: fragile.code-review.v1) so local invocation history follows
a skill when its directory/load name changes. Legacy skills without an id
remain compatible and use their exact catalogue name as historical identity.
A package published through FStack's community store additionally requires a
canonical SemVer release scalar such as version: 1.2.0. Nakode treats store
provenance and version metadata as inert package metadata: it discovers the
package only after FStack explicitly materializes it under the normal
~/.agents/skills root. Nakode does not read PostgreSQL, a store cache, or a
registry root, and store availability never gates local discovery or startup.
Run Nakode inside a Herdr pane to expose its lifecycle in
Herdr automatically. No Nakode or Herdr plugin is required. When HERDR_ENV=1
and the pane identity is available, Nakode reports itself as idle, working,
or blocked, includes its persisted logical session id when one exists, and
releases its status authority on exit. Missing or failed Herdr reporting never
prevents Nakode from starting or handling a turn.
nakode restart-when-idle waits until the server atomically confirms no live session work or
pending delegations remain, then restarts it. It never escalates to forced shutdown. New work
can prolong the wait; unsupported quiescence protocols fail without stopping the server.
Authenticated clients can replace a logical session’s ephemeral process environment through SetSessionEnvironment. Values never appear in snapshots or session persistence. Clients reinject them before work after a service restart. Injection accepts exact retained logical identities without activating a provider, so it can precede OpenSession; incomplete inventory is not proof of absence. Environment values are cleared only after successful durable session deletion. Native Bash and PTY tools (including delegates) inherit the logical owner’s variables.
Owner clients can save a shell command and explicitly Sync the execution service’s PATH through the public SDK. Startup resolves it before runtime preparation; failures retain the last-good/inherited value. See machine PATH for precedence, shell initialization, security bounds and platform limitations.