← Discover MCPs and Agents
n
MCPAI & MLGitHub

nix-claude-code

Declarative Claude Code in Nix — plugins, marketplaces, skills, hooks, MCP, and permissions as composable home-manager modules. Reproducible on macOS and Linux.

Links

README

From the repo.

nix-claude-code

Declarative Claude Code in Nix — plugins, marketplaces, skills, hooks, MCP, and permissions as composable home-manager modules. Reproducible on macOS and Linux.

CI License: MIT Nix Flake home-manager Anthropic Spec

A Nix flake that ships Claude Code as composable home-manager modules. Drop it into your flake — you get a fully-configured Claude Code with a curated plugin stack, statusline, hooks, MCP servers, and permission rules. All declared in Nix, reproducible across machines, rolled back with one command.

What you get

  • All marketplaces, no fiddling. Anthropic's official marketplaces (claude-plugins-official, anthropic-agent-skills) plus 15+ curated community marketplaces, wired up to refresh automatically.
  • Plugins as data. Every plugin you enable is declared in programs.claude.enabledPlugins, version-pinned in flake.lock, rolled back atomically with darwin-rebuild --rollback.
  • Full-trust auto mode. Claude Code ships with defaultMode = "auto" and zero hard-coded allow/ask/deny rules — every tool call goes to the auto-mode classifier, which reads the conversation and the repo instead of pattern-matching a command prefix. The structured permission data is still here and still exported for Codex, Gemini, and any other agent that has no classifier of its own.
  • Statusline themes. Pick powerline, ccstatusline, or daniel3303's theme with one option.
  • Optional account switching. Enable claude-swap only where needed for manual Claude subscription switching and parallel terminal sessions.
  • MCP plumbing. Surface programs.claude.mcpServers from your favorite MCP runtime; we wire them into Claude's settings.json exactly the way Anthropic specifies.
  • Built on Anthropic's official spec. Reads .claude-plugin/marketplace.json and .claude-plugin/plugin.json per the official plugin reference. No proprietary formats; no surprises.

Installation

Add nix-claude-code to your flake inputs:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";

    home-manager.url = "github:nix-community/home-manager/release-26.05";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";

    nix-claude-code.url = "github:dryvist/nix-claude-code";
    nix-claude-code.inputs.nixpkgs.follows = "nixpkgs";
    nix-claude-code.inputs.home-manager.follows = "home-manager";
  };
}

Or scaffold from a template:

nix flake init -t github:dryvist/nix-claude-code#minimal
# or, if you already use flake-parts:
nix flake init -t github:dryvist/nix-claude-code#flake-parts

Usage

The simplest setup imports homeModules.default:

{
  outputs = { home-manager, nix-claude-code, nixpkgs, ... }: {
    homeConfigurations."you" = home-manager.lib.homeManagerConfiguration {
      pkgs = nixpkgs.legacyPackages.aarch64-darwin;
      modules = [
        nix-claude-code.homeModules.default
        ({ ... }: {
          home.username = "you";
          home.homeDirectory = "/Users/you";
          home.stateVersion = "25.11";
          programs.claude.enable = true;
        })
      ];
    };
  };
}

Then activate:

nix run home-manager#switch -- --flake .#you
claude   # ready to go

Switch Claude subscriptions

claude-swap is disabled by default. Enable it to install the manual account-switching CLI:

programs.claude.swap.disabled = false;

After activation, log in to each Claude subscription interactively and run cswap add for each account. Use cswap switch <alias> to change the active account, or cswap run <alias> -- … to start a parallel terminal-local Claude session. The module does not configure automatic switching or store account credentials in Nix.

Pick and choose

homeModules.default enables everything. Or compose à-la-carte:

ModuleWhat it ships
homeModules.defaultAll of the below, sane defaults — the 95% answer
homeModules.claudeAlias of default
homeModules.coresettings.json, auto-mode posture, the claude-code binary
homeModules.pluginsMarketplace + plugin management
homeModules.statuslinePowerline / ccstatusline / daniel3303 themes
homeModules.hooksSession-output capture + marketplace-refresh hooks
homeModules.mcpprograms.claude.mcpServers option (you populate from any runtime)
homeModules.latestOpt-in auto-installer for the latest Claude Code release

Want only settings.json and the permission posture, nothing else? Import homeModules.core and skip the rest. Want the plugins but not the statusline? Import homeModules.core + homeModules.plugins.

