Pasted config snippets no longer have to be valid JSON. repair_json_text() auto-fixes markdown fences, surrounding prose, // /* */ # comments, trailing and missing commas, smart quotes, single quotes, unquoted keys, Python/JS literals, and unclosed braces. parse_pasted_json_verbose() reports every repair applied; the paste dialog now parses as you type and previews exactly what will be added and what was fixed. Also includes ruff lint fixes and formatting across bcc.py/bcc_core.py.
4.2 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/ServerEntrydataclasses (the data model)discover_profiles()— scans the platform's app-support directory forClaude*folders (Claude Desktop) and always adds~/.claude/settings.json(Claude Code, cross-platform)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 anlru_cache-memoizedaugmented_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 stateServerEditor— right-panel form with aQStackedWidgetfor stdio vs remote pages; callscore.check_dependency()on every field changeKeyValueTable— reusable widget for env vars and headersConnTester(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 →.appbundle) and Windows/Linux (onefile). Platform-aware icon selection.icons/app.icns(macOS) andicons/app.ico(Windows) are pre-generated and committed; source PNGs are inicons/twin-gears/rounded/.scripts/build_icons.py— regenerates both icon files from source PNGs. Usesiconutil(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
ACCENTat the top ofbcc.py— the one constant to change for a rebrandKNOWN_FIELDSinbcc_core.py— fields the editor renders; anything else on a server object is preserved as_extrainServerEditorDISABLED_KEY = "_disabledMcpServers"— the parking key for disabled serversMAX_BACKUPS = 15— rolling backup limit per config file