pilot_drag
Drag an element from a source and drop it onto a target to reorder items or interact with drag-and-drop UI elements.
Instructions
Drag one element and drop it onto another element on the page. Use when the user wants to move an element, reorder items in a drag-and-drop list, or interact with a drag-and-drop UI.
Parameters:
start_ref: The source element reference from snapshot (e.g., "@e3") or CSS selector to drag from
end_ref: The target element reference from snapshot (e.g., "@e5") or CSS selector to drop onto
Returns: Confirmation with source and target refs.
Errors:
"Element not found": Either ref is stale. Run pilot_snapshot to get fresh refs.
Timeout (5s): The drag operation could not be completed. The elements may not support drag-and-drop.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| start_ref | Yes | Source element ref or CSS selector | |
| end_ref | Yes | Target element ref or CSS selector |
Implementation Reference
- src/tools/interaction.ts:295-331 (handler)The pilot_drag tool handler — uses startRef and endRef to drag an element onto a target via Playwright's locator.dragTo() with a 5-second timeout. Returns confirmation or error.
server.tool( 'pilot_drag', `Drag one element and drop it onto another element on the page. Use when the user wants to move an element, reorder items in a drag-and-drop list, or interact with a drag-and-drop UI. Parameters: - start_ref: The source element reference from snapshot (e.g., "@e3") or CSS selector to drag from - end_ref: The target element reference from snapshot (e.g., "@e5") or CSS selector to drop onto Returns: Confirmation with source and target refs. Errors: - "Element not found": Either ref is stale. Run pilot_snapshot to get fresh refs. - Timeout (5s): The drag operation could not be completed. The elements may not support drag-and-drop.`, { start_ref: z.string().describe('Source element ref or CSS selector'), end_ref: z.string().describe('Target element ref or CSS selector'), }, async ({ start_ref, end_ref }) => { await bm.ensureBrowser(); try { const page = bm.getPage(); const startResolved = await bm.resolveRef(start_ref); const endResolved = await bm.resolveRef(end_ref); const startLocator = 'locator' in startResolved ? startResolved.locator : page.locator(startResolved.selector); const endLocator = 'locator' in endResolved ? endResolved.locator : page.locator(endResolved.selector); await startLocator.dragTo(endLocator, { timeout: 5000 }); bm.resetFailures(); return { content: [{ type: 'text' as const, text: `Dragged ${start_ref} → ${end_ref}` }] }; } catch (err) { bm.incrementFailures(); return { content: [{ type: 'text' as const, text: wrapError(err) }], isError: true }; } } ); - src/tools/register.ts:73-86 (registration)registerAllTools calls registerInteractionTools which registers 'pilot_drag'. The tool is also listed in STANDARD_TOOLS (line 41) so it's available in the 'standard' profile.
export function registerAllTools(server: McpServer, bm: BrowserManager, profile: ToolProfile = 'full'): void { const allowed = PROFILE_TOOLS[profile]; const effectiveServer = allowed ? createFilteredServer(server, allowed) : server; registerNavigationTools(effectiveServer, bm); registerSnapshotTools(effectiveServer, bm); registerInteractionTools(effectiveServer, bm); registerPageTools(effectiveServer, bm); registerInspectionTools(effectiveServer, bm); registerVisualTools(effectiveServer, bm); registerTabTools(effectiveServer, bm); registerSettingsTools(effectiveServer, bm); registerIframeTools(effectiveServer, bm); registerAutomationTools(effectiveServer, bm); - src/tools/register.ts:36-52 (registration)STANDARD_TOOLS set includes 'pilot_drag' at line 41, meaning it's available in 'standard' and 'full' profiles.
const STANDARD_TOOLS = new Set([ ...CORE_TOOLS, // navigation 'pilot_back', 'pilot_forward', 'pilot_reload', 'pilot_get', // interaction 'pilot_hover', 'pilot_select_option', 'pilot_scroll', 'pilot_drag', // tabs 'pilot_tabs', 'pilot_tab_new', 'pilot_tab_close', 'pilot_tab_select', // page reading 'pilot_page_text', 'pilot_page_html', // visual 'pilot_annotated_screenshot', // iframe 'pilot_frames', 'pilot_frame_select', 'pilot_frame_reset', // session + config 'pilot_auth', 'pilot_block', 'pilot_find', ]);