Fransys

Tech blog — Architecture, Cloud & DevOps

BlogServicesContactAbout

Follow me

githubGitHublinkedinLinkedinmailMail

© 2026 Fransys • Fransys

Fransys

Categories

  • All posts
  • Tags
  • productivity10
  • nas10
  • ai8
  • security7
  • self-hosting7
  • linux6
  • claude-code6
  • neovim5
  • docker5
  • editor4
  • networking4
  • mcp3
  • vpn3
  • lua2
  • terminal2
claude-codeaiproductivityterminal

Optimizing your Claude Code configuration for development

Published on
February 20, 2026·5 min read
Avatar François GUERLEZFrançois GUERLEZ

Introduction: mastering your AI assistant (or it masters you)

Claude Code's been my dev companion for a year+. But using default settings? Like driving with the dashboard closed. Good settings transform everything: faster responses, save quota, automated tasks, real security.

I'm going to share my complete ~/.claude/settings.json and what each thing does. Hours spent perfecting it.

Environment variables: the core

The env section controls how Claude Code behaves at the lowest level. Here's my setup:

{
  "env": {
    "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1",
    "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "80",
    "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "64000",
    "MAX_THINKING_TOKENS": "63999",
    "BASH_DEFAULT_TIMEOUT_MS": "120000",
    "BASH_MAX_TIMEOUT_MS": "600000",
    "MAX_MCP_OUTPUT_TOKENS": "25000",
    "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1",
    "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
    "DISABLE_TELEMETRY": "1",
    "DISABLE_ERROR_REPORTING": "1",
    "CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY": "1",
    "CLAUDE_CODE_SUBAGENT_MODEL": "haiku"
  }
}

Saving your quota (important stuff)

DISABLE_NON_ESSENTIAL_MODEL_CALLS: "1": Claude Code launches "verification" API calls that aren't critical. Disabling keeps quota for real work.

CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "80": Default is 60%. I use 80% to keep more history. Useful when you return to a problem discussed an hour ago.

CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000": Allows very long responses (massive refactorings, articles). Zero quota impact - you pay what you use.

MAX_THINKING_TOKENS: "63999": Extended thinking at max. For hard problems (algorithms, architectures), deep thinking = better solutions.

Managing bash timeouts (crucial!)

BASH_DEFAULT_TIMEOUT_MS: "120000": 2 minutes. Max time before a bash command times out. Useful for slow builds or lengthy tests.

BASH_MAX_TIMEOUT_MS: "600000": 10 minutes if you really want to wait. For massive compilations or deployments.

CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR: "1": CRITICAL. Claude keeps the same pwd between bash commands. Without this, every command restarts from home - nightmare.

Experimental features (actually useful)

CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1": Agent teams. If the problem's complex, Claude creates multiple sub-agents working in parallel. Game-changing for multi-faceted projects.

CLAUDE_CODE_SUBAGENT_MODEL: "haiku": Sub-agents use Haiku (faster, cheaper). Haiku is plenty for 90% of work tasks.

Privacy first (because why not)

DISABLE_TELEMETRY: "1", DISABLE_ERROR_REPORTING: "1", CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY: "1": No telemetry, no survey popups. Autonomy over your data.

Security permissions: lock down what matters

Claude Code can read/write anywhere and run shell commands. Powerful - but risky. The permissions section says "no":

{
  "permissions": {
    "deny": [
      "~/.ssh/**",
      "~/.aws/**",
      "~/.gnupg/**",
      "~/.config/gh/**",
      "~/.git-credentials",
      "~/.netrc",
      "~/.kube/config",
      "~/.docker/config.json"
    ],
    "blockCommands": ["rm -rf /*", "git push --force", "sudo rm", "dd if=/dev/zero", "mkfs.*"]
  }
}

