NueOS Documentation
Configuration

Configuration Schema

System configuration reference for Nous-OSS

Configuration Schema

Nous uses JSON5 for configuration. The config file is validated at load time with Zod schemas.

Location: {dataDir}/config.json5 (or path from NOUS_CONFIG_PATH)

Top-Level Sections

SectionDescription
profileDeployment profile (local_strict, hybrid_controlled, remote_primary; legacy: local-only, remote-only, hybrid)
pfcTierCortex tier 0–5 (see Cortex Mode Capability Matrix)
pfcTierPresetsCapability definitions per tier
modelRoleAssignmentsWhich provider fulfills which model role
providersProvider configurations (Ollama, Chat Completions-compatible remote providers, etc.)
agentAgent identity, personality, welcome-message tracking, and user profile (optional; absent in default config — populated by the first-run wizard or by hand-editing)
defaultsDefault project settings
storageStorage backends and options
securityTrace sensitivity, optional settings

Profile

{
  "profile": {
    "name": "hybrid_controlled",  // see Profile names below
    "description": "Local preferred with explicit remote fallback",
    "defaultProviderType": "local",
    "allowLocalProviders": true,
    "allowRemoteProviders": true,
    "allowSilentLocalToRemoteFailover": false
  }
}

Profile names (Phase 2.3):

CanonicalLegacy (deprecated)Semantics
local_strictlocal-onlyLocal providers only; no silent local→remote failover
remote_primaryremote-onlyRemote providers primary; local only when explicitly configured
hybrid_controlledhybridLocal preferred with explicit remote fallback under policy

Legacy names are normalized at runtime. allowSilentLocalToRemoteFailover — when false (default), remote is allowed only as explicit fallback in hybrid_controlled.

When Anthropic or OpenAI credentials are restored at startup and the active profile is local-only or local_strict, Nous promotes the runtime into a hybrid-compatible profile so remote providers can actually be routed. Removing the last cloud provider returns the runtime to local-only posture.

Cortex Tier

pfcTier is a number 0–5. Higher tiers enable more capabilities (reflection, memory gating, tool authorization, planning, escalation detection). See Cortex Mode Capability Matrix.

Model Role Assignments

{
  "modelRoleAssignments": [
    {
      "role": "cortex-chat",
      "providerId": "550e8400-e29b-41d4-a716-446655440002",
      "fallbackProviderId": "550e8400-e29b-41d4-a716-446655440001"
    }
  ]
}

providerId and optional fallbackProviderId must be valid UUIDs matching provider id values in the providers array. Built-in provider ids are deterministically derived from certified provider-definition vendorKey values at runtime and surfaced through provider config identity; custom/user provider instances use persisted generated ids. Model assignment writers validate role compatibility before saving so command-bound CLI providers cannot be assigned to Cortex persistent-chat roles. Roles: cortex-chat, cortex-system, orchestrators, workers.

Saved Principal and System model selections are restored into this structure at startup. When both saved selections are available, Nous uses the primary selection as providerId and the secondary selection as fallbackProviderId for the active cortex-chat assignment.

Providers