See docs/settings.md for the full settings.json option catalog, including the freeform passthrough for keys with no typed option yet.

Already on flake-parts?

{
  outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } {
    imports = [ inputs.nix-claude-code.flakeModule ];
    # ...
  };
}

Architecture

flowchart LR
    A[17 marketplace inputs<br/>flake.nix] --> B[lib.parseMarketplace]
    C[data/permissions/*.nix<br/>Nix-native data] --> D[lib.mkDefaultPermissions]
    D --> P[Codex / Gemini / other<br/>agents without a classifier]
    B --> E[modules/plugins.nix]
    F[modules/core.nix<br/>defaultMode=auto, no rules] --> G[~/.claude/settings.json]
    E --> G
    H[modules/statusline] --> I[~/.claude/statusline]
    J[modules/hooks] --> K[~/.claude/hooks/]
    L[modules/mcp<br/>mcpServers option] --> G
    M[pkgs.claude-code] --> N[~/.nix-profile/bin/claude]

See docs/architecture.md for the full breakdown.

API

The lib.* exports are designed for any AI-agent tool that wants to consume Claude-spec data:

{ inputs, lib, ... }:
let
  market = inputs.nix-claude-code.lib.parseMarketplace inputs.jacobpevans-cc-plugins;
  # market :: { name; description; owner; plugins; raw; }

  skills = inputs.nix-claude-code.lib.discoverSkills inputs.anthropic-agent-skills;
  # skills :: [{ name; path; pluginRoot; }]

  perms = inputs.nix-claude-code.lib.mkDefaultPermissions { tool = "codex"; };
  # perms :: { allow; allowMcp; ask; deny; denyExact; denyPatterns; webfetchDomains; }
  # (`ask` is always empty — see data/permissions/README.md. Claude Code
  #  itself no longer consumes this; auto mode is its gate.)
in
  # ... build whatever you need
Lib exportPurityReturns
lib.parseMarketplacepure{ name; description; owner; plugins; raw; }
lib.parsePluginpure{ name; description; version; author; raw; }
lib.discoverSkillspure[{ name; path; pluginRoot; }]
lib.discoverCommandspure[{ name; path; pluginRoot; }]
lib.discoverAgentspure[{ name; path; pluginRoot; frontmatter; }]
lib.discoverHookspurehooks.json attrset
lib.toSettingsJsonpure~/.claude/settings.json shape
lib.permissions.{allow,ask,deny,domains,toolSpecific}dataPermission lists
lib.mkDefaultPermissionspureComposed permissions for a tool
lib.wrapCommandsAsSkills { pkgs }impureDerivation wrapping commands/<name>.md as synthetic SKILL.md files

Compatibility

ComponentSupported
Claude Codelatest stable (auto-tracked from Anthropic upstreams)
nixpkgsnixos-26.05 (override via inputs.nix-claude-code.inputs.nixpkgs.follows)
home-managerrelease-26.05
Platformsaarch64-darwin, x86_64-darwin, aarch64-linux, x86_64-linux
Plugin specAnthropic official

Comparison

nix-claude-codeHand-maintained .claude/
Reproducible across machines
Atomic rollback✓ (--rollback)
Version-pinned plugins✓ (flake.lock)
Auto-refresh marketplaces✓ (opt-in hook)manual
One-command setup on a new machinehours of /plugin install
Anthropic plugin spec compliantdepends on what you wrote

Contributing

  • Add a marketplace: append to flake.nix inputs and the wiring in flake/modules.nix.
  • Add a statusline theme: drop a <name>.nix file in modules/statusline/.
  • Add a permission rule: edit data/permissions/*.nix. These are the source of truth for permission rules across AI agent tools that have no classifier of their own (Codex, Gemini). Claude Code does not consume them — teach the auto-mode classifier instead, via programs.claude.autoMode.
  • Add a lib helper: write a pure function in lib/, add a nix-unit test in checks/lib/.

Pre-commit hooks run treefmt, deadnix, statix, and YAML/TOML validation. CI runs nix flake check on every PR.

See docs/adopters.md for the full integration guide.

License

MIT © Jacob P. Evans — see LICENSE.


Part of a larger ecosystem of ~40 repos — see how it all fits together.

Collected info

  • 3 stars
  • 1 forks
  • Language: Nix
  • Source updated: 9/19/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.