Tools#

Nixi uses tools to interact with your NixOS system. The LLM decides which tools to call based on your request.

LLM Models#

Your choice of model directly affects how reliably Nixi can use tools. Larger models are significantly better at selecting the right tool, passing correct parameters, and chaining multi-step operations.

Model sizeTool reliabilityRecommendation
70B+ExcellentBest results, recommended for production use
30BGoodSolid for most tasks, the sweet spot for homelab hardware
7-14BInconsistentSimple tasks work, complex multi-tool flows may fail
< 7BPoorFrequently hallucinates tool names or passes wrong parameters

Warning: Models under 30B parameters can have issues reliably calling tools. You may see incorrect parameter types, hallucinated tool names, or skipped steps in multi-tool workflows. If you’re experiencing unreliable behavior, try a larger model before assuming a bug.

The default model (qwen3:30b-a3b) is a mixture-of-experts model that runs well on 16GB+ VRAM while delivering 30B-class tool calling accuracy. The installer recommends models based on your available memory.

You can switch models at any time with /model <name> in the TUI or Web UI.

Available Tools#

clock#

Returns current date, time, timezone, and system uptime. Always returns fresh data, so the LLM can call it mid-conversation to get the accurate current time.

Examples: “What time is it?”, “How long has the server been up?”, “What timezone is nixi-2 in?”

system_info#

Returns system information: hostname, OS, kernel version, NixOS version, memory, disk, and uptime.

Example: “What system am I running on?”

container#

Full container lifecycle management (Podman or Docker) with smart deployment from URLs.

Actions: list, inspect, deploy, update, start, stop, restart, remove, exec, logs, analyze

Examples:

  • “list my containers”
  • “deploy an nginx container called webserver on port 8080”
  • “deploy a minecraft server from github.com/itzg/docker-minecraft-server”
  • “deploy nextcloud with a postgres database”
  • “show me the webserver logs”
  • “exec redis-cli ping in the cache container”
  • “remove webserver” (asks for confirmation)
  • “stop all containers on nixi-2” (batch)
  • “remove redis and cache” (batch with single confirmation)

Key behaviors:

  • All containers join the nixi network by default, enabling container-to-container DNS by name
  • All container data must be stored under /srv/<container-name>/
  • Volume mounts accept /srv/ paths (container data) and /mnt/ paths (external NFS/SMB/USB mounts)
  • Mount external storage first with the mount tool, then bind into the container (e.g. /mnt/media:/media:ro)
  • Removing a container keeps its data in /srv/ unless you ask to purge it
  • Analyze: fetches a URL (GitHub repo, Docker Hub, docs page) and extracts deployment config (image, ports, volumes, env vars). Parses docker-compose.yml files automatically. The LLM then uses the extracted info to deploy, asking about unclear settings. Read-only, no confirmation needed.
  • Stacks: related services use stack naming – <stack> for the main service, <stack>-db for database, <stack>-cache for cache, etc. (e.g. nextcloud, nextcloud-db). All stack containers connect via container DNS on the nixi network. Dependencies are deployed first.
  • Deploy, update, and remove require user confirmation. Analyze is read-only.
  • Batch operations: start, stop, restart, and remove accept comma-separated names (e.g. redis,cache) or * for all containers. Batch remove shows one confirmation listing all targets. Port and name conflicts are detected before confirmation.

nixos#

NixOS system configuration, packages, firewall, upgrades, and management.

Actions: version, config-read, config-edit, rebuild, generations, rollback, services, reboot, firewall, package-search, package-list, package-install, package-remove, channels, channel-add, channel-remove, update, upgrade, garbage-collect

Examples:

  • “what version of nixos is this?”
  • “open port 8080 on the firewall”
  • “what ports are open?”
  • “close port 8080”
  • “rebuild the system”
  • “rollback to generation 3”
  • “restart the sshd service”
  • “any failed services?”
  • “enable the nginx service”
  • “show me the nixos config”
  • “search for htop”
  • “install nginx”
  • “install nginx, redis, and git” (batch, one rebuild)
  • “what packages are installed?”
  • “remove vim”
  • “what channel am I on?”
  • “switch to nixos-unstable”
  • “upgrade the system”
  • “clean up old generations, keep the last 3”