Sensitive files:

  • ~/.ssh/**: SSH keys (PRIVATE!)
  • ~/.aws/**: AWS credentials
  • ~/.gnupg/**: GPG keys
  • ~/.config/gh/**: GitHub token
  • ~/.git-credentials: Git credentials
  • ~/.kube/config: Kubernetes
  • ~/.docker/config.json: Docker registry creds

Blocked commands: Glob patterns like git push --force *. Security is pattern-based - be very specific.

Pro tip: I've created "decoy" files with fake data in sensitive paths. If Claude tries to access them, I see it in the logs immediately. (once caught a hallucination trying to read ~/.ssh)

Hooks: automating before/after

Hooks = shell scripts executed at key moments. I use them to track sessions and metrics:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "name": "claude-prompt-start",
        "command": "echo \"[$(date +'%Y-%m-%d %H:%M:%S')] Prompt submitted\" >> ~/.claude/session.log"
      },
      {
        "name": "autoname-session.sh",
        "command": "~/.claude/autoname-session.sh"
      }
    ],
    "Stop": [
      {
        "name": "claude-prompt-end",
        "command": "echo \"[$(date +'%Y-%m-%d %H:%M:%S')] Session ended\" >> ~/.claude/session.log"
      }
    ]
  }
}

UserPromptSubmit: Triggered when you submit a prompt. Useful for:

  • Logging timestamps
  • Auto-naming sessions based on prompt content (my autoname-session.sh extracts keywords)

Stop: Triggered when Claude Code closes. I log the end to measure total duration.

You can also create hooks that send logs to servers, or run post-session tests.

UI configuration and polish (the small things)

{
  "showTurnDuration": true,
  "cleanupPeriodDays": 90,
  "enableAllProjectMcpServers": false,
  "skipDangerousModePermissionPrompt": true,
  "spinnerVerbs": {
    "mode": "replace",
    "verbs": [" ⠋", " ⠙", " ⠹", " ⠸", " ⠼", " ⠴", " ⠦", " ⠧", " ⠇", " ⠏"]
  }
}

showTurnDuration: true : Shows response time. Identifies slow calls.

cleanupPeriodDays: 90 : Auto-deletes sessions older than 90 days. Don't saturate your disk.

enableAllProjectMcpServers: false : By default, Claude Code asks before activating project MCP servers. Safety measure - you control what executes.

skipDangerousModePermissionPrompt: true : I'm a power user so I trust myself. Lets me switch to "Dangerous Mode" without confirmation. Use carefully!

Plugins: the superpowers

{
  "plugins": [
    {
      "name": "context7",
      "enabled": true
    },
    {
      "name": "safety-net",
      "enabled": true
    },
    {
      "name": "ralph-loop",
      "enabled": true
    }
  ]
}

Context7: Real-time doc access for 100+ frameworks/libs. Instead of Claude hallucinating Next.js v15's API, it looks it up.

Safety-Net: Basic static analysis on commits/PRs before you push - detects accidentally committed secrets, sensitive logs, etc. Handy.

Ralph-Loop: If Claude detects a build/test error, it automatically loops to fix it. Revolutionary.

The complete file

Here's my full settings.json:

{
  "env": {
    "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1",
    "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "80",
    "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "64000",
    "MAX_THINKING_TOKENS": "63999",
    "BASH_DEFAULT_TIMEOUT_MS": "120000",
    "BASH_MAX_TIMEOUT_MS": "600000",
    "MAX_MCP_OUTPUT_TOKENS": "25000",
    "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1",
    "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
    "DISABLE_TELEMETRY": "1",
    "DISABLE_ERROR_REPORTING": "1",
    "CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY": "1",
    "CLAUDE_CODE_SUBAGENT_MODEL": "haiku"
  },
  "permissions": {
    "deny": [
      "~/.ssh/**",
      "~/.aws/**",
      "~/.gnupg/**",
      "~/.config/gh/**",
      "~/.git-credentials",
      "~/.netrc",
      "~/.kube/config",
      "~/.docker/config.json"
    ],
    "blockCommands": ["rm -rf /*", "git push --force", "sudo rm", "dd if=/dev/zero", "mkfs.*"]
  },
  "hooks": {
    "UserPromptSubmit": [
      {
        "name": "claude-prompt-start",
        "command": "echo \"[$(date +'%Y-%m-%d %H:%M:%S')] Prompt submitted\" >> ~/.claude/session.log"
      }
    ],
    "Stop": [
      {
        "name": "claude-prompt-end",
        "command": "echo \"[$(date +'%Y-%m-%d %H:%M:%S')] Session ended\" >> ~/.claude/session.log"
      }
    ]
  },
  "showTurnDuration": true,
  "cleanupPeriodDays": 90,
  "enableAllProjectMcpServers": false,
  "skipDangerousModePermissionPrompt": true,
  "spinnerVerbs": {
    "mode": "replace",
    "verbs": [" ⠋", " ⠙", " ⠹", " ⠸", " ⠼", " ⠴", " ⠦", " ⠧", " ⠇", " ⠏"]
  },
  "plugins": [
    {
      "name": "context7",
      "enabled": true
    },
    {
      "name": "safety-net",
      "enabled": true
    },
    {
      "name": "ralph-loop",
      "enabled": true
    }
  ]
}

Bottom line

Configuring Claude Code isn't one-and-done. I revisit regularly, add deny patterns when cautious, adjust timeouts. The goal: an environment that pushes toward best practices.

Copy this config, adapt to your context (your sensitive paths, dangerous commands), iterate. Claude Code quickly becomes a real productivity multiplier.

Previous post

← Building a complete media center with Jellyfin and the *arr stack

Next post

Managing photos with self-hosted Immich→
← Back to blog

Table of Contents

  • Introduction: mastering your AI assistant (or it masters you)
  • Environment variables: the core
  • Saving your quota (important stuff)
  • Managing bash timeouts (crucial!)
  • Experimental features (actually useful)
  • Privacy first (because why not)
  • Security permissions: lock down what matters
  • Hooks: automating before/after
  • UI configuration and polish (the small things)
  • Plugins: the superpowers
  • The complete file
  • Bottom line