Core (bcc_core.py): server_log_path(name: str) -> Path | None — returns the platform-specific Claude Desktop MCP log path for a server, or None if it doesn't exist yet.
Other platforms: None (no known Claude Desktop log location)
GUI (bcc.py): new "View logs" button in the server detail panel (ServerEditor), next to "Test launch" / "Details". Opens LogViewerDialog — a read-only QPlainTextEdit that polls the log file every 1.5s via QTimer (auto-tail, scrolls to bottom only if already at the bottom), tails at most the last 300 KB, and shows a graceful "No log file for '' yet." message instead of erroring when the file doesn't exist.
Tests (tests/test_core.py): 5 new tests for server_log_path — macOS found/missing, Windows found/missing (via monkeypatch.setattr(sys, "platform", ...) + APPDATA env), and an unsupported-platform case. server_log_path branches on sys.platform only (not os.name), so tests never mutate os.name, which would otherwise corrupt pathlib's internal Path subclass dispatch mid-test-run.
Verification
ruff check . — all checks passed
ruff format --check . — clean
pytest -q — 97 passed (was 92 on main; +5 new tests), 0 failures/errors
bcc_core.py (incl. server_log_path) imports and runs with no display required
Caveats
bcc.py needs a real Qt platform backend to import in a headless CI-like box (pre-existing PySide6 constraint, not introduced by this change) — verification here exercised bcc_core.py directly plus ruff/pytest against the full tree.
The log viewer never writes to the log file — strictly read-only, per the diagnostics-panel pattern already used elsewhere in the app.
Closes #6
## What
- **Core** (`bcc_core.py`): `server_log_path(name: str) -> Path | None` — returns the platform-specific Claude Desktop MCP log path for a server, or `None` if it doesn't exist yet.
- macOS: `~/Library/Logs/Claude/mcp-server-<name>.log`
- Windows: `%APPDATA%\Claude\logs\mcp.log`
- Other platforms: `None` (no known Claude Desktop log location)
- **GUI** (`bcc.py`): new "View logs" button in the server detail panel (`ServerEditor`), next to "Test launch" / "Details". Opens `LogViewerDialog` — a read-only `QPlainTextEdit` that polls the log file every 1.5s via `QTimer` (auto-tail, scrolls to bottom only if already at the bottom), tails at most the last 300 KB, and shows a graceful "No log file for '<name>' yet." message instead of erroring when the file doesn't exist.
- **Tests** (`tests/test_core.py`): 5 new tests for `server_log_path` — macOS found/missing, Windows found/missing (via `monkeypatch.setattr(sys, "platform", ...)` + `APPDATA` env), and an unsupported-platform case. `server_log_path` branches on `sys.platform` only (not `os.name`), so tests never mutate `os.name`, which would otherwise corrupt `pathlib`'s internal `Path` subclass dispatch mid-test-run.
## Verification
- `ruff check .` — all checks passed
- `ruff format --check .` — clean
- `pytest -q` — 97 passed (was 92 on `main`; +5 new tests), 0 failures/errors
- `bcc_core.py` (incl. `server_log_path`) imports and runs with no display required
## Caveats
- `bcc.py` needs a real Qt platform backend to import in a headless CI-like box (pre-existing `PySide6` constraint, not introduced by this change) — verification here exercised `bcc_core.py` directly plus `ruff`/`pytest` against the full tree.
- The log viewer never writes to the log file — strictly read-only, per the diagnostics-panel pattern already used elsewhere in the app.
the_og
added the P1 label 2026-07-07 20:41:11 -04:00
Supervisor review (Cowork): approve. CI run #158 green; isolated diff. server_log_path returns the correct platform paths (None when missing); LogViewerDialog is read-only with throttled tailing and a graceful "no log yet". Same benign _normalize_unicode NBSP-line rewrite as #22/#24/#25 (resolve at merge). Ready for v1.2.0.
Supervisor review (Cowork): **approve.** CI run #158 green; isolated diff. `server_log_path` returns the correct platform paths (None when missing); `LogViewerDialog` is read-only with throttled tailing and a graceful "no log yet". Same benign `_normalize_unicode` NBSP-line rewrite as #22/#24/#25 (resolve at merge). Ready for v1.2.0.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #6
What
bcc_core.py):server_log_path(name: str) -> Path | None— returns the platform-specific Claude Desktop MCP log path for a server, orNoneif it doesn't exist yet.~/Library/Logs/Claude/mcp-server-<name>.log%APPDATA%\Claude\logs\mcp.logNone(no known Claude Desktop log location)bcc.py): new "View logs" button in the server detail panel (ServerEditor), next to "Test launch" / "Details". OpensLogViewerDialog— a read-onlyQPlainTextEditthat polls the log file every 1.5s viaQTimer(auto-tail, scrolls to bottom only if already at the bottom), tails at most the last 300 KB, and shows a graceful "No log file for '' yet." message instead of erroring when the file doesn't exist.tests/test_core.py): 5 new tests forserver_log_path— macOS found/missing, Windows found/missing (viamonkeypatch.setattr(sys, "platform", ...)+APPDATAenv), and an unsupported-platform case.server_log_pathbranches onsys.platformonly (notos.name), so tests never mutateos.name, which would otherwise corruptpathlib's internalPathsubclass dispatch mid-test-run.Verification
ruff check .— all checks passedruff format --check .— cleanpytest -q— 97 passed (was 92 onmain; +5 new tests), 0 failures/errorsbcc_core.py(incl.server_log_path) imports and runs with no display requiredCaveats
bcc.pyneeds a real Qt platform backend to import in a headless CI-like box (pre-existingPySide6constraint, not introduced by this change) — verification here exercisedbcc_core.pydirectly plusruff/pytestagainst the full tree.Supervisor review (Cowork): approve. CI run #158 green; isolated diff.
server_log_pathreturns the correct platform paths (None when missing);LogViewerDialogis read-only with throttled tailing and a graceful "no log yet". Same benign_normalize_unicodeNBSP-line rewrite as #22/#24/#25 (resolve at merge). Ready for v1.2.0.Superseded by #26 (release: v1.2.0), which merged this change into
mainas part of the integrated release. Closing.Pull request closed