Documentation

Configuration

Global and project-level config, merge rules, and a complete TOML reference for every setting.

Edit on GitHub

Nyzhi uses TOML configuration files with a two-layer merge system: global defaults plus optional per-project overrides.

Config File Locations

FileLocationPurpose
Global~/.config/nyzhi/config.tomlYour personal defaults
Project<project>/.nyzhi/config.tomlProject-specific overrides
Local<project>/.nyzhi/config.local.tomlMachine-local overrides (gitignore this)

When Nyzhi starts, it loads global first, then merges project config on top.

Tip: Run nyz init inside any project to scaffold a .nyzhi/ directory with a starter config.

Merge Rules

The merge is not a naive overwrite. Each section has specific semantics:

SectionMerge behavior
provider.providersMerged per provider — project can override api_key, model, etc.
provider.defaultProject wins only if it differs from the built-in default (openai)
mcp.serversProject extends the global map
agent.trust.deny_tools / deny_pathsUnion + deduplicate
agent.hooks / agent.commandsConcatenated (global first, then project)
agent.agents.rolesMerged map — project can add or override roles
browser.headlessAND — both must be true
memory.auto_memoryOR — either can enable it
update.enabled / index.enabledAND — both must be true
update.release_urlGlobal only (project cannot override — security)

Quick Start Example

A minimal global config to get started:

# ~/.config/nyzhi/config.toml

[provider]
default = "openai"

[provider.openai]
model = "gpt-5.3-codex"

[agent.trust]
mode = "limited"

And a project config that tweaks behavior for a specific repo:

# <project>/.nyzhi/config.toml

[provider]
default = "anthropic"

[provider.anthropic]
model = "claude-sonnet-4-20250514"

[agent]
max_steps = 50
custom_instructions = "Always run tests before committing."

[agent.trust]
deny_paths = [".env", "secrets/"]

Full Schema Reference

[provider]

Controls which LLM provider and model to use.

[provider]
default = "openai"   # provider ID to use by default

[provider.openai]
api_key = ""         # or use OPENAI_API_KEY env var (recommended)
base_url = ""        # override API endpoint
model = "gpt-5.3-codex"
api_style = ""       # "openai" | "anthropic" | "gemini" — usually auto-detected
max_tokens = 4096
temperature = 0.7

You can define multiple providers and switch between them:

[provider.anthropic]
model = "claude-sonnet-4-20250514"

[provider.deepseek]
model = "deepseek-chat"

[provider.ollama]
base_url = "http://localhost:11434"
model = "codestral"

[models]

Global model defaults (applied when not set per-provider):

[models]
max_tokens = 4096
temperature = 0.7

[tui]

Terminal UI appearance and behavior.

[tui]
markdown = true       # render markdown in responses
streaming = true      # stream tokens as they arrive
theme = "dark"        # "dark" | "light"
accent = "copper"     # accent color name
show_thinking = true  # show model reasoning blocks
output_style = "normal"  # "normal" | "verbose" | "minimal" | "structured"

[tui.notify]
bell = true           # terminal bell on completion
desktop = false       # OS-level desktop notification
min_duration_ms = 5000  # only notify if turn took longer than this

[agent]

Core agent behavior.

[agent]
max_steps = 100                # max tool calls per turn
max_tokens = 200000            # context window budget
custom_instructions = ""       # extra instructions injected into system prompt
auto_compact_threshold = 0.8   # compact context when this % of window is used
compact_instructions = ""      # custom instructions for compaction
enforce_todos = false          # require todo tracking
auto_simplify = false          # auto-simplify when context is tight
auto_commit = false            # auto-commit after each turn
model_profile = ""             # model-specific tuning profile
subagent_model = ""            # model for spawned subagents

[agent.trust]

Permission system that controls what the agent can do without asking.

[agent.trust]
mode = "limited"     # "off" | "limited" | "autoedit" | "full"
allow_tools = []     # explicit allow list (empty = all allowed minus deny)
deny_tools = ["git_commit"]  # tools that always need approval
allow_paths = []     # paths the agent can freely modify
deny_paths = [".env", "secrets/"]  # paths the agent cannot touch
auto_approve = false   # auto-approve all permission requests
always_ask = false     # always ask, even for safe operations
remember_approvals = true  # remember per-tool approvals for the session

Trust modes explained:

