Skip to content

feat: add chrome_move_tab tool for state-preserving tab moves#335

Open
pooyak wants to merge 1 commit into
hangwin:masterfrom
pooyak:feat/move-tab-tool
Open

feat: add chrome_move_tab tool for state-preserving tab moves#335
pooyak wants to merge 1 commit into
hangwin:masterfrom
pooyak:feat/move-tab-tool

Conversation

@pooyak
Copy link
Copy Markdown

@pooyak pooyak commented Apr 28, 2026

Summary

Adds a new MCP tool chrome_move_tab that moves an existing tab between windows (or detaches it into a brand-new window) without reloading the page. Tab state — scroll position, navigation history, form input, and any in-page renderer state — is preserved, because the underlying chrome.tabs.move / chrome.windows.create({ tabId }) APIs reattach the existing renderer rather than recreating it.

Motivation

There's currently no MCP tool exposed for moving tabs. Achieving the equivalent today requires reading the URL, opening a new tab in the destination window, then closing the original — which causes a full page reload, a network round-trip, and loss of all in-page state. For users orchestrating tab layouts across many windows (the original motivating use case), this is both lossy and slow.

The Chrome extension API already provides chrome.tabs.move for this exact purpose; this PR just exposes it.

API

{
  tabId: number;          // required
  windowId?: number;      // destination window — required unless newWindow=true
  newWindow?: boolean;    // detach into a new window — mutually exclusive with windowId
  index?: number;         // position in destination window; -1 (default) = append
  focused?: boolean;      // focus destination window after move; default true
}

Validation:

  • tabId is required.
  • Exactly one of windowId / newWindow=true must be provided.
  • index is ignored when newWindow=true.

Changes

  • packages/shared/src/tools.ts — register TOOL_NAMES.BROWSER.MOVE_TAB and add a TOOL_SCHEMAS entry.
  • app/chrome-extension/entrypoints/background/tools/browser/move-tab.ts — new MoveTabTool extending BaseBrowserToolExecutor.
  • app/chrome-extension/entrypoints/background/tools/browser/index.ts — re-export so the dispatcher picks it up.

The tool follows the same shape as SwitchTabTool and reuses existing error-handling conventions.

Test plan

  • pnpm build:shared — passes
  • pnpm build:extension (wxt build) — passes; chrome_move_tab appears in the bundled background.js
  • npx eslint <changed files> — clean (the 4 unrelated lint errors on master are not in changed paths)
  • npx prettier --check <changed files> — clean
  • Manual verification: load the unpacked extension, call chrome_move_tab with { tabId, newWindow: true } and { tabId, windowId } from an MCP client, confirm tab moves without reload (scroll/form state preserved).

Notes

  • No changes to the native bridge or installation flow.
  • Backwards-compatible: purely additive.

🤖 Generated with Claude Code

Adds a new MCP tool that moves an existing tab between windows
(or detaches it into a new window) using chrome.tabs.move and
chrome.windows.create({ tabId }). Unlike workarounds that read
the URL and reopen it elsewhere, this preserves the tab renderer:
scroll position, navigation history, form input, and any in-page
state remain intact.

API: { tabId, windowId? | newWindow?, index?, focused? }
- windowId and newWindow are mutually exclusive (one is required)
- index defaults to -1 (append) when moving into an existing window
- focused defaults to true

- packages/shared: register MOVE_TAB tool name and schema
- app/chrome-extension: implement MoveTabTool, wire export
@pooyak pooyak force-pushed the feat/move-tab-tool branch from a6c0fdf to 6daf44f Compare April 28, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant