# mcp-nixos: an MCP server that gives AI assistants real NixOS package and option data

> mcp-nixos is a Model Context Protocol server that answers package, option and flake queries from live NixOS sources instead of letting a model invent names. It installs with uvx, Nix, Docker or HTTP, and it does not require Nix on the host.

**utensils/mcp-nixos** — MCP-NixOS - Model Context Protocol Server for NixOS resources

- Repository: https://github.com/utensils/mcp-nixos
- Website: https://mcp-nixos.io/
- Stars: 848 · Forks: 45
- Language: Python
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/utensils-mcp-nixos

## The problem mcp-nixos addresses: invented Nix attribute names

Language models are good at Nix syntax and bad at Nix facts. Ask one for the option that enables a service and you get a plausible `services.foo.enable` that no channel ever had. The failure is quiet: the expression parses, the build fails later, and the correction loop costs more than the lookup would have.

mcp-nixos is a Model Context Protocol server that answers those lookups from real sources. The README frames the project bluntly: it exists so an AI does not hallucinate package names. The audience is narrow and specific. You need an MCP-capable client (Claude, Cursor and Pi are the ones the README walks through) and you need to work with NixOS, Home Manager, nix-darwin, Nixvim or NVF configuration. The server itself runs anywhere. The README states that no Nix or NixOS installation is required, because the server queries APIs rather than evaluating a local Nix expression. That matters on macOS and Windows, where a full Nix evaluation environment is a real cost.

There is one exception to the no-Nix claim, and it is worth knowing before you install: the `flake-inputs` and `store` actions read from the local Nix store, and the README marks both as requiring Nix.

## Two tools, eleven sources, and why the consolidation matters

The README says the project consolidated 17 tools into 2, on the argument that a model's context window is finite. The published budget is about 1,030 tokens in total. Whether or not that number holds in your client, the design choice is the interesting part: instead of one MCP tool per data source, there is a single `nix` tool with an `action` parameter and a `source` parameter, and the model picks a combination.

The signature given in the README is `nix(action, query, source, type, channel, limit, version, system)`. The `version` and `system` arguments are only used when `action="cache"`. Actions are `search`, `info`, `stats`, `browse`, `channels`, `flake-inputs`, `cache` and `store`. Sources are `nixos`, `home-manager`, `darwin`, `flakes`, `flakehub`, `nixvim`, `nvf`, `noogle`, `wiki`, `nix-dev` and `nixhub`. That is eleven sources behind one tool definition, which is how the token count stays low.

The data flow is HTTP plus HTML parsing, not a local evaluation. The dependencies in `pyproject.toml` are `fastmcp>=4.0.0`, `requests>=2.32.4` and `beautifulsoup4>=4.13.4`. BeautifulSoup in a dependency list means at least some sources are scraped from rendered pages rather than consumed as JSON APIs. That is a maintainability trade-off the project accepts in exchange for covering sources that publish documentation but not a machine-readable index. If one of those sites changes its markup, the corresponding source breaks until the parser is updated.

One detail shows the care taken with option paths. NVF results use canonical `vim.*` paths, and the README says queries written as `programs.nvf.vim.*` or `programs.nvf.settings.vim.*` are normalized automatically. Asking an assistant to remember which of three spellings a given source expects is exactly the kind of thing models get wrong, so normalizing on the server side is the right place for it.

## Installing mcp-nixos with uvx, Nix or Docker

The README lists four installation paths plus a Pi-specific route. The recommended one is uvx. You add a server entry to your MCP client's configuration, and the client starts the server as a subprocess. For a JSON-configured client, the entry looks like this:

```json
{
  "mcpServers": {
    "nixos": {
      "command": "uvx",
      "args": ["mcp-nixos"]
    }
  }
}
```

After restarting the client, the `nix` tool should appear in its tool list. Nothing else is needed on the machine, per the README, because the server reaches out to the upstream sources over the network.

If you would rather not depend on uvx, the Nix path runs the flake directly:

```json
{
  "mcpServers": {
    "nixos": {
      "command": "nix",
      "args": ["run", "github:utensils/mcp-nixos", "--"]
    }
  }
}
```

The Docker path pulls a published image and runs it attached to stdin and stdout, which is what an MCP stdio client expects:

```bash
{
  "mcpServers": {
    "nixos": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "ghcr.io/utensils/mcp-nixos"]
    }
  }
}
```

For a first real query, ask your assistant for a package you know exists and one you suspect does not. A search for `firefox` against the `nixos` source with `type="packages"` is the example the README gives. The useful signal is the negative case: when the model asks the server about a package that does not exist, it gets an empty result rather than a fabricated attribute path, and the answer it gives you should reflect that.

There is also a remote transport. FastMCP can serve this over HTTP, with the MCP endpoint defaulting to `/mcp`:

```bash
MCP_NIXOS_TRANSPORT=http MCP_NIXOS_HOST=127.0.0.1 MCP_NIXOS_PORT=8000 mcp-nixos
```

Setting `MCP_NIXOS_TRANSPORT=stdio` selects the default stdio mode explicitly. `MCP_NIXOS_PATH` changes the endpoint path, and `MCP_NIXOS_STATELESS_HTTP=1` disables per-client session state, which is the setting you want behind a load balancer or any setup where requests from one client may land on different workers.

## Where mcp-nixos is the wrong tool

The server is a lookup layer, not a Nix evaluator. It cannot tell you whether a configuration you wrote will build, it cannot resolve your overlays, and it cannot see your local `configuration.nix`. If your actual question is "why does this evaluation fail", mcp-nixos will not answer it, and reaching for it will waste a turn.

