Documentation

#Overview

MCP-NixOS provides a set of tools to search, explore, and retrieve information about NixOS packages, options, and configurations. These tools are designed to make working with the Nix ecosystem more accessible and efficient through AI assistants and other interfaces.

Why Use MCP-NixOS?

MCP-NixOS is built as a standard I/O (stdio) implementation using FastMCP, the Pythonic framework for building Model Context Protocol servers. This allows seamless integration with AI assistants through the standardized MCP interface.

AI Integration

Designed for AI assistants to provide accurate Nix information

Unified Interface

Consistent access to NixOS, Home Manager, and nix-darwin

Rich Metadata

Detailed information beyond what's available in standard documentation

FastMCP Implementation

Uses stdio communication for reliable tool execution and context sharing

Fast Responses

Optimized for quick retrieval with smart caching

Markdown Formatting

Human-readable responses that work well in chat interfaces

Data Collection and Caching Architecture

Data Sources

MCP-NixOS collects data from multiple authoritative sources:

  • NixOS Elasticsearch API - Queries the official search.nixos.org backend for package and option data
  • Home Manager - Parses official HTML documentation to extract option definitions and metadata from Home Manager modules
  • nix-darwin - Extracts macOS-specific configuration options by parsing official nix-darwin HTML documentation

Multi-Level Caching System

MCP-NixOS implements a sophisticated multi-level caching architecture for optimal performance:

In-Memory Cache (SimpleCache)
  • Thread-safe implementation with RLock
  • Dual timestamp approach for time shift resilience
  • Configurable TTL (default: 10 minutes for API data)
  • Automatic expiration with lazy cleanup
  • Size-limited with LRU eviction policy
Filesystem Cache (HTMLCache)
  • Cross-platform cache directory management
  • Atomic file operations with proper locking
  • Content-addressed storage with MD5 hashing
  • Metadata preservation for diagnostics
  • Longer TTL (default: 24 hours for stable data)

Both caching systems include comprehensive metrics tracking and resilience against system time shifts.

Optimization Techniques

  • Smart Query Construction - Optimized Elasticsearch DSL queries with proper field boosting
  • Parallel Processing - Concurrent data fetching for multi-source queries
  • Pre-Caching - Optional pre-population of cache during initialization
  • Incremental Updates - Only fetch and process changed data
  • Response Formatting - Efficient markdown generation for AI consumption

Configuration Options

The caching system can be fine-tuned via environment variables:

VariableDescriptionDefault
MCP_NIXOS_CACHE_DIRCustom cache directory locationOS-specific cache location
MCP_NIXOS_CACHE_TTLCache time-to-live in seconds86400 (24 hours)
ELASTICSEARCH_URLNixOS Elasticsearch API URLsearch.nixos.org/backend

FastMCP and STDIO Implementation

JSON-based Communication Protocol

MCP-NixOS uses the Model Context Protocol (MCP) with a stdio implementation powered by FastMCP:

Communication Flow
  1. Request Handling
    • Client sends JSON request via stdin
    • FastMCP server parses and validates request format
    • Request is routed to appropriate MCP resource handler
  2. Resource Processing
    • Resource handler executes the requested operation
    • Data is retrieved from cache or source as needed
    • Response is formatted according to MCP specifications
  3. Response Delivery
    • JSON response is serialized with proper formatting
    • Response is written to stdout for client consumption
    • Errors are handled gracefully with descriptive messages

FastMCP Integration

Server Features
  • Asynchronous request processing
  • Thread-safe resource management
  • Graceful error handling and recovery
  • Comprehensive logging with configurable levels
  • Automatic context management and cleanup
