Onboard an unfamiliar NixOS or Home Manager flake by running nix-agent inspect-flake and generating AGENT_MAP.md, CLAUDE.md, and .mcp.json from observed facts. Use on first contact with a config repo, when the user asks how the flake is laid out, or when making the repo agent-ready. Requires the nix-agent MCP server.
Scanned 8/30/2026
Install to Claude Code
npx -y skills add JEFF7712/nix-agent --skill nix-agent-init --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Nix Agent Init?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jeff7712-nix-agent-init)More formats (shields.io, HTML) on the badges page.
---
name: nix-agent-init
description: Onboard an unfamiliar NixOS or Home Manager flake by running nix-agent inspect-flake and generating AGENT_MAP.md, CLAUDE.md, and .mcp.json from observed facts. Use on first contact with a config repo, when the user asks how the flake is laid out, or when making the repo agent-ready. Requires the nix-agent MCP server.
---
# Nix Agent Init
## Overview
Make a NixOS/Home Manager config repo agent-ready in one pass. Run
`nix-agent inspect-flake` once, then generate three artifacts, each derived
from the returned facts and the files you actually read:
- `AGENT_MAP.md`: task-routing table plus search shortcuts.
- `CLAUDE.md` (+ `AGENTS.md`): a one-screen repo brief.
- `.mcp.json`: wires `nix-agent` and `mcp-nixos`.
Everything you write must trace back to an observed fact. A sparse repo
gets a short map; a rich repo gets a longer one. Never pad with generic
NixOS advice, aspirational structure, or rules the facts do not support.
If a fact is null or "unknown", say so or omit the row. Do not invent.
You do not run `nix flake show` yourself: `nix-agent inspect-flake` does.
You do read the repo's own files (module dirs, flake.nix) with your native
tools to name real files in the tables.
## Step 1: Inspect
Run `nix-agent inspect-flake` (via Bash); it prints the fact bundle as JSON.
With no argument it auto-resolves the target; if the user named a repo, pass
the path: `nix-agent inspect-flake /path/to/repo`.
The returned facts drive every decision below:
- `flake_dir`: absolute repo path. Pin `.mcp.json` to this.
- `hosts`: nixosConfiguration names. `null` means flake show failed.
- `home_configurations`: standalone HM outputs.
- `hm_integration`: `"integrated"`, `"standalone"`, `"none"`, or
`"unknown"`.
- `module_dirs`: dirs where module files actually live.
- `auto_import`: `"import-tree"`, `"none"`, or `"unknown"`.
- `formatter`: `"treefmt"`, `"nixfmt"`, a passthrough name, or `"none"`.
- `lint_tools`: subset of `["deadnix", "statix"]` on PATH.
- `has_justfile`, `has_ci`: booleans.
- `mcp_json`: `"present"` or `"absent"`.
If `hosts` is `null` (flake show failed), note in `CLAUDE.md` which facts
are unavailable and read `note` / `first_error`, then continue with the
file-level facts only (`module_dirs`, `auto_import`, `has_justfile`,
`mcp_json`). Do not stall.
Read the `module_dirs` with your native tools so the routing table names
real files (`hosts/laptop.nix`, `modules/nixos/desktop.nix`), not
placeholders. If `module_dirs` is empty, the table stays generic and
short; that is correct, not a gap to fill.
## Step 2: AGENT_MAP.md
A task-routing table plus search shortcuts, both keyed to the layout you
observed. Columns: Task, Inspect first, Usually edit, Validate.
Derive the **Validate** column from `has_justfile`:
- `has_justfile == true`: read the justfile and map validation to its real
recipes (`just check`, `just switch`). Cite recipes that exist, not ones
you assume.
- otherwise: the nix-agent ladder, `check("lint")` then
`check("dry-build")` then `diff()` then `switch()`. Drop `check("lint")`
from the recommendation if `lint_tools` is empty.
Derive **Usually edit** targets from `module_dirs` and the files you read.
One row per real task the layout supports (add a package, change a host
option, edit an HM program). Do not emit rows for structure the repo does
not have.
Add a **Search shortcuts** section keyed to the repo's actual directory
names, so an agent greps the right place. Add an **Edit rules** section
only for rules the facts support, for example:
- `auto_import == "import-tree"`: "Drop a new `.nix` file into
`<module_dir>`; it is imported automatically, no manual import line."
- `auto_import == "none"`: note that new modules need an explicit import.
Skeleton (this is the *shape*, not the content; every cell must come from
this repo's facts):
```markdown
<!-- generated by nix-agent /init -->
# Agent Map
<!-- nix-agent:begin routing -->
| Task | Inspect first | Usually edit | Validate |
| --- | --- | --- | --- |
| Add a system package | `eval_config("environment.systemPackages")` | `modules/nixos/packages.nix` | `check("dry-build")` then `diff()` then `switch()` |
<!-- nix-agent:end routing -->
<!-- nix-agent:begin search -->
## Search shortcuts
- Host definitions: `hosts/`
- NixOS modules: `modules/nixos/`
<!-- nix-agent:end search -->
```
## Step 3: CLAUDE.md and AGENTS.md
A one-screen repo brief. Include only what the facts establish: what this
repo is, its `hosts`, its HM mode, the validation commands (justfile
recipes or the nix-agent ladder), and gotchas the facts support.
When `hm_integration == "integrated"`, state the mode trap plainly: Home
Manager is wired in as a NixOS module, there is no separate
`home-manager switch`, and nix-agent calls that touch HM options must use
`mode="nixos"` (the default) with the attr spelled
`home-manager.users.<user>.<attr>`.
When `hm_integration == "standalone"`, note that HM is its own flake and
its operations use `mode="home-manager"`.
When `hm_integration == "unknown"`, the facts were inconclusive
(lock-file presence alone does not prove integration). Say that. Do not
write a hard mode rule.
Keep it to one screen. Do not restage generic NixOS tutorials. When the
brief includes the nix-agent ladder, state that the default is apply:
`diff()` then `switch()` without waiting, unless the user asked only to
preview or check.
Then create `AGENTS.md` as a symlink to `CLAUDE.md`:
```bash
ln -s CLAUDE.md AGENTS.md
```
If the platform cannot symlink, write `AGENTS.md` as a copy carrying the
same markers.
## Step 4: .mcp.json
Wire both servers. Pin `NIX_AGENT_FLAKE` to `flake_dir`. Append `#<host>`
only when exactly one host exists; with several hosts, pin the bare dir
(hostname resolution and unique-host fallback pick the attr). List the
hosts in `CLAUDE.md`. Do not wait for the user to pick one. Never put a
secret, token, or password in this file.
```json
{
"mcpServers": {
"nix-agent": {
"command": "nix-agent",
"env": { "NIX_AGENT_FLAKE": "<flake_dir>[#<host>]" }
},
"mcp-nixos": {
"command": "mcp-nixos"
}
}
}
```
Match the host's actual MCP config schema if it differs from this shape;
the constants are the two server names and the `NIX_AGENT_FLAKE` pin.
## Marker and no-clobber contract
This is exact and testable. Follow it verbatim.
- Every file you generate starts with the header line, on its own line:
```
<!-- generated by nix-agent /init -->
```
- Each section you own is bounded by a matched pair:
```
<!-- nix-agent:begin <section> -->
...generated content...
<!-- nix-agent:end <section> -->
```
- On a **re-run**, regenerate ONLY the content between marker pairs. Text
the user added outside any marked section is left byte-for-byte intact.
- If a target file already exists and does NOT contain the header marker,
it is hand-written. Do NOT write it. Instead show the proposed content
as a diff and let the user decide. This holds for `CLAUDE.md`,
`AGENT_MAP.md`, and `.mcp.json` alike. `.mcp.json` is JSON and cannot
carry HTML comments, so treat ANY existing `.mcp.json` as hand-written:
propose the merged content as a diff, never silently replace it.
## What not to do
- No validation infrastructure. Do not create justfiles, CI workflows, or
git hooks. Report the ladder; do not build one.
- No editing hand-written docs. Existing unmarked `CLAUDE.md` /
`AGENT_MAP.md` are proposed-as-diff only, never overwritten.
- No secrets in `.mcp.json`. Reference them via sops-nix/agenix elsewhere;
this file holds only the flake pin and server names.
- No boilerplate. Every line traces to a fact from `nix-agent inspect-flake`
or a file you read. When a fact is missing, omit the line.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!