Detect wrong MCP binary in integration-test skill (#154)#155
Merged
Conversation
When iterating in a git worktree nested under the main repo, Claude Code launches the stdio MCP server from the parent repo's `.build/` rather than the worktree's. /resume makes it sticky. The skill's existing `preview_build_info` staleness check happily reports green in this state — the binary at the resolved path matches its running process; it just isn't the binary the developer is iterating on. Hit live during PR #153 validation: a full integration-test run reported green against a parent-repo binary that didn't have any of the PR's changes. Step 2 of the skill now runs two independent checks: 2a. Wrong-binary: derive expected path from `git rev-parse --show-toplevel` of the skill's CWD, resolve symlinks, compare to `preview_build_info`'s `binaryPath`. Mismatch aborts with a tailored relaunch message that names /resume as the trap. 2b. Stale-binary: existing check, unchanged. No change to `preview_build_info` itself — the MCP server has no way to know what the developer's current worktree is, and end users who installed via brew/mint don't have a `<root>/.build/...` layout to compare against. The skill is the only programmatic caller and the right place for the developer-mode check. Also documents the footgun in AGENTS.md near the existing "Refresh stdio" guidance, with a pointer to the skill's automatic detection. Out of scope: the upstream Claude Code path-resolution / /resume behavior. Tracked separately against anthropics/claude-code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Earlier wording framed worktree-based work as a footgun to detect. The actual story is simpler: open Claude Code from inside the worktree (don't /resume across them) and the relative .mcp.json command path resolves to the worktree's binary on its own. The skill's Step 2 detection is a safety net for accidental /resume, not the primary mechanism. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #154.
Summary
When iterating in a git worktree nested under the main repo (e.g.,
.claude/worktrees/<name>/), Claude Code launches the stdio MCP server from the parent repo's.build/, not the worktree's./resumemakes it sticky — it preserves the original project root regardless of relaunch CWD. The integration-test skill'spreview_build_infostaleness check (#147 / #150) happily reports green in this state: the binary at the resolved path does match its running process; it just isn't the binary the developer is iterating on.Hit live during PR #153 validation — a full integration-test run reported green against a parent-repo binary that didn't have any of the PR's changes.
Approach
Step 2 of the skill now runs two independent checks:
git rev-parse --show-toplevelof the skill's CWD, resolve symlinks the same waypreview_build_infodoes, compare to its returnedbinaryPath. Mismatch aborts with a tailored relaunch message that explicitly names/resumeas the trap.Both checks must pass before proceeding. They cover independent failure modes — wrong binary entirely vs stale binary at the right path.
Why not change
preview_build_infoitselfThe MCP server has no way to know what the developer's current worktree is. Users who installed PreviewsMCP via brew / mint / a binary copy have no
<root>/.build/<arch>/debug/previewsmcplayout to compare against — a server-side check would falsely flag every end-user install as "wrong tree." The skill is the only programmatic caller ofpreview_build_infoand the right place for developer-mode context (CWD, expected build layout).Documentation
Adds a "worktree footgun" paragraph to AGENTS.md alongside the existing "Refresh stdio" guidance, with a pointer to the skill's automatic detection.
Out of scope
The upstream Claude Code behavior —
${workspaceFolder}not expanding in.mcp.jsoncommand(anthropics/claude-code#3239, #9427), and/resumepreserving the original project root regardless of relaunch CWD. Tracked separately upstream.Test plan
/integration-testruns in a worktree, Step 2 will exercise the new check end-to-end🤖 Generated with Claude Code