-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Context
PR #297 fixed MCPServerCheck falsely reporting MCP servers as "not registered" in subdirectory projects. The root cause: Claude CLI keys local-scope MCP servers in ~/.claude.json by the git root, but ProjectDetector.findProjectRoot() can return a subdirectory (when CLAUDE.local.md is found before .git/).
#297 added a walk-up loop in MCPServerCheck.check() to bridge the gap. However, the same mismatch exists in other call sites, and the fix should be shared rather than duplicated.
Remaining issues
1. ConfigurationDiscovery has the same bug
Export/ConfigurationDiscovery.swift:165-167 does the same direct projects[projectRoot.path] lookup. mcs export from a subdirectory project silently misses project-scoped MCP servers.
2. Walk-up logic should be a shared utility
The walk-up-to-git-root logic in MCPServerCheck should be extracted (e.g., ProjectDetector.findGitRoot(from:) or a helper that probes ~/.claude.json project keys). Both MCPServerCheck and ConfigurationDiscovery should use it.
3. Missing tests for walk-up behavior
PR #297 added no tests. The walk-up loop has non-trivial termination logic (.git/ sentinel + / guard). Per CLAUDE.md, integration tests are mandatory for doctor check changes. Minimum:
- Subdirectory project root finds server keyed at git root →
.pass - Walk-up stops at
.git/boundary → doesn't escape the repo - Regression:
projectRoot == gitRootstill works
4. Minor: candidate: URL? should be plain URL
deletingLastPathComponent() always returns a non-nil URL. The optional wrapper is unnecessary.
Why this matters
| Command | Reads ~/.claude.json directly? |
Affected? |
|---|---|---|
mcs doctor |
Yes (MCPServerCheck) |
Fixed by #297 |
mcs export |
Yes (ConfigurationDiscovery) |
Still broken |
mcs sync |
No (delegates to claude CLI) |
Not affected |
mcs pack remove |
No (delegates to claude CLI) |
Not affected |