Key behaviors:

  • Config edits automatically trigger a rebuild (one confirmation for both)
  • Sensitive values (passwords, tokens, secrets) are redacted in config output
  • Rebuild, config-edit, rollback, and reboot require user confirmation
  • Firewall open/close require confirmation; firewall list does not
  • Service start/stop/restart/enable/disable do not require confirmation
  • Service enable/disable use systemctl and may not persist across NixOS rebuilds for NixOS-managed services
  • Package search uses nix search (falls back to nix-env without flakes)
  • Package install/remove modify environment.systemPackages in configuration.nix and rebuild
  • Batch packages: install/remove accept comma-separated names (e.g. nginx,redis,git). Config is edited once and rebuilt once, not per-package
  • Upgrade updates channels AND rebuilds the system, including kernel, drivers, and OS components
  • Kernel updates from upgrade take effect after reboot
  • Garbage-collect deletes old generations and runs nix-store --gc to free disk space (keeps 5 most recent by default)
  • Garbage collection is a good candidate for a scheduled recurring task via the scheduler tool

network#

Network diagnostics and connectivity testing.

Actions: interfaces, dns, firewall, ports, ping, resolve, route

Examples:

  • “what’s my IP address?”
  • “can I reach google.com?”
  • “what ports are listening?”
  • “show me the firewall rules”
  • “resolve docs.nixi.sh”

All network actions are read-only and require no confirmation.

logs#

Query systemd journal logs for troubleshooting and diagnostics.

Actions: query, boot, units, kernel

Examples:

  • “show me the sshd logs”
  • “any errors in the last hour?”
  • “what happened during the last boot?”
  • “show kernel messages”
  • “check nginx logs for 404 errors”
  • “list all running services”

Key behaviors:

  • Logs are read-only and require no confirmation
  • Default 50 lines, max 200 per query
  • Supports time ranges (since, until), priority filtering, and grep patterns
  • Sensitive values (passwords, tokens) in log output are redacted before display, but the LLM can still use them for troubleshooting

mount#

Manage NFS, SMB/CIFS, and USB drive mounts. Designed for homelab NAS integration with services like Plex, Jellyfin, and Immich.

Actions: list, devices, mount, unmount, persist

Examples:

  • “list my mounts”
  • “show available drives”
  • “mount the NFS share at 192.168.1.10:/media”
  • “mount SMB share //nas/movies with username erik”
  • “mount the public share from //nas/public” (anonymous/guest mount)
  • “unmount /mnt/media”
  • “unmount all mounts” (batch)
  • “make the media mount persistent”

Key behaviors:

  • Mount points default to /mnt/<share-name>, must be under /mnt/ or /srv/
  • SMB supports both authenticated and anonymous (guest) mounts
  • SMB credentials are stored securely in /srv/.credentials/ (root-owned, mode 600), never in NixOS config
  • SMB auto-retries with older protocol versions (3.0, 2.1, 2.0) if the default fails
  • Persistent mounts use NixOS fileSystems with x-systemd.automount to avoid boot hangs when the NAS is offline
  • Mount, list, and devices do not require confirmation
  • Unmount and persist require user confirmation
  • Batch unmount: accepts comma-separated paths (e.g. /mnt/nas,/mnt/media) or * for all non-system mounts under /mnt/ and /srv/
  • After mounting a share for a container, use it as a volume bind (e.g. /mnt/media:/media:ro)
  • Requires cifs-utils (SMB) and nfs-utils (NFS) in system packages

users#

NixOS user management for homelab and server environments.

Actions: list, add, remove, groups, ssh-keys, password, shell, lock, unlock

Examples:

  • “list users”
  • “add user erik with wheel and users groups”
  • “add SSH key for deploy user”
  • “remove user guest”
  • “add erik to the podman group”
  • “change erik’s shell to zsh”
  • “set password for testuser”
  • “lock user guest”

