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
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.
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.
- Auto-discovers Claude Code (~/.claude/settings.json) alongside Claude Desktop
- Generated icons/app.icns (macOS) and icons/app.ico (Windows) from rounded PNGs
- bcc.spec: PyInstaller spec for all platforms (.app on macOS, onefile on Windows/Linux)
- .github/workflows/release.yml: builds and publishes GitHub Release on version tags
- scripts/build_icons.py: regenerates icon files from source PNGs
- requirements-dev.txt: adds pyinstaller and pillow for building
- CLAUDE.md: initial repo guidance for Claude Code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>