the_ogandClaude Opus 4.8 4a95b370b9
CI / Tests (py3.12 / windows-latest) (pull_request) Successful in 24s
CI / Lint (ruff) (pull_request) Successful in 21s
CI / Tests (py3.10 / ubuntu-latest) (pull_request) Successful in 32s
CI / Tests (py3.12 / ubuntu-latest) (pull_request) Successful in 31s
CI / Tests (py3.13 / ubuntu-latest) (pull_request) Successful in 35s
CI / Catalog signature (pull_request) Successful in 26s
refactor: introduce ClientSpec adapter; route Claude Desktop + Code through it (#5)
Cross-client support (Cursor / Windsurf / VS Code) was blocked on Claude's
layout being hard-coded throughout the code: servers always under the literal
"mcpServers" key, a fixed set of Claude file locations, and "which client is
this?" answered by sniffing a filename. Adding a client that differs on any of
those axes meant chasing those assumptions through a dozen sites.

This is phase 1 of #5: the keystone refactor, with NO behaviour change. It adds
a ClientSpec adapter that captures the three things that vary across clients --
the top-level servers key, the config discovery paths, and the per-server value
shape -- plus the capability flags that were previously computed inline from a
filename (does the client expand ${VAR}? can we offer Restart?).

- ClientSpec (frozen dataclass): servers_key, disabled_key, config_filename,
  expands_env_refs, supports_restart, and entry_to_internal/entry_from_internal
  -- the per-server translation seam, identity for any mcpServers-shaped client,
  the single point a differently-shaped client (VS Code's type/inputs form)
  overrides.
- CLAUDE_DESKTOP and CLAUDE_CODE specs; both use mcpServers + the existing
  parking key, so their translation is the identity and nothing changes for
  today's users. resolve_client(path) reproduces the old filename rule exactly;
  each Profile now carries its resolved .client.
- extract_servers / apply_servers / _server_sections / external_change_summary
  take an optional spec and default to Claude's layout, so every existing call
  site and test that omits a spec is byte-for-byte unchanged. The cardinal rule
  now generalises: apply_servers only ever writes the client's own two keys,
  parameterised rather than hard-coded.
- profile_targets_claude_desktop and client_expands_env_refs are now thin reads
  off the profile's spec -- one source of truth for client identity instead of
  scattered filename checks -- with identical answers.
- GUI: the load, Copy-to, save and stale-merge paths pass the profile's spec
  into the core calls. Mechanical; no logic moved into bcc.py (which CI can't
  test -- no PySide6).

Tests: +14. Existing suite unchanged and green (behaviour preservation). A
synthetic non-mcpServers spec ("servers" key, a different disabled key, a
per-server `type` field) exercises the whole pipeline -- extract, apply,
masking, external-change diff -- proving the seam actually generalises before
any real client depends on it. 458 passed, 1 skipped; ruff clean.

Refs #5

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKwBecy6N83jnqQmw8ezwE
2026-08-04 02:53:51 +00:00
2026-06-29 14:12:50 -04:00

Better Claude Config (BCC)

A small, cross-platform GUI for editing the mcpServers block of Claude Desktop and Claude Code installs — without ever hand-writing JSON.

BCC only ever touches mcpServers (and its own _disabledMcpServers parking key). Every other key in your config is preserved verbatim, in its original order. Each write is atomic and makes a timestamped backup first.

Download (no Python required)

Pre-built self-contained binaries are attached to every GitHub Release:

Platform Download Run
macOS BetterClaudeConfig-macOS.zip Unzip → drag BetterClaudeConfig.app to Applications
Windows BetterClaudeConfig-Windows.zip Unzip → double-click BetterClaudeConfig.exe
Linux BetterClaudeConfig-Linux.tar.gz Extract → run BetterClaudeConfig

macOS Gatekeeper note: the app is not notarized. On first launch, right-click → Open, or run xattr -cr /Applications/BetterClaudeConfig.app in a terminal.

Verifying your download

BCC isn't code-signed — there's no budget for a paid certificate (macOS Developer ID, Windows Authenticode). Instead, every release publishes a SHA256SUMS file listing the checksum of each archive, detached-signed with Ed25519 as SHA256SUMS.sig. Both are attached to the release alongside the binaries.

What this proves: the file you downloaded is byte-for-byte what we published, and the manifest itself was signed by our release key.

What this does NOT do: it does not make the binary "safe," and it does not remove the macOS Gatekeeper or Windows SmartScreen warning — those are only suppressed by a paid OS-vendor certificate, which this project doesn't have. Verifying checksums is about detecting tampering in transit or on a mirror, not about vouching for the software.

This manifest is signed with BCC's release key, which is a different key from the one that signs the MCP server catalog — see Signing keys below for why, and for the public key value to use with --pubkey-b64 below.

macOS / Linux

# From inside the folder you downloaded the release files into:
sha256sum -c SHA256SUMS

If your sha256sum complains about missing files, download SHA256SUMS into the same directory as the archive you downloaded — it lists every platform's archive, and only the one(s) present will be checked.

To also verify the manifest's signature (optional, requires Python + pip install cryptography and a checkout of this repo):

python3 scripts/sign_checksums.py verify \
  --sums SHA256SUMS --sig SHA256SUMS.sig \
  --pubkey-b64 "<the release public key from Signing keys, below>"

Windows (PowerShell)

Get-FileHash .\BetterClaudeConfig-Windows.zip -Algorithm SHA256

Compare the printed hash (case-insensitively) against the matching line in SHA256SUMS.

If a release has no SHA256SUMS.sig

The signing key is a repo secret that has to be configured manually; if a release is missing the .sig file, the checksums themselves are still valid and safe to check against — the release workflow only skips signing, never checksum generation.

Signing keys

BCC uses two separate Ed25519 keypairs, deliberately never the same key, because they protect different things and live in different places:

Catalog key Release key
Signs data/catalog.json (the MCP server catalog every user's app trusts) SHA256SUMS (the checksum manifest for release binaries)
Verified by bcc_core.CATALOG_PUBKEYS scripts/sign_checksums.RELEASE_PUBKEYS
Lives Offline, passphrase-encrypted, maintainer's machine only (OS keychain or an encrypted file outside the repo — see the Catalog Console, issue #62) A Gitea Actions repo secret, RELEASE_SIGNING_KEY — intentionally CI-resident
Generated with python catalog_console.py keygen python catalog_console.py keygen --release
Exported for CI with (never — there is no supported way to export this key) python catalog_console.py show-seed-b64 --release

Why two keys: the catalog key is the root of trust for what BCC actually executes on a user's machine — every command/args pair in the shipped catalog is only there because this key signed it. If that key and the release-checksum key were the same (as they briefly were — see issue #68), then anything that can exfiltrate a Gitea Actions secret (a malicious workflow-file PR, a compromised runner, a leaky log) could sign a catalog every user's copy of BCC would trust, not just a checksum manifest. Splitting them means a CI/secret compromise burns the release key, never the catalog key — checksums for a future release could be forged, which is bad, but no attacker gains the ability to make BCC run arbitrary commands on installs that trust the catalog. That asymmetry is the entire point of having two keys instead of one.

The catalog key is never meant to leave the maintainer's machine: it's generated, stored, unlocked, and used to sign entirely inside the Catalog Console (catalog_console.py), and catalog_console.py show-seed-b64 refuses to run without --release specifically so the catalog seed can't be exported by habit or muscle memory.

Release signing public key (Ed25519, base64, raw 32 bytes) — this is the RELEASE key, not the catalog key:

<PLACEHOLDER — AJ: paste the release public key from `catalog_console.py keygen --release` here>

Run from source

pip install -r requirements.txt
python bcc.py

(Python 3.10+, PySide6 6.6+.)

What it does

  • Auto-discovers installs — scans the platform's app-support folder for any Claude* directory (so Claude and Claude-Work both show up) and finds Claude Code's user-scope config at ~/.claude.json (the file claude mcp add writes). Use Add config… to point at any other file manually — e.g. a project's .mcp.json.

  • Form-based editing — name, command, args (one per line), env vars, or for remote servers: URL, transport, and headers. No raw JSON.

  • Paste JSON — even broken JSON — drop in any snippet from an MCP doc (full mcpServers block, inner map, or a single bare server object); it's parsed and merged. The paste box parses as you type and auto-repairs the stuff docs and chat windows love to break: markdown fences, surrounding prose, comments, trailing or missing commas, smart quotes, single quotes, unquoted keys, and unclosed braces — and tells you exactly what it fixed before you commit.

  • Drag & drop a .json file onto the window to import servers from it.

  • Copy to ▸ — copy the selected server straight into your other install.

  • Active / Disabled sections — servers are shown in two labelled lists with live counts, so a server that's switched off in the config is obvious at a glance. Toggle a server's checkbox to move it between sections (disabled servers are parked under _disabledMcpServers, which Claude ignores).

  • Dependency check + diagnostics — each server shows whether its command is actually found on PATH:

    • ● green — found on the normal PATH; will work anywhere.
    • ▲ amber (PATH-risk) — found, but only in a location BCC added on top of the inherited PATH. It'll work when you launch Claude from a terminal, but a double-clicked .app may not see it. This is the usual cause of "the tool says it's fine but Claude won't start the server." One click on Use full path ↳ rewrites the bare command (npx) to its absolute path so any launch finds it.
    • ● red (broken) — not found anywhere.
    • ◆ blue — remote (url) server. Test connection does a live reachability check on a background thread (any HTTP response = reachable).

    Each section header shows a broken / PATH-risk count badge, and selecting a flagged server auto-opens a Details panel with a full, copy-pasteable report: which command resolved to what, tailored install hints, and the exact PATH that was searched (with + marking the dirs BCC added). Re-check re-scans PATH after you install something; Copy diagnostics grabs the whole report for a bug report.

After saving, restart that Claude install for changes to take effect.

Config locations it scans

Claude Desktop

OS Base it scans for Claude*
macOS ~/Library/Application Support
Windows %APPDATA%
Linux ~/.config

Claude Code (all platforms): ~/.claude.json (user scope). If servers are found parked in ~/.claude/settings.json — where Claude Code ignores them — that file is also listed, marked legacy, so you can copy them over.

Files

  • bcc.py — the GUI.
  • bcc_core.py — all the file/JSON/validation/dependency logic (no GUI deps).
  • test_core.py — unit suite for the core (python test_core.py).
  • bcc.spec — PyInstaller build spec (cross-platform).
  • scripts/build_icons.py — regenerates icons/app.icns and icons/app.ico from source PNGs.
  • scripts/sign_checksums.py — generates and Ed25519-signs the release SHA256SUMS manifest (see Verifying your download).
  • catalog_console.py / catalog_review.py — maintainer-only, never shipped to users (excluded from bcc.spec; see tests/test_catalog_console_packaging.py). The Catalog Console: review + sign data/catalog.json, and generate/manage both signing keys (keygen, keygen --release) — see Signing keys.

Building from source

pip install -r requirements-dev.txt
python scripts/build_icons.py   # regenerate icons if needed
pyinstaller bcc.spec
# macOS  → dist/BetterClaudeConfig.app
# Windows → dist/BetterClaudeConfig.exe
# Linux  → dist/BetterClaudeConfig

Releases are built automatically by GitHub Actions (.github/workflows/release.yml) when a version tag is pushed:

git tag v1.0.0 && git push --tags

Rebrand

The accent color is one constant (ACCENT) at the top of bcc.py.

License

MIT — see LICENSE.

S
Description
No description provided
Readme MIT
8.1 MiB
2026-08-14 12:59:27 -04:00
Languages
Python 100%