Network dependency is the second boundary. Every source except the local store actions is fetched over HTTP. On an air-gapped machine, in a restricted CI runner, or on a laptop with no connectivity, the server has nothing to return. The README does not document an offline cache or a fallback dataset, so plan for the failure mode rather than assuming one exists.

The scraping surface is the third. Because `beautifulsoup4` is a runtime dependency, sources that are parsed from HTML are only as stable as the pages they parse. A site redesign can break a source without any change to the server, and the failure will look like an empty result rather than an error. If you are wiring this into anything automated, treat an empty result from a scraped source as ambiguous: it may mean the thing you asked about does not exist, or it may mean the parser stopped matching.

Finally, consider whether you need a server at all. If you want to check one package name once, `search.nixos.org` in a browser is faster than installing and configuring an MCP client. The value here is in repeated lookups inside a conversation, where the alternative is the model guessing.

## How mcp-nixos differs from a general web-search MCP server

The obvious alternative is a general-purpose web search or fetch MCP server, which can also reach search.nixos.org. The difference is in what the model has to do. With a general fetcher, the model constructs a URL, receives a page of HTML or text, and extracts the answer itself. That works, but it puts the parsing and the judgement back on the model, and it burns context on markup. mcp-nixos moves that work server-side: the model calls `nix(action="info", query=..., source="nixos")` and gets a structured answer.

The second alternative is the local approach: run `nix search` or `nix eval` on your own machine. That is more accurate for your pinned revision and it works offline, but it requires Nix, it is slow on a cold store, and it only covers what your flake inputs contain. mcp-nixos covers Home Manager, nix-darwin, Nixvim, NVF, FlakeHub, Noogle, the NixOS Wiki and nix.dev in one interface, which a local `nix search` does not.

The third comparison is against other domain MCP servers. The README's own framing is the token budget: it claims about 1,030 tokens across two tools while other servers consume more. The claim is the project's, not something verified here, but the design that produces it is visible in the source list. A server with one tool per source would need eleven tool definitions; this one needs one.

## Maintenance, release cadence and what the MIT licence means here

The repository is not archived, and the last push was on 2026-09-05. Releases v3.0.1, v3.0.2 and v3.1.0 landed between 2026-08-12 and 2026-09-05, so the project is being released, and the `release-please-config.json` and `.release-please-manifest.json` files in the repository root indicate releases are automated rather than cut by hand.

The upgrade surface is small, which is the main reason the maintenance cost is low. The runtime dependencies are three packages: `fastmcp`, `requests` and `beautifulsoup4`. There is no database, no daemon and no state on disk. Upgrading means changing a version in your MCP client config or pulling a new image. The `pyproject.toml` requires Python 3.11 or newer and classifies 3.11, 3.12 and 3.13, with 3.14 commented out, so if you are pinned to 3.10 the uvx path will not work for you.

The real maintenance risk is not the server code but the upstream sources. Eleven sources means eleven things that can change independently of this project. The CI and Codecov badges in the README indicate a test suite exists, and the dev extras include `pytest`, `pytest-asyncio`, `pytest-xdist` and `pytest-rerunfailures`, but the README does not state how much of the scraping surface is covered by fixtures rather than live network calls. That is the first thing to check if you depend on a specific source.

On licensing: the project is MIT, and `pyproject.toml` declares `license = {text = "MIT"}` with the matching OSI classifier. MIT is permissive, so embedding the server in an internal toolchain is straightforward. Note that the licence covers this code, not the upstream data. The sources it queries include community documentation and third-party registries, and the README does not discuss the terms under which that content is served. If you plan to redistribute results, check the upstream sources directly; this is a factual observation about the repository, not legal advice.

## Conclusion

Adopt mcp-nixos if you already drive Claude, Cursor or another MCP client and you keep hitting invented Nix attribute names, since the server replaces guesses with live queries against search.nixos.org, Home Manager, nix-darwin, Nixvim, NVF, FlakeHub, Noogle, the NixOS Wiki, nix.dev and NixHub. Skip it if you only need a one-off package lookup, because a browser tab is cheaper than running a server. Before rolling it out, confirm the flake-inputs and store actions work on your machine, since both require Nix, and check the CI and Codecov badges on the repository to see what the test suite actually covers.

## FAQ

### What is NixOS used for, and what does mcp-nixos have to do with it?

NixOS is the Linux distribution whose packages and options this server queries, and the README lists NixOS packages, options and programs as the primary source behind the `nix` tool. You do not need NixOS installed to use the server, because it queries APIs rather than evaluating a local configuration.

### How is MCP different from an API?

An API is called by your own code; MCP is a protocol that exposes tools to an AI assistant, which decides when to call them. In mcp-nixos the assistant calls a single `nix` tool with an `action` and a `source`, and the server handles the underlying HTTP requests to sources such as search.nixos.org and NixHub.

### What are the downsides of using NixOS, and does mcp-nixos remove them?

mcp-nixos does not change NixOS itself; it only answers lookup questions about packages and options. It is a lookup layer rather than an evaluator, so it cannot tell you whether your own configuration will build, and every source except the local store actions needs network access.

### Does ChatGPT use MCP, and can it use mcp-nixos?

The README does not mention ChatGPT. It documents Claude, Cursor and Pi as the clients it supports, and any MCP client that can start a stdio subprocess can run the server through the uvx, Nix or Docker configuration.

## Sources

- [License: MIT](https://github.com/utensils/mcp-nixos/blob/main/LICENSE)
- [Project website](https://mcp-nixos.io/)
- [README](https://github.com/utensils/mcp-nixos/blob/main/README.md)
- [Releases](https://github.com/utensils/mcp-nixos/releases)
- [utensils/mcp-nixos on GitHub](https://github.com/utensils/mcp-nixos)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/utensils-mcp-nixos
