omnixient/docs/mcp.md
2026-06-28 10:00:14 +02:00

3.2 KiB

Claude Code MCP Configuration

Omnixient manages Claude Code MCP (Model Context Protocol) servers declaratively via modules/mcp.nix. This doc covers setup, secrets, and the safety defaults.

How it works

  1. modules/mcp.nix renders a mcpServers attrset to ~/.config/omni/mcp-servers.json on each nixos-rebuild switch.
  2. A home-manager activation step then merges .mcpServers from that file into ~/.claude.json via jq, preserving Claude Code's other state (project history, OAuth tokens).
  3. Secrets live in ~/.config/omni/secrets/ (mode 0700) and are loaded by thin wrapper scripts at MCP launch time — never baked into the nix store or exported to the shell.

Enabling / disabling servers

Edit configuration.nix:

omni.mcp = {
  enable = true;

  servers = {
    # Defaults on:
    mcp-nixos.enable = true;     # nixpkgs / NixOS search
    github.enable   = true;      # HTTP + OAuth
    forgejo.enable  = true;      # needs ~/.config/omni/secrets/forgejo-token
    fetch.enable    = true;      # generic HTTP fetch

    # Defaults off — opt-in per host:
    postgres.enable   = false;
    docker.enable     = false;
    nostr.enable      = false;
    shadcn-vue.enable = false;
  };
};

Required secret files

Create any of these outside the nix store with mode 0600. The secrets directory is auto-created at 0700 on the first rebuild.

Forgejo

install -m600 /dev/stdin ~/.config/omni/secrets/forgejo-token <<< 'YOUR_FORGEJO_PAT'

Issue a PAT at https://git.atitlan.io/user/settings/applications.

GitHub

No secret file needed — uses OAuth via /mcp inside Claude Code. On first use run /mcp in a Claude session and authenticate in the browser.

Safety defaults

  • No filesystem MCP. Claude Code's built-in Read/Edit/Write tools already cover filesystem work with per-action approval; adding a filesystem MCP widens blast radius without adding capability.

  • Postgres is restricted by default. --access-mode=restricted blocks destructive SQL. To run migrations, flip postgres.writable = true for that session only:

    omni.mcp.servers.postgres.writable = true;
    

    Rebuild, do the migration, revert. Or better: pipe psql yourself.

Adding a new server

  1. Add a new servers.<name> option block in modules/mcp.nix.
  2. Append a corresponding optionalAttrs cfg.servers.<name>.enable { ... } clause to mcpServers.
  3. If it needs a secret, write a wrapper in the pattern of forgejoMcpWrapper that sources the token file and execs the real binary.

Future work

  • Package forgejo-mcp as a buildGoModule derivation instead of reading from ~/go/bin/ (imperative state leftover from go install).
  • Replace plain secret files with agenix or sops-nix once forgejo-mcp is validated end-to-end.
  • Add a permissions.deny list in ~/.claude/settings.json for tool names that should be hard-blocked regardless of approval prompts.

Debugging

# Inspect the rendered JSON
cat ~/.config/omni/mcp-servers.json

# See the merged result
jq '.mcpServers' ~/.claude.json

# List from Claude Code's side
claude mcp list

Inside a Claude Code session, /mcp shows live server status and handles OAuth for HTTP servers.