claude-home/workstation/claude-code-config.md
Cal Corum b1fed02219
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: sync KB — tag-triggered-release-deploy.md,release-2026.3.20.md claude-code-config.md
2026-03-20 14:00:43 -05:00

5.4 KiB

title description type domain tags
Claude Code Configuration Reference for Claude Code config file locations and precedence, MCP server setup in ~/.claude.json, hooks, permissions, and common gotchas. reference workstation
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:

{
  "mcpServers": {
    "server-name": {
      "command": "/path/to/binary",
      "args": ["-t", "stdio"],
      "env": {
        "API_KEY": "value"
      }
    }
  }
}

Server Types

stdio — local process, communicates over stdin/stdout:

{
  "command": "/path/to/binary",
  "args": ["--flag", "value"],
  "env": { "KEY": "value" }
}

http — remote HTTP server (Streamable HTTP transport):

{
  "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:

{
  "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/