The whole AI toolkit, in one flake. nix run and go.
nix-ai is the package and config layer for everything AI-coding-related. It packages command-line
tools that don’t yet have first-party Nix derivations. It also pins MCP server versions and exports
overlays that the rest of the Nix stack consumes.
Host-specific provider wiring is intentionally outside nix-ai. If a tool needs
to point at a private local LLM gateway, package the tool here. Then keep the
endpoint and token-source module in the consuming workstation flake. That keeps
reusable packaging public and environment topology private.
What it does
- Packages Claude Code, the Antigravity (
agy) command-line tool, the GitHub Copilot command-line tool, Cribl and Splunk operator command-line tools, and assorted AI tooling - Tracks the operator command-line tool sources through the flake lock, so consumers can gate their installation to workstation hosts
- Provides MLX module derivations for Apple Silicon
- Pins a catalog of MCP servers and exposes them as reusable Nix attributes; most of the catalog is on-demand, not always-on (see below)
- Exports an overlay so
nix-darwinandnix-homecan include AI tools without duplicating logic - Includes a shell module (
devShells.default) for a ready-made AI sandbox
How it fits
Configuration surface
nix-ai ships as a reusable flake module with a single knob surface: modules/maintainer-profile.nix. This is the one file a consumer touches to adapt the stack:
- Identity fields (
user.fullName,user.trustedOrgs) have maintainer defaults, so derived values (for example, the Claude auto-mode trusted-org list) stay internally consistent. Override them for your own identity. - Infrastructure fields (
homelab.*,telemetry.*,trustedProjectDirs) default to clean/off/empty, so the module evaluates to a neutral config with zero consumer input. No personal context ships in the flake.
userConfig via _module.args so nothing outside maintainer-profile.nix needs to
import it directly. A consumer overrides values either in their own nix-darwin config (via
extraSpecialArgs) or by importing the module and setting options.
Secrets and injection
Runtime secrets are never stored in Nix store paths or committed files. Four injection patterns are in use:
Source-control credentials use none of these. They are short-lived tokens
minted on demand per request. They are never written to disk: not to the Keychain, not
to a
.env, and not to a direnv cache. Direnv persists its environment dump
on disk, which would turn a mint-time credential into a stored one. The Keychain row
preceding this covers third-party service keys only. Treat any older guidance that routes
source-control credentials through it as retired.
The Splunk entry is one shared catalog item rendered for Claude, Codex, Qwen,
and the Antigravity command-line tool and IDE surfaces. Antigravity (agy) is the
Gemini-family harness; it is not a second Gemini MCP identity. Hermes uses the
same Splunk connection through its machine AppRole. Terrakube workload
identity applies only to remote Terrakube jobs, not interactive workstation
agents.
The variable catalog (required vs optional, purpose, source) lives in .env.example at the repo
root. A real .env is an opt-in convenience; direct injection is preferred. The local injection
runbook is AGENTS.local.md (gitignored).
On-demand MCP servers
MCP tool schemas are the largest addressable per-session token cost. So most local servers stay out of the always-on profile:apple-events, zammad,
fabric, grep, time, and token-meter render to
~/.claude/mcp-available/<name>.json instead of loading at session start.
The always-on profile carries only what the gateway routes (context7,
memory) plus vikunja. Codex was removed from the catalog entirely. See
Multi-model review for how it’s
invoked now.
A repository attaches on-demand servers through its skill groups instead of listing
them by hand: programs.agentSkills.groupMcpServers maps a group to server names
(default homelab → zammad; ai → fabric, grep, time, token-meter), and the
direnv linker unions those with any AGENTS.md mcp-servers: frontmatter into the
managed part of an untracked .mcp.json. Ten rarely used Zammad tools stay denied by
bare-name permission rules so their schemas never reach context even when the server
attaches. The curated on-demand list is a config-level definition, so a consuming host
can append a server without losing the default set.
Getting started
1
Try a single tool
nix run github:JacobPEvans/nix-ai#claude-code -- --help. No clone needed.2
Enter the sandbox shell
nix develop github:JacobPEvans/nix-ai drops you into a shell with every AI command-line tool on PATH.3
Import into nix-darwin
Add
nix-ai as a flake input, then include nix-ai.overlays.default in your nixpkgs config. The README has the boilerplate.4
Override the maintainer profile
Set
userConfig.user.fullName and any homelab.* / telemetry.* options in your own config to adapt the stack to your environment.Related repos
ai-assistant-instructions
The rules layer. nix-ai packages the tools; this configures them.
claude-code-plugins
Extension layer on top of the packaged Claude Code CLI.
nix-darwin
The system-level consumer.
Local LLM
How the packaged MLX stack runs and is tuned on Apple Silicon.
Source on GitHub
Packages, overlays, full README.