ModeReadsEditsShellDescription
offAskAskAskEverything needs approval
limitedAutoAskAskReads are free, writes need approval
autoeditAutoAutoAskFile edits are free, shell needs approval
fullAutoAutoAutoFull autonomy — use with caution

Aliases: autoedit, auto_edit, and auto-edit all work.

[agent.retry]

Automatic retry on transient failures.

[agent.retry]
max_retries = 3
initial_backoff_ms = 1000
max_backoff_ms = 30000

[agent.routing]

Automatic model routing based on prompt complexity.

[agent.routing]
enabled = false
low_keywords = ["fix typo", "rename"]     # route to smaller model
high_keywords = ["refactor", "architect"]  # route to larger model

[agent.verify]

Verification checks that run after the agent completes a task.

[[agent.verify.checks]]
kind = "command"
command = "npm test"

[[agent.verify.checks]]
kind = "command"
command = "cargo clippy"

[agent.agents]

Subagent settings.

[agent.agents]
max_threads = 4   # max concurrent subagents
max_depth = 2     # max nesting (agent spawning agent)

[agent.agents.roles.researcher]
description = "Read-only exploration agent"
read_only = true
allowed_tools = ["read", "grep", "glob", "semantic_search"]
max_steps = 30

[agent.sharing]

Session sharing via Cloudflare Pages.

[agent.sharing]
enabled = false
pages_project = ""
domain = ""
redact_patterns = ["API_KEY", "SECRET"]

[agent.voice]

Voice input support.

[agent.voice]
enabled = false
api_key_env = "OPENAI_API_KEY"
model = "whisper-1"

[agent.hooks]

Event-driven automation. See the Hooks guide for full details.

[[agent.hooks]]
event = "after_edit"
command = "prettier --write {file}"
timeout = 10

[[agent.hooks]]
event = "after_turn"
hook_type = "command"
command = "npm test"
block = true

Supported events: session_start, user_prompt_submit, pre_tool_use, post_tool_use, post_tool_use_failure, permission_request, notification, after_edit, after_turn, subagent_start, subagent_end, compact_context, worktree_create, worktree_remove, config_change, teammate_idle, task_completed.

[mcp]

Model Context Protocol server connections.

# stdio transport
[mcp.servers.my-tool]
command = "npx"
args = ["-y", "@my/mcp-server"]
env = { API_KEY = "..." }

# HTTP transport
[mcp.servers.remote-tool]
url = "https://mcp.example.com/sse"
headers = { Authorization = "Bearer ..." }

[shell]

Shell configuration and sandboxing.

[shell]
path = "/bin/zsh"
env = { NODE_ENV = "development" }
startup_commands = ["source ~/.nvm/nvm.sh"]

[shell.sandbox]
enabled = false
allow_network = true
allow_read = ["/usr/local", "/opt/homebrew"]
allow_write = []
block_dotfiles = true

[browser]

Browser automation settings.

[browser]
enabled = false
executable_path = ""   # path to Chrome/Chromium
headless = true

[memory]

Persistent memory across sessions.

[memory]
auto_memory = true   # automatically save and recall context

[index]

Semantic code index for auto-context.

[index]
enabled = true
embedding = "auto"         # "auto" | "voyage" | "openai" | "perplexity" | "tfidf"
embedding_model = ""       # override specific model
auto_context = true        # inject relevant code into prompts
auto_context_chunks = 5    # how many chunks to inject
exclude = ["target/**", "node_modules/**", "dist/**"]

[update]

Self-update behavior.

[update]
enabled = true
check_interval_hours = 4
release_url = "https://get.nyzhi.com"  # global only — cannot be overridden

[external_notify]

External notification integrations.

[external_notify]
webhook_url = ""
telegram_bot_token = ""
telegram_chat_id = ""
discord_webhook_url = ""
slack_webhook_url = ""

CLI Overrides

Some flags override config at runtime:

FlagEffect
--trust fullSets agent.trust.mode to full
nyz exec --full-autoSets trust to full + sandbox to workspace-write
nyz exec --sandboxSets runtime sandbox level
--provider <id>Overrides provider.default
--model <name>Overrides the model for the active provider

File Locations Summary

WhatPath
Config directory~/.config/nyzhi/
Data directory~/.local/share/nyzhi/
Sessions~/.local/share/nyzhi/sessions/
Auth store~/.local/share/nyzhi/auth.json

Next Steps

  • Authentication — API keys, OAuth, multi-account setup
  • Providers — full provider list and model options
  • Hooks — automate workflows with event-driven hooks