A fast, low-footprint MCP server for the Nix ecosystem, written in Go. It is a drop-in reimplementation of mcp-nixos with the same two-tool surface and output, but as a single static binary (~tens of MB RSS instead of a ~150 MB Python runtime).
- stdio and HTTP transports — standalone or behind a proxy.
- MCP roots (incl. the
X-Mcp-RootHTTP header) so one HTTP instance can serve many clients/worktrees;flake-inputsresolves the flake directory from the calling client's root. - Live data: queries search.nixos.org (Elasticsearch), NixHub, FlakeHub,
cache.nixos.org, the NixOS wiki, nix.dev, Noogle, and the Home Manager /
nix-darwin / Nixvim option docs — faster and more current than
nix search. - No runtime deps beyond
nixitself, and only forflake-inputs(which shells out tonix flake archive); everything else is pure Go.
Nix (binary cache at nix.stubbe.dev):
nix run github:stubbedev/nix-mcpGo:
go install github.com/stubbedev/nix-mcp@lateststdio (default):
nix-mcpHTTP (multi-client; one shared server):
nix-mcp --http # 127.0.0.1:8765/mcp
# or: nix-mcp --http=0.0.0.0:9000 --http-path=/mcpBehind a proxy, pin the workspace root per request so flake-inputs targets
the right project:
X-Mcp-Root: /path/to/flake-project
Example MCP client config (stdio):
{
"mcpServers": {
"nix": {
"command": "nix-mcp"
}
}
}| Env var | Default | Purpose |
|---|---|---|
NIX_MCP_HTTP |
— | Truthy (1/true) enables HTTP on the default 127.0.0.1:8765. |
NIX_MCP_HTTP_ADDR |
— | Enable HTTP on this address (or use --http). |
NIX_MCP_HTTP_PATH |
/mcp |
HTTP endpoint path (--http-path). |
NIX_MCP_TOKEN |
— | If set, HTTP clients must send it as Authorization: Bearer <token> (or X-Mcp-Token). Ignored for stdio. |
For drop-in compatibility with the Python mcp-nixos service, the
MCP_NIXOS_TRANSPORT=http / MCP_NIXOS_HOST / MCP_NIXOS_PORT /
MCP_NIXOS_PATH env vars are also honored.
Two tools are exposed (no gating — both are always available):
nix— unifiedactiondispatcher:action=search— keyword search.sourceone ofnixos(default),home-manager,darwin,flakes,flakehub,nixvim,wiki,nix-dev,noogle,nixhub. Forsource=nixos,typeispackages/options/programs/flakes.action=info— details for an exact name (package/option, HM/darwin/nixvim option, flakehuborg/project, wiki page, nix.dev page, noogle function, nixhub package).action=stats— counts per source.action=browse— walk an option tree by prefix (home-manager,darwin,nixvim,noogle).action=channels— list NixOS channels with indexed/branch revisions.action=flake-inputs—type=list|ls|readover a flake's inputs (uses the client root /sourcepath; requiresnixon PATH).action=cache— binary-cache status for a package across systems.action=store—type=ls|readof an absolute/nix/store/path.
nix_versions— package version history from NixHub (which nixpkgs commit shipped version X, attribute path, platforms, dates).
Improvements over the upstream mcp-nixos (whose scrapers for these had broken):
- flakes — the search index generation (
latest-N-group-manual) is now discovered at runtime instead of hardcoded, so flake search/stats work again (upstream's index data is currently sparse, but the query is correct). - home-manager / nixvim — these upstreams replaced their scrapeable docs with formats that expose no bulk/queryable endpoint (paginated mdBook HTML / a binary WASM-decoded index). These sources return a clear "unavailable" message instead of silently empty results. nixos and darwin option search are unaffected and work.
just build # compile
just test # go test ./...
just lint # format + vet + golangci-lint
just check # everything CI runsReleases are cut with just release-patch|minor|major (tags vX.Y.Z), which
trigger multi-arch binary builds, the nix cache push, and the GitHub release.
MIT