MCP Resources
  • URL-based resource identification
  • Consistent scheme patterns (nixos://, home-manager://, darwin://)
  • Structured response formatting
  • Rich metadata with source information
  • Standardized error reporting

#API Reference

Response Format

All MCP-NixOS responses are wrapped in a standardized JSON structure following the Model Context Protocol:

json
{
  "result": "# Markdown or text content here...

Formatted for AI consumption",
  "status": "success",
  "metadata": {
    "source": "nixos|home-manager|darwin",
    "timestamp": 1649267584,
    "cache_hit": true,
    "query_time_ms": 42
  }
}

Key Fields

  • result: The main response content (markdown/text)
  • status: Operation result (success/error)
  • metadata: Additional context information
  • error: Error message (if status is error)

Response Characteristics

  • Markdown formatting optimized for AI consumption
  • Consistent structure across all tools
  • Rich metadata for context awareness
  • Documentation examples show only the result field for clarity

#NixOS Resources & Tools

Tools for searching and retrieving information about NixOS packages, options, and programs.

Search for NixOS packages, options, or programs.

Parameters:
  • query: The search term
  • type: The type to search ("packages", "options", or "programs") - default: "packages"
  • limit: Maximum number of results to return - default: 20
  • channel: NixOS channel to use ("unstable" or "24.11") - default: "unstable"
Example: Search for packages
json
{
  "type": "call",
  "tool": "nixos_search",
  "params": {
    "query": "python",
    "type": "packages",
    "limit": 10,
    "channel": "unstable" 
  }
}
Sample Response:
text
Found 10 packages matching 'python':

- python2 (2.7.18.8)
  High-level dynamically-typed programming language

- python2Full (2.7.18.8)
  High-level dynamically-typed programming language

- python27Full (2.7.18.8)
  High-level dynamically-typed programming language

- python3Full (3.12.9)
  High-level dynamically-typed programming language

- python314 (3.14.0a6)
  High-level dynamically-typed programming language

- python39 (3.9.21)
  High-level dynamically-typed programming language

- python3Minimal (3.12.9)
  High-level dynamically-typed programming language

- python313Full (3.13.2)
  High-level dynamically-typed programming language

- python314Full (3.14.0a6)
  High-level dynamically-typed programming language

- texlivePackages.python (0.22)
  Embed Python code in LaTeX
Example: Search for options
json
{
  "type": "call",
  "tool": "nixos_search",
  "params": {
    "query": "services.postgresql",
    "type": "options",
    "channel": "unstable"
  }
}

#nixos_info()

Get detailed information about a NixOS package or option.

Parameters:
  • name: The name of the package or option
  • type: Either "package" or "option" - default: "package"
  • channel: NixOS channel to use ("unstable" or "24.11") - default: "unstable"
Example: Get package info
json
{
  "type": "call",
  "tool": "nixos_info",
  "params": {
    "name": "python3Full",
    "type": "package",
    "channel": "unstable"
  }
}
Sample Response:
markdown
# python3Full

**Version:** 3.12.9

**Description:** High-level dynamically-typed programming language

**Long Description:**
Python is a remarkably powerful dynamic programming language that is
used in a wide variety of application domains...

**Homepage:** https://www.python.org

**License:** Python Software Foundation License version 2

**Source:** [pkgs/development/interpreters/python/cpython/default.nix:803](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/interpreters/python/cpython/default.nix#L803)

**Maintainers:** Martin Weinelt, Tomoya Otabi

**Platforms:** mips64-linux, i686-freebsd, armv6l-linux, i686-cygwin, riscv64-linux, x86_64-darwin...

**Provided Programs:** 2to3, 2to3-3.12, idle, idle3, idle3.12, pydoc, pydoc3, pydoc3.12, python, python-config, python3, python3-config, python3.12, python3.12-config

#nixos_stats()

Get statistics about available NixOS packages and options.

Parameters:
  • channel: NixOS channel to use ("unstable" or "24.11") - default: "unstable"
Example: Get NixOS stats
json
{
  "type": "call",
  "tool": "nixos_stats",
  "params": {
    "channel": "unstable"
  }
}
Sample Response:
markdown
# NixOS Statistics (Channel: unstable)

Total options: 21,496

## Package Statistics

### Top 10 Platforms
- x86_64-linux: 118,497 packages
- aarch64-linux: 116,467 packages
- i686-linux: 116,344 packages
- armv7l-linux: 115,540 packages
- armv6l-linux: 115,483 packages
- riscv64-linux: 115,469 packages
- powerpc64le-linux: 115,453 packages
- armv7a-linux: 115,365 packages
- armv5tel-linux: 115,362 packages
- s390x-linux: 115,344 packages

#Home Manager Resources & Tools

Tools for searching and retrieving information about Home Manager options and configurations.

Search for Home Manager options based on a query string.

Parameters:
  • query: The search term
  • limit: Maximum number of results to return - default: 20
Example: Search for options
json
{
  "type": "call",
  "tool": "home_manager_search",
  "params": {
    "query": "programs.neovim",
    "limit": 5
  }
}
Sample Response:
markdown
# Search Results for 'programs.neovim' (5 of 12 results)

## programs.neovim.enable

**Type**: boolean
**Default**: false
**Description**: Whether to enable Neovim.

## programs.neovim.defaultEditor

**Type**: boolean
**Default**: false
**Description**: Whether to configure the EDITOR environment variable to use Neovim.

## programs.neovim.package

**Type**: package
**Default**: pkgs.neovim
**Description**: The Neovim package to use.

## programs.neovim.viAlias

**Type**: boolean
**Default**: false
**Description**: Symlink 'vi' to 'nvim' binary.

## programs.neovim.vimAlias

**Type**: boolean
**Default**: false
**Description**: Symlink 'vim' to 'nvim' binary.

#home_manager_info()

Get detailed information about a specific Home Manager option.

Parameters:
  • name: The name of the option
Example: Get option info
json
{
  "type": "call",
  "tool": "home_manager_info",
  "params": {
    "name": "programs.git.enable"
  }
}
Sample Response:
markdown
# programs.git.enable

## Type
boolean

## Default
false

## Description
Whether to install and configure Git.

## Declared In
/nix/store/...-source/modules/programs/git.nix:15

## Defined In
/nix/store/...-source/modules/programs/git.nix:15

## Example
{
  programs.git.enable = true;
}

## Related Options
- programs.git.package
- programs.git.userName
- programs.git.userEmail
- programs.git.aliases
- programs.git.signing
- programs.git.extraConfig

#home_manager_list_options()

List all top-level Home Manager option categories with statistics.

Parameters:

This function takes no parameters.

Example: List option categories
json
{
  "type": "call",
  "tool": "home_manager_list_options"
}
Sample Response:
markdown
# Home Manager Top-Level Option Categories

Total categories: 25
Total options: 2456

## programs

- **Options count**: 500
- **Option types**:
  - boolean: 149
  - null or package: 39
  - list of string: 32
  - strings concatenated with "
": 28
  - package: 23
- **Enable options**: 70
  - abook: Whether to enable Abook..
  - aerc: Whether to enable aerc..
  - aerospace: Whether to enable AeroSpace window manager..
  - ...and 67 more

#home_manager_options_by_prefix()

Get all Home Manager options under a specific prefix.

Parameters:
  • option_prefix: The option prefix to search for (e.g., "programs", "programs.git")
Example: Get options by prefix
json
{
  "type": "call",
  "tool": "home_manager_options_by_prefix",
  "params": {
    "option_prefix": "programs.git"
  }
}
Sample Response:
markdown
# Home Manager Options: programs.git

Found 67 options

## Direct Options

- **programs.git.aliases** (aliases) (attribute set of string)
  Git aliases to define.
- **programs.git.attributes** (attributes) (list of string)
  List of defining attributes set globally.
- **programs.git.enable** (enable) (boolean)
  Whether to enable Git.
- **programs.git.extraConfig** (extraConfig) (strings concatenated with "
" or attribute set of attribute set of (string or boolean or signed integer or list of (string or boolean or signed integer) or attribute set of (string or boolean or signed integer or list of (string or boolean or signed integer))))
  Additional configuration to add. The use of string values is
deprecated and will be removed in the future.
- **programs.git.hooks** (hooks) (attribute set of absolute path)
  Configuration helper for Git hooks.
See https://git-scm.com/docs/githooks
for reference.
- **programs.git.ignores** (ignores) (list of string)
  List of paths that should be globally ignored.

## Option Groups

### cliff options (3)

To see all options in this group, use:
`home_manager_options_by_prefix(option_prefix="programs.git.cliff")`

- **enable** (boolean)
- **package** (null or package)
- **settings** (TOML value)

### signing options (4)

To see all options in this group, use:
`home_manager_options_by_prefix(option_prefix="programs.git.signing")`

- **format** (null or one of "openpgp", "ssh", "x509")
- **key** (null or string)
- **signByDefault** (null or boolean)
- **signer** (null or string)

#home_manager_stats()

Get statistics about Home Manager options.

Parameters:

This function takes no parameters.

Example: Get Home Manager stats
json
{
  "type": "call",
  "tool": "home_manager_stats"
}
Sample Response:
markdown
# Home Manager Option Statistics

Total options: 3704
Categories: 4
Option types: 391

## Distribution by Source

- options: 3697 options
- nix-darwin-options: 7 options

## Top Categories

- Note: 1943 options
- Caution: 1264 options
- Uncategorized: 430 options
- Warning: 74 options

## Distribution by Type

- boolean: 936 options
- null or string: 300 options
- string: 282 options
- package: 239 options
- list of string: 175 options
- strings concatenated with "
": 145 options
- null or boolean: 137 options
- null or package: 136 options
- null or signed integer: 82 options
- attribute set of string: 71 options

## Index Statistics

- Words indexed: 4382
- Prefix paths: 4432
- Hierarchical parts: 4403

#nix-darwin Resources & Tools

Tools for searching and retrieving information about nix-darwin macOS options and configurations.

Search for nix-darwin options based on a query string.

Parameters:
  • query: The search term
  • limit: Maximum number of results to return - default: 20
Example: Search for darwin options
json
{
  "type": "call",
  "tool": "darwin_search",
  "params": {
    "query": "keyboard",
    "limit": 5
  }
}
Sample Response:
markdown
# Search Results for 'keyboard' (5 of 15 results)

## system.keyboard.enableKeyMapping

**Type**: boolean
**Default**: false
**Description**: Whether to enable keyboard mapping.

## system.keyboard.remapCapsLockToControl

**Type**: boolean
**Default**: false
**Description**: Whether to remap the Caps Lock key to Control.

## system.keyboard.remapCapsLockToEscape

**Type**: boolean
**Default**: false
**Description**: Whether to remap the Caps Lock key to Escape.

#darwin_info()

Get detailed information about a specific nix-darwin option.

Parameters:
  • name: The name of the option
Example: Get option info
json
{
  "type": "call",
  "tool": "darwin_info",
  "params": {
    "name": "homebrew.enable"
  }
}
Sample Response:
markdown
## homebrew.enable
Whether to enable nix-darwin to manage installing/updating/upgrading Homebrew taps, formulae,
and casks, as well as Mac App Store apps and Docker containers, using Homebrew Bundle. Note that enabling this option does not install Homebrew, see the Homebrew website for installation instructions. Use the homebrew.brews , homebrew.casks , homebrew.masApps , and homebrew.whalebrews options
to list the Homebrew formulae, casks, Mac App Store apps, and Docker containers you'd like to
install. Use the homebrew.taps option, to make additional formula
repositories available to Homebrew. This module uses those options (along with the homebrew.caskArgs options) to generate a Brewfile that nix-darwin passes to the brew bundle command during
system activation.

**Type:** boolean
**Default:** false
**Example:** true
**Declared by:** <nix-darwin/modules/homebrew.nix>

#darwin_list_options()

List all top-level nix-darwin option categories with statistics.

Parameters:

This function takes no parameters.

Example: List option categories
json
{
  "type": "call",
  "tool": "darwin_list_options"
}
Sample Response:
markdown
## nix-darwin Option Categories
### _module
- **Options count:** 1
- **Usage:** `darwin._module`

### documentation
- **Options count:** 4
- **Usage:** `darwin.documentation`

### environment
- **Options count:** 34
- **Usage:** `darwin.environment`

### fonts
- **Options count:** 1
- **Usage:** `darwin.fonts`

### homebrew
- **Options count:** 49
- **Usage:** `darwin.homebrew`

### launchd
- **Options count:** 249
- **Usage:** `darwin.launchd`

### networking
- **Options count:** 26
- **Usage:** `darwin.networking`

### nix
- **Options count:** 55
- **Usage:** `darwin.nix`

### nixpkgs
- **Options count:** 10
- **Usage:** `darwin.nixpkgs`

### power
- **Options count:** 6
- **Usage:** `darwin.power`

### programs
- **Options count:** 69
- **Usage:** `darwin.programs`

### security
- **Options count:** 17
- **Usage:** `darwin.security`

### services
- **Options count:** 297
- **Usage:** `darwin.services`

### system
- **Options count:** 208
- **Usage:** `darwin.system`

### time
- **Options count:** 1
- **Usage:** `darwin.time`

### users
- **Options count:** 20
- **Usage:** `darwin.users`

To view options in a specific category, use the `darwin_options_by_prefix` tool with the category name.

#darwin_options_by_prefix()

Get all nix-darwin options under a specific prefix.

Parameters:
  • option_prefix: The option prefix to search for (e.g., "homebrew", "system")
Example: Get options by prefix
json
{
  "type": "call",
  "tool": "darwin_options_by_prefix",
  "params": {
    "option_prefix": "homebrew"
  }
}
Sample Response:
markdown
## nix-darwin options with prefix 'homebrew'
Found 49 options.

### homebrew.brewPrefix
The path prefix where the brew executable is located. This will be set to
the correct value based...
**Type:** `string`

For more details, use `darwin_info("homebrew.brewPrefix")`

### homebrew.brews
List of Homebrew formulae to install. Formulae defined as strings, e.g., "imagemagick" , are a sh...
**Type:** `list`

For more details, use `darwin_info("homebrew.brews")`

### homebrew.brews._.args
Arguments flags to pass to brew install . Values should not include the
leading "--" . Type: null...
**Type:** `null`

For more details, use `darwin_info("homebrew.brews._.args")`

### homebrew.brews._.conflicts_with
List of formulae that should be unlinked and their services stopped (if they are
installed). Type...
**Type:** `null`

For more details, use `darwin_info("homebrew.brews._.conflicts_with")`

### homebrew.brews._.link
Whether to link the formula to the Homebrew prefix. When this option is null , Homebrew will use ...
**Type:** `null`

For more details, use `darwin_info("homebrew.brews._.link")`

### homebrew.brews._.name
The name of the formula to install. Type: string Declared by: <nix-darwin/modules/homebrew.nix>
**Type:** `string`

For more details, use `darwin_info("homebrew.brews._.name")`

### homebrew.taps
List of Homebrew formula repositories to tap. Taps defined as strings, e.g., "user/repo" , are a ...
**Type:** `list`

For more details, use `darwin_info("homebrew.taps")`

### homebrew.whalebrews
List of Docker images to install using whalebrew . When this option is used, "whalebrew" is autom...
**Type:** `list`

For more details, use `darwin_info("homebrew.whalebrews")`

[...and more options]

#darwin_stats()

Get statistics about nix-darwin options.

Parameters:

This function takes no parameters.

Example: Get Darwin stats
json
{
  "type": "call",
  "tool": "darwin_stats"
}
Sample Response:
markdown
## nix-darwin Options Statistics
- **Total options:** 1048
- **Total categories:** 16
- **Last updated:** 2025-04-03T22:07:02.122217

### Top-level Categories
- **_module**: 1 options
- **documentation**: 4 options
- **environment**: 34 options
- **fonts**: 1 options
- **homebrew**: 49 options
- **launchd**: 249 options
- **networking**: 26 options
- **nix**: 55 options
- **nixpkgs**: 10 options
- **power**: 6 options
- **programs**: 69 options
- **security**: 17 options
- **services**: 297 options
- **system**: 208 options
- **time**: 1 options
- **users**: 20 options

#Configuration

MCP-NixOS can be configured through environment variables, grouped by purpose:

Essential Variables
VariableDescriptionDefault Value
MCP_NIXOS_LOG_LEVELLogging levelINFO
MCP_NIXOS_LOG_FILEPath to log fileNone (stdout)
MCP_NIXOS_CACHE_DIRDirectory for cache files~/.cache/mcp_nixos/ (platform-specific)
MCP_NIXOS_CACHE_TTLCache time-to-live in seconds600 (10 minutes)
Advanced Variables (Optional)
VariableDescriptionDefault Value
ELASTICSEARCH_URLCustom Elasticsearch URL (only needed for custom deployments)https://search.nixos.org/backend
Development Variables
VariableDescriptionDefault Value
MCP_NIXOS_CLEANUP_ORPHANSClean up orphaned cache filestrue
KEEP_TEST_CACHEKeep test cache directory for debuggingfalse