Files
AJ b16c0fd526
CI / Lint (ruff) (push) Successful in 7s
CI / Tests (py3.10) (push) Successful in 7s
CI / Tests (py3.12) (push) Successful in 7s
fix: point Claude Code profile at ~/.claude.json, not settings.json
Claude Code stores user-scope MCP servers in ~/.claude.json (what
'claude mcp add' writes); ~/.claude/settings.json is for permissions
and hooks and rejects an mcpServers key with a schema error, so BCC
was reading (and writing) servers where Claude Code never looks.

If servers are found parked in settings.json, that file is still
listed as 'Claude Code (legacy settings.json)' so they can be copied
into the real config via Copy to. Docs updated; verified against
docs.claude.com/en/docs/claude-code/settings.
2026-07-02 00:27:01 -04:00

4.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Install runtime dependency
pip install -r requirements.txt
python bcc.py          # run the GUI

# Test & lint (no GUI / PySide6 needed — tests only exercise bcc_core)
pip install -r requirements-dev.txt
python -m pytest       # unit tests in tests/
ruff check .           # lint
ruff format .          # format (CI enforces ruff format --check)

# Build a self-contained binary
python scripts/build_icons.py   # regenerate icons/app.icns + icons/app.ico if needed
pyinstaller bcc.spec
# macOS  → dist/BetterClaudeConfig.app
# Windows → dist/BetterClaudeConfig.exe
# Linux  → dist/BetterClaudeConfig

Requires Python 3.10+. Runtime dependency: PySide6>=6.6. Tooling config (ruff, pytest, project metadata) lives in pyproject.toml. CI (.github/workflows/ci.yml) runs lint + tests on every push/PR; releases build on tag push (release.yml).

Architecture

The codebase is split into two layers:

bcc_core.py — All logic with no GUI imports. Contains:

  • Profile / ServerEntry dataclasses (the data model)
  • discover_profiles() — scans the platform's app-support directory for Claude* folders (Claude Desktop) and always adds ~/.claude.json (Claude Code user scope — what claude mcp add writes). ~/.claude/settings.json is NOT a server config (it rejects mcpServers with a schema error) and is only surfaced, labelled legacy, if servers are found parked in it. Project-scope .mcp.json files can be opened via Add config…
  • load_config / extract_servers / apply_servers / write_config — the read/write pipeline; writes are atomic with rotating timestamped backups in .bcc_backups/
  • parse_pasted_json() / parse_pasted_json_verbose() — accepts three JSON shapes (full config, inner map, or bare server object). Input does not have to be valid JSON: repair_json_text() auto-fixes markdown fences, surrounding prose, // /* */ # comments, trailing/missing commas, smart quotes, single quotes, unquoted keys, Python/JS literals, and unclosed braces. The verbose variant also returns human-readable notes describing every repair applied (shown live in the paste dialog)
  • check_dependency() / diagnostics_text() / pin_command_path() — PATH resolution logic; distinguishes "found on normal PATH" (ok) vs "found only on augmented PATH" (warn) vs "not found" (missing). Uses an lru_cache-memoized augmented_path() that extends the inherited PATH with common runtime locations (nvm, homebrew, cargo, volta, etc.)
  • test_remote() — synchronous HTTP reachability check, intended to run off the UI thread

bcc.py — PySide6 GUI that is a thin shell over bcc_core. Key classes:

  • MainWindow — manages the profile combo, two server tables (active/disabled), action bar, and dirty state
  • ServerEditor — right-panel form with a QStackedWidget for stdio vs remote pages; calls core.check_dependency() on every field change
  • KeyValueTable — reusable widget for env vars and headers
  • ConnTester(QThread) — background thread for remote reachability tests

The cardinal rule: apply_servers() only ever writes to mcpServers and _disabledMcpServers. All other keys in the user's config are preserved verbatim and in their original order.

Disabled servers are parked under _disabledMcpServers (which Claude Desktop ignores) so they can be re-enabled without losing their definition.

Packaging

  • bcc.spec — PyInstaller spec; handles macOS (onedir → .app bundle) and Windows/Linux (onefile). Platform-aware icon selection.
  • icons/app.icns (macOS) and icons/app.ico (Windows) are pre-generated and committed; source PNGs are in icons/twin-gears/rounded/.
  • scripts/build_icons.py — regenerates both icon files from source PNGs. Uses iconutil (macOS-only) for .icns, Pillow for .ico.
  • .github/workflows/release.yml — builds on all three platforms on tag push, publishes as GitHub Release assets.

To release: git tag vX.Y.Z && git push --tags.

Key constants

  • ACCENT at the top of bcc.py — the one constant to change for a rebrand
  • KNOWN_FIELDS in bcc_core.py — fields the editor renders; anything else on a server object is preserved as _extra in ServerEditor
  • DISABLED_KEY = "_disabledMcpServers" — the parking key for disabled servers
  • MAX_BACKUPS = 15 — rolling backup limit per config file