144 lines
5.4 KiB
Markdown
144 lines
5.4 KiB
Markdown
---
|
|
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/<sanitized-cwd>/settings.json` | Project-level | Project-specific permission overrides |
|
|
| `<repo>/.claude/settings.json` | Repo-level (checked in) | Shared team settings |
|
|
| `<repo>/.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 <token>"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Current MCP Servers
|
|
|
|
All defined in `~/.claude.json` under `mcpServers`:
|
|
|
|
| Server | Type | Purpose |
|
|
|--------|------|---------|
|
|
| `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 <name>` 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 are defined in `~/.claude/settings.json` — check the `hooks` key for the live list.
|
|
|
|
Additionally, the `format-on-save@agent-toolkit` plugin registers its own `PostToolUse` hook for auto-formatting files on Edit/Write (runs ruff for Python, prettier for JS/TS, shfmt for shell, etc). See the plugin source at `~/.claude/plugins/cache/agent-toolkit/format-on-save/` for the full formatter list.
|
|
|
|
## 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:*)"` — allow fetching from any domain
|
|
- `"Bash"` — allow all Bash commands (subject to cmd-gate hook below)
|
|
|
|
## permission-manager Plugin (cmd-gate)
|
|
|
|
The `permission-manager@agent-toolkit` plugin adds a `PreToolUse` hook on all `Bash` tool calls. It parses commands into an AST via `shfmt --tojson`, classifies each segment, and returns allow/ask/deny.
|
|
|
|
### How it works
|
|
|
|
1. Compound commands (`&&`, `||`, pipes) are split into segments
|
|
2. Each segment is checked against **custom allow patterns** first (bypasses classifiers)
|
|
3. Then dispatched to language/tool-specific classifiers (git, docker, npm, etc.)
|
|
4. Most restrictive result wins across all segments
|
|
|
|
### Custom allow patterns
|
|
|
|
Loaded from two files (both checked, merged):
|
|
- **Global:** `~/.claude/command-permissions.json`
|
|
- **Project-level:** `.claude/command-permissions.json` (relative to cwd)
|
|
|
|
Format:
|
|
```json
|
|
{
|
|
"allow": [
|
|
"git pull*",
|
|
"git push origin main"
|
|
]
|
|
}
|
|
```
|
|
|
|
Patterns are **bash glob matched** per-segment against the command string. Project-level patterns are resolved from `$PWD` at hook time (i.e., the project Claude Code is working in, not the target of a `cd` in the command).
|
|
|
|
### Protected branches
|
|
|
|
The git classifier denies `git push` to `main` or `master` by default. To allow pushes to main from a specific project, add `"git push origin main"` to that project's `.claude/command-permissions.json`.
|
|
|
|
### Bypass
|
|
|
|
- Scheduled tasks use `--permission-mode bypassPermissions` which skips cmd-gate entirely
|
|
- For classifier development details, see `development/permission-manager-classifier-development.md`
|
|
- Plugin source: `~/.claude/plugins/cache/agent-toolkit/permission-manager/`
|