--- title: "Claude Code Configuration" description: "Reference for Claude Code config file locations and precedence, MCP server setup in ~/.claude.json, hooks, permissions, and common gotchas." type: reference domain: workstation tags: [claude-code, mcp, config, hooks, permissions, claude] --- # Claude Code Configuration ## Config File Locations Claude Code reads settings from multiple files in a specific precedence order: | File | Scope | What goes here | |------|-------|---------------| | `~/.claude.json` | User-level (all projects) | MCP servers, startup state, git repo mappings | | `~/.claude/settings.json` | User-level (all projects) | Permissions, hooks, env vars, plugins, status line | | `~/.claude/projects//settings.json` | Project-level | Project-specific permission overrides | | `/.claude/settings.json` | Repo-level (checked in) | Shared team settings | | `/.mcp.json` | Repo-level (checked in) | Project-scoped MCP servers | **Important**: `~/.claude.json` (home directory root) is different from `~/.claude/settings.json` (inside the `.claude` directory). They serve different purposes. ## MCP Server Configuration MCP servers are defined in the top-level `mcpServers` key of `~/.claude.json`: ```json { "mcpServers": { "server-name": { "command": "/path/to/binary", "args": ["-t", "stdio"], "env": { "API_KEY": "value" } } } } ``` ### Server Types **stdio** — local process, communicates over stdin/stdout: ```json { "command": "/path/to/binary", "args": ["--flag", "value"], "env": { "KEY": "value" } } ``` **http** — remote HTTP server (Streamable HTTP transport): ```json { "type": "http", "url": "http://host:port/mcp", "headers": { "Authorization": "Bearer " } } ``` ### Current MCP Servers All defined in `~/.claude.json` under `mcpServers`: | Server | Type | Purpose | |--------|------|---------| | `cognitive-memory` | stdio | Persistent memory system (local Python) | | `n8n-mcp` | stdio | n8n workflow automation API | | `gitea-mcp` | stdio | Gitea API (issues, PRs, repos) | | `tui-driver` | stdio | TUI automation for testing | | `kb-search` | url | Knowledge base semantic search (manticore) | ### Managing MCP Servers - **Add interactively**: `/mcp add ` in Claude Code (stores in `~/.claude.json`) - **Add manually**: Edit the `mcpServers` object in `~/.claude.json` - **Reconnect**: `/mcp` → select server → Reconnect (useful after remote server restarts) - **Permissions**: Auto-allow MCP tools via `"mcp__server-name__*"` in `~/.claude/settings.json` permissions.allow ### Gotchas - **Session drops**: Remote (url) MCP servers lose their session if the server container restarts. Run `/mcp` to reconnect. - **Don't confuse config files**: `~/.claude.json` holds MCP servers. `~/.claude/settings.json` holds permissions/hooks. They are NOT the same file. - **Stale configs**: `~/.claude/.mcp.json` and `~/.claude/.mcp-full.json` are NOT read by Claude Code despite looking like they should be. The canonical location is `~/.claude.json`. ## Hooks Hooks are configured in `~/.claude/settings.json` under the `hooks` key. They run shell commands or HTTP requests in response to events. ### Current Hooks | Event | Action | |-------|--------| | `PostToolUse` (Edit/Write/MultiEdit) | Auto-format code via `format-code.sh` | | `SubagentStop` | Notify via `notify-subagent-done.sh` | | `SessionEnd` | Save session memories via `cognitive-memory` | ## Permissions Permission rules live in `~/.claude/settings.json` under `permissions.allow` and `permissions.deny`. Format: `ToolName(scope:pattern)`. Common patterns: - `"mcp__gitea-mcp__*"` — allow all gitea MCP tools - `"WebFetch(domain:docs.example.com)"` — allow fetching from specific domain - `"Bash(ssh:*)"` — allow SSH commands