Key behaviors:

  • Users are declarative in NixOS configuration.nix – add, remove, groups, and shell trigger a rebuild
  • SSH keys are file-based (~/.ssh/authorized_keys) for instant updates without rebuild
  • Password, lock, and unlock are direct commands, no rebuild needed
  • Username validation: lowercase alphanumeric, hyphens, underscores only. System users (root, nixi) are protected.
  • Common groups: wheel (sudo), podman/docker, networkmanager, users

nvidia#

NVIDIA GPU detection, driver management, and monitoring.

Actions: status, enable, disable, configure

Examples:

  • “do I have a GPU?”
  • “enable NVIDIA drivers”
  • “show GPU utilization”
  • “disable NVIDIA support”
  • “enable NVIDIA power management”
  • “switch to the open NVIDIA driver”

Key behaviors:

  • Returns soft failure (“No NVIDIA GPU detected”) on systems without NVIDIA hardware
  • Detection uses lspci (works without drivers installed)
  • status shows GPU model, driver version, CUDA version, memory, utilization, temperature, and NixOS config state
  • enable adds all required NixOS config: unfree packages, graphics, NVIDIA kernel module (proprietary), modesetting, and container toolkit for GPU passthrough
  • enable requires a reboot after rebuild for the kernel module to load
  • disable removes NVIDIA-specific config but keeps allowUnfree and hardware.graphics as they may be needed for other packages
  • configure tunes driver settings:
    • power_management – enable/disable suspend/resume support
    • open_driver – switch between open (Turing+ GPUs only) and proprietary kernel module
  • Enable, disable, and configure require user confirmation
  • The install script also auto-detects NVIDIA GPUs and offers to configure drivers during initial setup
  • Previously named gpu, renamed to nvidia to allow a separate amdgpu tool

amdgpu#

AMD GPU detection, driver configuration, and monitoring.

Actions: status, enable, disable, configure

Examples:

  • “do I have an AMD GPU?”
  • “enable amdgpu drivers”
  • “show GPU utilization”
  • “disable AMD GPU support”
  • “set GTT size to 8192”
  • “set ROCm override to 11.0.0 for my APU”

Key behaviors:

  • Returns soft failure (“No AMD GPU detected”) on systems without AMD GPU hardware
  • Detection uses lspci (works without drivers configured)
  • AMD uses the open-source amdgpu kernel driver, no unfree packages needed
  • status shows GPU model, VRAM usage, GTT (shared RAM) usage, utilization, temperature, power draw, kernel module state, and NixOS config
  • Automatically detects APUs (integrated GPUs) and shows shared memory details with performance notes
  • Runtime metrics are read directly from sysfs (/sys/class/drm/)
  • enable loads the amdgpu kernel module early via initrd for early KMS, sets the video driver, enables hardware graphics, enables ROCm HIP runtime + OpenCL for GPU compute (LLM acceleration via Ollama, llama.cpp, etc.), and creates the /opt/rocm/hip symlink. For APUs, also configures Ollama service with rocmOverrideGfx and GTT shared memory env vars (GPU_MAX_ALLOC_PERCENT, HSA_ENABLE_SDMA)
  • disable removes amdgpu-specific config, ROCm HIP/OpenCL, the /opt/rocm/hip symlink, and Ollama ROCm config, then rebuilds
  • configure tunes driver settings:
    • gtt_size – set GTT shared memory size in MB (controls how much system RAM the GPU can access, useful for APUs)
    • rocm_override – set HSA_OVERRIDE_GFX_VERSION for APU or older GPU ROCm compatibility
  • Enable, disable, and configure require user confirmation

scheduler#

Manage scheduled tasks using systemd timers. Supports both recurring cron-like schedules and one-shot future actions.

Actions: list, create, remove, status, enable, disable

