[BUG] Claude_Preview MCP preview_start spawns dev server with main-repo cwd instead of session's worktree cwd
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary:
Calling the Claude_Preview MCP tool mcp__Claude_Preview__preview_start from a Claude Code session whose cwd is a git worktree under <repo>/.claude/worktrees/<branch> spawns the dev-server child process with cwd = main repo, not the worktree. The session believes it is exercising its branch under test; in reality the dev server is compiling and serving the main repo's currently-checked-out branch, writing to main_repo/.next/, and binding the default port (3000) — colliding with whatever other agent or human task is using the main repo on the same machine.
Actual Behavior: cwd = <repo> (main repo). The dev server serves the main repo's currently-checked-out branch and writes to <repo>/.next/. Port 3000 is bound on the main repo, colliding with any parallel main-repo dev server.
Confirmed via lsof on 2026-05-28 (PID 61276 spawned from a worktree session at /Users/jeff/Dev/GitHub/bounce/.claude/worktrees/BNC-1457-lounge-slug-validation-rls; lsof -p 61276 | grep cwd returned /Users/jeff/Dev/GitHub/bounce).
What Should Happen?
Expected: cwd = <repo>/.claude/worktrees/repro-branch. The dev server should serve the worktree's branch and write to <worktree>/.next/.
Error Messages/Logs
Steps to Reproduce
Reproduction:
- In a repo with multiple worktrees:
git worktree add .claude/worktrees/repro-branch -b repro-branch origin/main. - Open a Claude Code session whose cwd is
<repo>/.claude/worktrees/repro-branch. Confirm$CLAUDE_PROJECT_DIRis the worktree path. - From that session, call
mcp__Claude_Preview__preview_startwith a Next.js dev command (e.g.,PORT=0 bun run dev). - After the MCP reports a server is up, find the spawned PID (the Next.js / bun parent of the node child), then run
lsof -p <pid> | awk '/cwd/{print $NF}'.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude 1.9255.2 (1dc8f7) 2026-05-27T01:57:20.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Environment:
- Claude Code: v2.1.149 (Claude.app desktop), macOS Darwin 25.5.0
- Project: a Next.js monorepo where the user runs parallel Claude Code sessions out of git worktrees under <repo>/.claude/worktrees/<branch-name>
- Dev command:
bun run dev(Next.js, Bun workspace)
Attempted workarounds that did NOT fix it:
- Restarting Claude Code (full app quit + relaunch).
- Updating to the latest available version (still 2.1.149 at time of test).
- Routing the dev command through
sh -c "cd <worktree> && exec bun run dev"inlaunch.json— the resulting node child still ended up with cwd = main repo. Either the MCP forces cwd post-spawn orbun run devre-resolves to the main-repo workspace root via the lockfile.
Impact:
- Worktree sessions silently corrupt main-repo
.next/cache and serve the wrong branch under test. - Two parallel agents on the same machine fight over port 3000.
- Verification workflows (
/test-work-item local, anypreview_*round-trip) produce false-positive results because the page being tested is not the session's branch.
Suggested fix:
The spawn-time cwd of the dev-server child should be derived from $CLAUDE_PROJECT_DIR (or equivalently the session's primary working directory shown in the system prompt), not from any cached or globally-resolved project root. If $CLAUDE_PROJECT_DIR is set, the child's cwd should equal it.
Related upstream issues (same worktree-context defect class — not duplicates):
- anthropics/claude-code#36182 — "Worktree: Edit/Read tools use main workspace paths instead of worktree paths". Same shape (worktree session → tool targets main-repo paths) but reports the bug on the built-in Edit/Read/Write tools rather than the Claude_Preview MCP. Notably, that ticket's description explicitly assumes
preview_startis the correct path ("The running app (via preview_start) executes from the worktree and sees none of the changes") — i.e. as of 2026-03-19 the reporter believed preview_start was worktree-scoped. This report is evidence that either (a) preview_start has since regressed, or (b) preview_start was already broken in the same direction in March but went unnoticed because the Edit/Read bug masked it. - anthropics/claude-code#61062 — "Worktree-session feature doesn't carry project-scoped MCP config/auth from originalCwd to worktreePath". A different worktree-boundary leakage on the MCP layer (
~/.claude.json.projects[<path>]entries don't propagate across the originalCwd→worktreePath transition). Not the same surface as this report, but the underlying "worktree session inherits main-cwd state" theme is identical — worth fixing both passes in one sweep.
Local workaround we have applied:
A user-scope PreToolUse hook in ~/.claude/settings.json that matches mcp__Claude_Preview__preview_start and rejects the call with exit 2 + an explanatory message when $CLAUDE_PROJECT_DIR matches */.claude/worktrees/*. From worktree sessions we now manually spawn PORT=0 bun run dev & via the Bash tool, capture the bound port from lsof, and drive Claude_in_Chrome against http://localhost:<port> instead.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