Skip to content

Add worktree handoff and status tools to the t3-code MCP server#3754

Open
nsxdavid wants to merge 9 commits into
pingdotgg:mainfrom
nsxdavid:pr/mcp-worktree-tools
Open

Add worktree handoff and status tools to the t3-code MCP server#3754
nsxdavid wants to merge 9 commits into
pingdotgg:mainfrom
nsxdavid:pr/mcp-worktree-tools

Conversation

@nsxdavid

@nsxdavid nsxdavid commented Jul 6, 2026

Copy link
Copy Markdown

What Changed

Closes #3753.

Adds two tools to the t3-code MCP server:

  • worktree_handoff creates a worktree and re-points the calling thread at it. branch is the only required argument; the rest are optional:

    • baseRef defaults to the branch checked out in the project workspace
    • startFromOrigin defaults to the existing "new worktrees start from origin" server setting
    • path defaults to the managed worktrees directory
    • runSetupScript defaults to true
  • worktree_status reports the thread's current binding (attached or not, worktree path, branch, workspace root) so an agent can check before trying.

No new machinery. The handler runs the same sequence as the thread-bootstrap path in ws.ts: GitWorkflowService.createWorktree, a thread.meta.update dispatch, a status refresh, and the project setup script runner. The session restart with resume on cwd change picks the rest up on the next turn, and worktree cleanup on thread delete works unchanged since it keys off worktreePath. A worktree capability is added alongside preview in the MCP credential.

Deliberately not included: a detach/undo tool. The UI has no equivalent (worktree removal only happens on thread delete), and detaching raises lifecycle questions that seem worth their own discussion.

Why

See #3753: an agent can create a worktree from its shell, but the thread binding lives in T3 Code's orchestration state and nothing agent-reachable can update it, so agent-driven worktree setup dead-ends. The MCP server is the only channel T3 Code exposes to the agent, so this is the only place the capability can live.

Tested with unit tests over the handlers, an HTTP-level test that drives the production MCP layer end to end (auth, initialize, tools/list), and manually in a packaged Windows build: status, handoff from origin, session resume inside the worktree with conversation intact, and cleanup on thread delete.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Agents can create worktrees and change thread metadata via git and orchestration; rollback and concurrency guards reduce orphan worktrees, but filesystem and git side effects remain meaningful.

Overview
Adds worktree_handoff and worktree_status to the t3-code MCP server so agents can bind a thread to a git worktree through orchestration instead of only creating worktrees in a shell.

worktree_handoff creates a worktree (optional origin-based base, absolute path, setup script), dispatches thread.meta.update with branch and worktreePath, refreshes VCS status, and returns setup-script outcome. It rejects threads already on a worktree, invalid paths, and concurrent handoffs per thread; if metadata update fails, it force-removes the new worktree.

worktree_status is read-only: attachment state, paths, branch, workspace root, and the server default for startFromOrigin.

New MCP credentials include a worktree capability alongside preview; handlers use dedicated requireWorktreeCapability checks. Shared Effect schemas and tagged errors live in packages/contracts/worktree.ts. The HTTP MCP layer registers the worktree toolkit next to preview; handler and HTTP tools/list tests cover the flow.

Reviewed by Cursor Bugbot for commit a33fb24. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add worktree_handoff and worktree_status tools to the t3-code MCP server

  • Defines two new MCP tools in tools.ts: worktree_handoff for end-to-end git worktree creation with optional origin fetch, thread metadata update, rollback on failure, and optional setup script execution; and worktree_status to query current worktree attachment state.
  • Adds handlers.ts with a per-thread in-flight serialization guard — concurrent worktree_handoff calls for the same thread fail with WorktreeHandoffInvalidRequestError.
  • Introduces worktree contracts (schemas and error types) in packages/contracts/src/worktree.ts and wires the WorktreeToolkit into the MCP server layer alongside the existing preview toolkit.
  • Newly issued MCP credentials now include the worktree capability; sessions without it receive WorktreeCapabilityUnavailableError on tool invocation.
  • Risk: worktree_handoff mutates git state (creates a worktree, updates thread metadata) and only rolls back the worktree creation on metadata update failure — setup script failures are reported but do not roll back the worktree.

Macroscope summarized a33fb24.

nsxdavid added 6 commits July 6, 2026 18:23
…andoff

Adds a worktree toolkit to the t3-code MCP server so an agent can move
its own thread into a new git worktree mid-conversation. The tool:

- creates the worktree branch from a base ref (defaults to the branch
  currently checked out in the project workspace), optionally starting
  from the remote-tracking commit of that ref (defaults to the server's
  'new worktrees start from origin' setting)
- supports an optional explicit worktree path (defaults to the
  server-managed worktrees directory)
- dispatches thread.meta.update so the provider session restarts inside
  the worktree at the next turn with the conversation preserved via the
  existing resumeCursor machinery