Examples:

  • “back up /srv/ every night at 3 AM”
  • “reboot the server in 2 hours”
  • “run a cleanup script every Monday at 6 AM”
  • “list my scheduled tasks”
  • “cancel the reboot timer”
  • “disable the backup timer”

Key behaviors:

  • Uses systemd timers and service units under /etc/systemd/system/ with a nixi- prefix
  • Recurring schedules use systemd calendar syntax (daily, *-*-* 03:00:00, Mon *-*-* 09:00:00, hourly, weekly)
  • One-shot delays use duration syntax (30m, 2h, 1d)
  • Recurring timers use Persistent=true so missed runs catch up after reboot
  • One-shot timers remain after firing and can be removed with the remove action
  • Create and remove require user confirmation
  • List, status, enable, and disable do not require confirmation

memory#

Persistent memory that survives across conversations. The LLM saves and recalls facts about your system, services, and preferences using a local SQLite database with full-text search.

Actions: save, search, list, delete

Examples:

  • “remember that I prefer port 8080 for web services”
  • “what do you know about my system?”
  • “list my memories”
  • “forget memory #3”

Key behaviors:

  • Memories persist across conversations and /clear – they are stored in ~/.local/share/nixi/memory.db
  • Relevant memories are automatically recalled and injected into context when you ask a question
  • The LLM is instructed to save facts proactively (system info, deployed services, preferences)
  • Categories: system, service, preference, general
  • No confirmation required for memory operations
  • Use the /memories slash command to view all saved memories directly

files#

Read, write, list, and manage files on the system.

Actions: read, write, list, delete, mkdir, stat

Examples:

  • “show me the nginx config in /srv/webserver/”
  • “list the files in /srv/”
  • “write a config file to /srv/myapp/config.yml”
  • “create a directory at /srv/newservice/data”

Key behaviors:

  • File access is scoped to /srv/, /etc/nixos/, /tmp/, and /home/
  • Path traversal (..) is blocked
  • Write and delete require user confirmation
  • Uses sudo automatically for /srv/ and /etc/ paths

For details on confirmations, file system boundaries, sensitive data handling, and sudo access, see the Security page.

Nodes#

What it does: List configured nodes with connectivity status, and remove nodes.

Actions: list, remove, setup

ActionNeeds ConfirmationDescription
listNoShow all nodes with SSH connectivity status
removeYesRemove a node from config and clear SSH known host
setupYesConfigure sudo rules, container runtime (Podman/Docker), mount utilities, and /srv/ on a remote node

Examples:

  • “list all nodes”
  • “show me the node status”
  • “set up nixi-2” (configures remote node for Nixi management)
  • “remove the monitoring node”

Key behaviors:

  • The local controller node appears as hostname (local) with its IP
  • SSH connectivity is probed in parallel for fast status checks
  • Node names are fuzzy-matched to catch typos
  • To adopt a new node, use the /adopt TUI command (passwords are handled securely, never sent to the LLM)
  • See Multi-Node for the full guide

Multi-Node Support#

Every tool accepts an optional node parameter. If omitted, the tool runs on the local (controller) node. Remote nodes are reached via SSH. Nodes can be in managed (full control) or monitored (read-only) mode. See Multi-Node for details.

Adding Custom Tools#

Tools implement a simple Go interface:

type Tool interface {
    Name() string
    Description() string
    Parameters() map[string]interface{}
    Notes() string
    Execute(ctx context.Context, exec Executor, args json.RawMessage) (string, error)
}

Key points:

  • Use the Executor interface for all command execution, never os/exec directly. This ensures your tool works on both local and remote nodes.
  • Parameters() returns a JSON schema. The registry automatically injects a node parameter.
  • Notes() returns optional guidance that gets injected into the system prompt.
  • Register your tool in internal/agent/agent.go via reg.Register(&YourTool{}).

Error Handling#

Tools use fuzzy matching on names. If the LLM calls a tool that doesn’t exist, Nixi suggests the closest match (e.g., “did you mean system_info?”). Nixi also retries failed tool calls by diagnosing the error before giving up.