{
  "providers": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Ollama",
      "type": "text",
      "modelId": "llama3.2:3b",
      "isLocal": true,
      "capabilities": ["chat", "streaming"],
      "providerClass": "local_text",
      "vendor": "ollama",
      "meetsProfiles": ["review-standard", "prompt-generation"]
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "openai",
      "type": "text",
      "endpoint": "https://api.openai.com",
      "modelId": "gpt-4o",
      "isLocal": false,
      "capabilities": ["chat", "streaming"],
      "providerClass": "remote_text",
      "vendor": "openai",
      "meetsProfiles": ["review-standard", "review-implementation"]
    }
  ]
}
  • providerClass (optional): local_text | remote_text — used for credential segregation and profile boundary.
  • vendor (optional): Certified provider vendor key for adapter selection. Known vendor values include anthropic, openai, and ollama; see Provider Adapters for how vendor keys map to provider leaves. Unknown values fall back through the adapter resolver rather than becoming certified vendors.
  • adapterKey (derived internally): Adapter implementation key resolved from the provider definition, such as anthropic, chat-completions, or ollama. text is the fallback adapter key, not a certified provider vendor.
  • meetsProfiles (optional): Array of capability profiles (e.g. review-standard, review-implementation). Router enforces that the selected provider meets the required profile unless Principal override evidence is present.
  • endpoint (optional): Use the provider base URL (for example https://api.openai.com or https://api.anthropic.com), not the full /v1/chat/completions path.

Provider types: text, image, video, vision, embedding, external-api.

Codex CLI Provider

The certified codex-cli provider is a local text provider that shells out to the installed Codex CLI. It does not use an API key in nous-config.json5; it uses the local Codex CLI login session instead. Install and authenticate Codex outside Nous before assigning this provider to a model role.

For transient and batch work, Codex CLI still runs through the one-shot codex exec command path. The Codex provider declares session_bound_command, which means it is command/session-bound and does not expose a strict long-lived process protocol.

Cortex Chat and Cortex System require persistent_process semantics for agent-cli providers. Settings disables/rejects Codex CLI for those Cortex roles instead of letting the chat path fail later. Codex CLI can still be used in compatible command-bound agent roles.

When a compatible CLI provider is used in a chat-bound context, the runtime session key is derived from the provider id, chat fixture role, and chat session id. Project-scoped chat also includes projectId; system-wide chat omits it. Conversation history remains in Cortex STM, not in provider session state.

Agent

The agent block stores agent identity and personality settings authored by the first-run wizard's Identity step or by direct hand-edit of the JSON5 file. This agent section is independent of the top-level profile (deployment profile) section above — they share no fields.

{
  "agent": {
    "name": "Nia",
    "personality": {
      "preset": "balanced",
      "overrides": { "thoroughness": "strict" }
    },
    "welcomeMessageSent": true,
    "profile": {
      "displayName": "Andrew",
      "role": "Software engineer",
      "primaryUseCase": "Architecture exploration",
      "expertise": "advanced"
    }
  }
}
  • name (string, optional) — Display name for the agent. When absent, readers return the typed default "Nous".
  • personality (object, optional) — Personality preset plus optional per-axis overrides. preset is one of balanced, professional, efficient, thorough. overrides is a partial map of TraitAxes (thoroughness, initiative, candor, communicationStyle, codeStyle). When absent, readers return the typed default { preset: "balanced" } and the production prompt path is byte-identical to the pre-personality baseline (regression-parity invariant).
  • welcomeMessageSent (boolean, optional) — Tracks whether the welcome message has been delivered (consumed by the welcome-message wiring in SP 1.6). When absent, readers return the typed default false.
  • profile (object, optional) — Typed user-profile sub-fields, all optional: displayName, role, primaryUseCase, expertise ('beginner' | 'intermediate' | 'advanced'). When absent, readers return the typed default {}. The schema is additive over time — new fields may be added in future sub-phases without breaking existing configs; renames or removals are migrations.

Read-time defaults — never persisted on read. The entire agent block is absent from the default system config. Readers (getAgentName, getPersonalityConfig, getUserProfile, getWelcomeMessageSent) synthesize their typed defaults at read time without writing to disk. The agent key first appears in nous-config.json5 only after the user completes the first-run Identity step or hand-edits the file.

Reset semantics. The firstRun.resetWizard tRPC mutation clears the entire agent block while leaving providers and modelRoleAssignments untouched. After reset, all four readers return their typed defaults again.

JSON5 comment caveat. Writes to nous-config.json5 (e.g. when the wizard's firstRun.writeIdentity procedure runs) emit JSON, not JSON5 — any comments you add to the file by hand are lost on the next write. This is a pre-existing Phase 1 tradeoff documented in the ConfigManager source. Hand-editors who rely on comments should be aware that wizard-driven writes will strip them.

Storage

{
  "storage": {
    "dataDir": "/path/to/data",
    "documentBackend": "sqlite",
    "vectorBackend": "stub",
    "graphBackend": "stub",
    "storageEncryption": false
  }
}
  • storageEncryption — When true, user is responsible for filesystem-level encryption (LUKS, BitLocker, FileVault). Phase 1: option validated; runbook in Security Baseline.

Security

{
  "security": {
    "traceSensitiveData": false
  }
}
  • traceSensitiveData — When false (default), user input, model output, and memory candidate content are redacted from traces. Structure (traceId, projectId, Cortex decisions) is preserved.

Defaults

{
  "defaults": {
    "projectType": "hybrid",
    "governance": "should",
    "memoryAccessPolicy": {
      "canReadFrom": "all",
      "canBeReadBy": "all",
      "inheritsGlobal": true
    },
    "retrievalBudgetTokens": 500,
    "stmCompactionPolicy": {
      "maxContextTokens": 1024,
      "targetContextTokens": 640,
      "minEntriesBeforeCompaction": 8,
      "retainedRecentEntries": 4
    },
    "escalationChannels": ["in-app"]
  }
}

These apply to newly created projects.

  • retrievalBudgetTokens — Default token budget for retrieval result assembly in new projects.
  • stmCompactionPolicy — Default short-term-memory pressure policy for new projects.
    • maxContextTokens — Threshold where STM should compact.
    • targetContextTokens — Post-compaction token budget.
    • minEntriesBeforeCompaction — Minimum recent turns required before compaction is allowed.
    • retainedRecentEntries — Number of newest turns kept verbatim when older context is summarized.

targetContextTokens must be lower than maxContextTokens, and retainedRecentEntries must be lower than minEntriesBeforeCompaction.

Environment Variables

VariablePurpose
NOUS_DATA_DIROverrides storage.dataDir
NOUS_CONFIG_PATHOverrides the config file path
NOUS_BASIC_AUTHEnables basic auth for tRPC (format: user:password)
OPENAI_API_KEYEnables the built-in OpenAI remote provider at startup
ANTHROPIC_API_KEYEnables the built-in Anthropic remote provider at startup
NOUS_PUBLIC_BASE_URLBase URL used in OAuth discovery documents for the public MCP edge (default: http://localhost:3000). Set this when deploying behind a non-localhost public endpoint.
NOUS_PUBLIC_MCP_HOSTED_BINDINGS_JSONSeeded hosted public-MCP binding records used to map a public host or user handle onto a hosted tenant runtime. Accepts a JSON object or JSON array of binding records.
NOUS_PUBLIC_MCP_TUNNEL_SESSIONS_JSONSeeded public-MCP tunnel session records used to map a public host or user handle onto a local tunnel runtime. Accepts a JSON object or JSON array of session records.

When OPENAI_API_KEY or ANTHROPIC_API_KEY is present at startup, Nous registers the matching remote provider, updates available cloud models, restores saved model selections against stable provider IDs, and enables hybrid-compatible routing. These variables can be supplied directly or populated from stored vault credentials during bootstrap.

Phase 13.5 config audit result: public MCP deployment routing adds two operator-facing seed variables for hosted and local-tunnel routing. NOUS_PUBLIC_BASE_URL remains the public MCP edge override for OAuth metadata and discovery URLs.

NOUS_PUBLIC_MCP_HOSTED_BINDINGS_JSON

Use this variable to seed hosted tenant routing records during web bootstrap. Each record must match the hosted-binding schema used by the public gateway:

[
  {
    "bindingId": "binding-1",
    "tenantId": "tenant-1",
    "userHandle": "andre",
    "host": "andre.nous.run",
    "storePrefix": "tenant-andre",
    "serverName": "Andre Hosted Nous",
    "phase": "phase-13.5",
    "status": "active",
    "createdAt": "2026-03-14T00:00:00.000Z",
    "updatedAt": "2026-03-14T00:00:00.000Z"
  }
]
  • bindingId — stable binding record identifier
  • tenantId — tenant-scoped runtime identity
  • userHandle — public handle used for hosted routing
  • host — public host that resolves to the hosted tenant runtime
  • storePrefix — tenant-local storage prefix used for document/vector/task/audit isolation
  • serverName — public-safe ortho.system.v1.info server name override
  • phase — public-safe phase label surfaced in ortho.system.v1.info
  • status — current binding state (active or disabled)

NOUS_PUBLIC_MCP_TUNNEL_SESSIONS_JSON

Use this variable to seed local-tunnel routing records during web bootstrap. Each record must match the tunnel-session schema used by the public gateway:

[
  {
    "sessionId": "session-1",
    "userHandle": "casey",
    "host": "casey.tunnel.nous.run",
    "sharedSecret": "0123456789abcdef0123456789abcdef",
    "status": "active",
    "createdAt": "2026-03-14T00:00:00.000Z",
    "updatedAt": "2026-03-14T00:00:00.000Z"
  }
]
  • sessionId — stable tunnel session identifier
  • userHandle — public handle associated with the tunnel session
  • host — public host that resolves to the tunnel backend
  • sharedSecret — shared secret used to validate edge-issued tunnel envelopes
  • status — current session state (active or disabled)

These variables affect deployment routing only. They do not change the public MCP tool catalog, OAuth posture, or JSON-RPC request and response shapes seen by external clients.

On this page