Scroll
pinchtab_scrollScroll web pages or specific elements in any direction. Specify pixel amount and direction for precise control.
Instructions
Scroll the page or a specific element. Supports all four directions.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| amount | No | Scroll amount in pixels. Default: 500 | |
| direction | Yes | Scroll direction | |
| ref | No | Element ref to scroll within (e.g. 'e5'). If omitted, scrolls the page. |
Implementation Reference
- src/tools/navigation.ts:108-120 (handler)Handler function for pinchtab_scroll. Constructs a scroll action body with optional amount (default 500px), direction, and optional element ref, then sends a POST /action request via the pinch client.
async ({ direction, amount, ref }) => { try { const body: Record<string, unknown> = { amount: amount ?? DEFAULT_SCROLL_PX, direction, kind: "scroll", }; if (ref) body.ref = ref; return toolResult(await pinch("POST", "/action", body)); } catch (error) { return toolError(error); } }, - src/tools/navigation.ts:93-105 (schema)Input schema for pinchtab_scroll: amount (optional number, default 500), direction (enum up/down/left/right), ref (optional string for element-scoped scrolling).
{ description: "Scroll the page or a specific element. Supports all four directions.", inputSchema: z.object({ amount: z .number() .optional() .describe(`Scroll amount in pixels. Default: ${DEFAULT_SCROLL_PX}`), direction: z.enum(["up", "down", "left", "right"]).describe("Scroll direction"), ref: z .string() .optional() .describe("Element ref to scroll within (e.g. 'e5'). If omitted, scrolls the page."), }), - src/tools/navigation.ts:91-121 (registration)Registration of the 'pinchtab_scroll' tool via server.registerTool with description, inputSchema, title, and handler.
server.registerTool( "pinchtab_scroll", { description: "Scroll the page or a specific element. Supports all four directions.", inputSchema: z.object({ amount: z .number() .optional() .describe(`Scroll amount in pixels. Default: ${DEFAULT_SCROLL_PX}`), direction: z.enum(["up", "down", "left", "right"]).describe("Scroll direction"), ref: z .string() .optional() .describe("Element ref to scroll within (e.g. 'e5'). If omitted, scrolls the page."), }), title: "Scroll", }, async ({ direction, amount, ref }) => { try { const body: Record<string, unknown> = { amount: amount ?? DEFAULT_SCROLL_PX, direction, kind: "scroll", }; if (ref) body.ref = ref; return toolResult(await pinch("POST", "/action", body)); } catch (error) { return toolError(error); } }, ); - src/pinchtab/client.ts:6-49 (helper)The pinch() helper function that makes HTTP requests to the PinchTab API, used by the scroll handler to POST /action.
export async function pinch( method: string, path: string, body?: Record<string, unknown>, ): Promise<unknown> { if (!(await isPinchtabRunning())) { await ensurePinchtabRunning(); } const headers: Record<string, string> = { "Content-Type": "application/json", }; if (PINCHTAB_TOKEN) { headers["Authorization"] = `Bearer ${PINCHTAB_TOKEN}`; } const url = `${PINCHTAB_URL}${path}`; let res: Response; try { res = await fetch(url, { body: body ? JSON.stringify(body) : undefined, headers, method, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), }); } catch (error) { if (error instanceof DOMException && error.name === "TimeoutError") { throw new Error(`PinchTab ${method} ${path} timed out after ${REQUEST_TIMEOUT_MS / 1000}s`); } throw error; } if (!res.ok) { const text = await res.text(); throw new Error(`PinchTab ${method} ${path} → ${res.status}: ${text}`); } const contentType = (res.headers.get("content-type") ?? "").split(";")[0].toLowerCase().trim(); if (contentType === "application/json") { return res.json(); } return res.text(); }