105 lines
3.2 KiB
Markdown
105 lines
3.2 KiB
Markdown
# 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`:
|
|
|
|
```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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```nix
|
|
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
|
|
|
|
```bash
|
|
# 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.
|