- runs the project's configured setup script in the new worktree by
  default; setup failures are reported in the result instead of
  failing the handoff
- fails cleanly when the thread is already attached to a worktree or
  the base ref cannot be resolved

Introduces a 'worktree' MCP capability alongside 'preview' and new
contracts (WorktreeHandoffInput/Result/Error).
…ror names

Adds a read-only worktree_status tool reporting the calling thread's
worktree binding (attached, worktreePath, branch), the project's main
workspace root, and the server default for startFromOrigin, so agents
can check whether a handoff is possible or already happened before
calling worktree_handoff.

Renames the shared error classes to be tool-neutral now that the
toolkit has more than one tool: WorktreeHandoffUnavailableError ->
WorktreeCapabilityUnavailableError, WorktreeHandoffThreadNotFoundError
-> WorktreeThreadNotFoundError, WorktreeHandoffOperationError ->
WorktreeOperationError. Handoff-specific errors keep their names.
- rename contracts module worktreeHandoff.ts to worktree.ts now that it
  also holds the status schemas
- type the handoff handler input with the WorktreeHandoffInput contract
  instead of an inline structural type
- give requireWorktreeCapability an Effect.fn trace span matching
  requireMcpCapability
- drop a dead undefined check on thread.worktreePath (contract is NullOr)
- use 'satisfies Partial<Service>' for test mocks instead of double
  casts, and tighten the createWorktree stub signature it flagged
… MCP layer

Boots the real McpHttpServer.layer (layerHttp transport, auth middleware,
session registry) over a test HTTP server, mints a credential, and
asserts tools/list includes worktree_handoff and worktree_status
alongside the preview tools.
An explicit empty Schema.Struct({}) serializes to JSON Schema
'anyOf: [object, array]', which is not a valid MCP tool inputSchema
(clients require a top-level object schema). Claude Code rejects the
entire t3-code MCP server when any tool schema is invalid, so the
broken worktree_status schema silently took the preview tools down
with it - the server stayed 'pending' and sessions saw zero tools.

Drop the explicit parameters so Tool.make defaults to Tool.EmptyParams,
which serializes to a top-level object schema, remove the now-unused
WorktreeStatusInput contract, and extend the registration test to
assert every listed tool has a top-level object inputSchema.
- correct the operation label on the settings read in the handoff path
  (resolveSettings, not resolveBaseRef)
- assert typed failure tags unconditionally in handler tests via an
  expectTypedFailure helper so defects can no longer slip past the
  guarded assertions
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 19de0df9-4ac1-4a47-9316-c723861f51fa

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 6, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One convention issue: WorktreeOperationError copies the underlying cause.message into a detail field and builds its message from it, instead of preserving the real failure as cause and deriving the message from structural attributes. The sibling previewAutomation.ts errors already follow the expected pattern (cause: Schema.Defect() plus bounded diagnostics). See inline comment.

Posted via Macroscope — Effect Service Conventions

Comment thread packages/contracts/src/worktree.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7bf0f58f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/server/src/mcp/toolkits/worktree/handlers.ts
Comment thread apps/server/src/mcp/toolkits/worktree/handlers.ts
Comment thread packages/contracts/src/worktree.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a7bf0f5. Configure here.

Comment thread apps/server/src/mcp/toolkits/worktree/handlers.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new worktree handoff and status MCP tools that create git worktrees, rebind agent threads, and run setup scripts. New features with cross-cutting behavior affecting session management and filesystem operations warrant human review.

You can customize Macroscope's approvability policy. Learn more.

- WorktreeOperationError now preserves the underlying failure as
  cause (Schema.Defect) and derives its message from the operation
  alone, matching the previewAutomation error conventions, instead of
  copying the wrapped error's message into a detail field
- worktree_handoff rejects relative paths: git would create them
  relative to the project workspace but the raw string would be stored
  as the thread's worktree binding and later used as the session cwd
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jul 7, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new worktree handlers: WorktreeOperationError requires a cause, but the project-not-found path has no underlying failure and fabricates an Error only to satisfy that field.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/mcp/toolkits/worktree/handlers.ts Outdated
Comment thread apps/server/src/mcp/toolkits/worktree/handlers.ts
nsxdavid added 2 commits July 6, 2026 19:14
…ting

- serialize handoffs per thread with an in-flight guard so concurrent
  calls cannot both pass the attachment check and create two worktrees
- remove the created worktree when the thread.meta.update dispatch
  fails so a failed handoff leaves nothing orphaned on disk
- reject relative paths at the schema level (absolute POSIX, Windows
  drive, or UNC) in addition to the handler check, so the input
  contract matches its description
…tools

WorktreeOperationError requires an underlying cause, and project-not-found
has none; manufacturing an Error just to fill the field violated the error
conventions. Add WorktreeProjectNotFoundError (threadId, projectId),
symmetric with WorktreeThreadNotFoundError, and use it in both handlers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let the agent move its thread into a worktree

1 participant