[BUG] Claude_Preview MCP preview_start spawns dev server with main-repo cwd instead of session's worktree cwd

Open 💬 2 comments Opened May 28, 2026 by jhopper28

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:

  1. In a repo with multiple worktrees: git worktree add .claude/worktrees/repro-branch -b repro-branch origin/main.
  2. Open a Claude Code session whose cwd is <repo>/.claude/worktrees/repro-branch. Confirm $CLAUDE_PROJECT_DIR is the worktree path.
  3. From that session, call mcp__Claude_Preview__preview_start with a Next.js dev command (e.g., PORT=0 bun run dev).
  4. 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" in launch.json — the resulting node child still ended up with cwd = main repo. Either the MCP forces cwd post-spawn or bun run dev re-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, any preview_* 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_start is 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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