upload_file_by_uid
Upload files to web forms by targeting specific file input elements using their unique identifiers. Provide the element UID and local file path to automate file submission in browser testing and automation workflows.
Instructions
Upload a file into an element identified by its UID. The file path must be accessible to the server.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Local filesystem path to the file to upload | |
| uid | Yes | The UID of the file input element |
Implementation Reference
- src/tools/input.ts:129-146 (schema)Tool schema definition including inputSchema for uid and filePath parameters.export const uploadFileByUidTool = { name: 'upload_file_by_uid', description: 'Upload file to file input by UID.', inputSchema: { type: 'object', properties: { uid: { type: 'string', description: 'File input UID from snapshot', }, filePath: { type: 'string', description: 'Local file path', }, }, required: ['uid', 'filePath'], }, };
- src/tools/input.ts:286-326 (handler)Main MCP handler for upload_file_by_uid tool. Validates input, gets Firefox instance, calls uploadFileByUid, handles specific errors.export async function handleUploadFileByUid(args: unknown): Promise<McpToolResponse> { try { const { uid, filePath } = args as { uid: string; filePath: string }; if (!uid || typeof uid !== 'string') { throw new Error('uid parameter is required and must be a string'); } if (!filePath || typeof filePath !== 'string') { throw new Error('filePath parameter is required and must be a string'); } const { getFirefox } = await import('../index.js'); const firefox = await getFirefox(); try { await firefox.uploadFileByUid(uid, filePath); return successResponse(`✅ upload ${uid}`); } catch (error) { const errorMsg = (error as Error).message; // Check for UID staleness if (errorMsg.includes('stale') || errorMsg.includes('Snapshot') || errorMsg.includes('UID')) { throw handleUidError(error as Error, uid); } // Check for file input specific errors if (errorMsg.includes('not a file input') || errorMsg.includes('type="file"')) { throw new Error(`${uid} is not a file input`); } if (errorMsg.includes('hidden') || errorMsg.includes('not visible')) { throw new Error(`${uid} is hidden/not interactable`); } throw error; } } catch (error) { return errorResponse(error as Error); } }
- src/index.ts:131-147 (registration)Registration of upload_file_by_uid handler in the toolHandlers Map (line 136).['click_by_uid', tools.handleClickByUid], ['hover_by_uid', tools.handleHoverByUid], ['fill_by_uid', tools.handleFillByUid], ['drag_by_uid_to_uid', tools.handleDragByUidToUid], ['fill_form_by_uid', tools.handleFillFormByUid], ['upload_file_by_uid', tools.handleUploadFileByUid], // Screenshot ['screenshot_page', tools.handleScreenshotPage], ['screenshot_by_uid', tools.handleScreenshotByUid], // Utilities ['accept_dialog', tools.handleAcceptDialog], ['dismiss_dialog', tools.handleDismissDialog], ['navigate_history', tools.handleNavigateHistory], ['set_viewport_size', tools.handleSetViewportSize], ]);
- src/index.ts:175-181 (registration)Registration of uploadFileByUidTool schema in the allTools array (line 180) for listTools.tools.clickByUidTool, tools.hoverByUidTool, tools.fillByUidTool, tools.dragByUidToUidTool, tools.fillFormByUidTool, tools.uploadFileByUidTool,
- src/firefox/dom.ts:250-284 (helper)Core implementation in DomInteractions: resolves UID to WebElement, unhides file input if necessary, sends filePath via sendKeys.async uploadFileByUid(uid: string, filePath: string): Promise<void> { if (!this.resolveUid) { throw new Error( 'uploadFileByUid: resolveUid callback not set. Ensure snapshot is initialized.' ); } const el = await this.resolveUid(uid); // Ensure it's an <input type=file>; if hidden, unhide via JS await this.driver.executeScript((element: Element) => { if (!element) { throw new Error('uploadFile: element not found'); } if (element.tagName !== 'INPUT' || (element as HTMLInputElement).type !== 'file') { throw new Error('uploadFile: element must be <input type=file>'); } const style = window.getComputedStyle(element); if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') { const s = (element as HTMLElement).style; s.display = 'block'; s.visibility = 'visible'; s.opacity = '1'; s.position = 'fixed'; s.left = '0px'; s.top = '0px'; s.zIndex = '2147483647'; } }, el); await el.sendKeys(filePath); // Wait for events to propagate await this.waitForEventsAfterAction(); }