ui_view
Retrieve compressed screenshot images of the current view from iOS simulators using the UDID to target specific devices.
Instructions
Get the image content of a compressed screenshot of the current simulator view
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| udid | No | Udid of target, can also be set with the IDB_UDID env var |
Implementation Reference
- src/index.ts:522-611 (handler)The handler function for the 'ui_view' tool. It captures a screenshot of the booted simulator using simctl, resizes it to logical point dimensions obtained from IDB ui describe-all, compresses it to JPEG using sips, encodes to base64, and returns as an image content block.async ({ udid }) => { try { const actualUdid = await getBootedDeviceId(udid); // Get screen dimensions in points from ui_describe_all const { stdout: uiDescribeOutput } = await idb( "ui", "describe-all", "--udid", actualUdid, "--json", "--nested" ); const uiData = JSON.parse(uiDescribeOutput); const screenFrame = uiData[0]?.frame; if (!screenFrame) { throw new Error("Could not determine screen dimensions"); } const pointWidth = screenFrame.width; const pointHeight = screenFrame.height; // Generate unique file names with timestamp const ts = Date.now(); const rawPng = path.join(TMP_ROOT_DIR, `ui-view-${ts}-raw.png`); const compressedJpg = path.join( TMP_ROOT_DIR, `ui-view-${ts}-compressed.jpg` ); // Capture screenshot as PNG await run("xcrun", [ "simctl", "io", actualUdid, "screenshot", "--type=png", "--", rawPng, ]); // Resize to match point dimensions and compress to JPEG using sips await run("sips", [ "-z", String(pointHeight), // height in points String(pointWidth), // width in points "-s", "format", "jpeg", "-s", "formatOptions", "80", // 80% quality rawPng, "--out", compressedJpg, ]); // Read and encode the compressed image const imageData = fs.readFileSync(compressedJpg); const base64Data = imageData.toString("base64"); return { isError: false, content: [ { type: "image", data: base64Data, mimeType: "image/jpeg", }, { type: "text", text: "Screenshot captured", }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: errorWithTroubleshooting( `Error capturing screenshot: ${toError(error).message}` ), }, ], }; } }
- src/index.ts:516-521 (schema)Input schema for the 'ui_view' tool using Zod: optional UDID string validated against UDID_REGEX.udid: z .string() .regex(UDID_REGEX) .optional() .describe("Udid of target, can also be set with the IDB_UDID env var"), },
- src/index.ts:511-613 (registration)Registration of the 'ui_view' tool on the MCP server, conditional on not being filtered, including name, description, input schema, and inline handler.if (!isToolFiltered("ui_view")) { server.tool( "ui_view", "Get the image content of a compressed screenshot of the current simulator view", { udid: z .string() .regex(UDID_REGEX) .optional() .describe("Udid of target, can also be set with the IDB_UDID env var"), }, async ({ udid }) => { try { const actualUdid = await getBootedDeviceId(udid); // Get screen dimensions in points from ui_describe_all const { stdout: uiDescribeOutput } = await idb( "ui", "describe-all", "--udid", actualUdid, "--json", "--nested" ); const uiData = JSON.parse(uiDescribeOutput); const screenFrame = uiData[0]?.frame; if (!screenFrame) { throw new Error("Could not determine screen dimensions"); } const pointWidth = screenFrame.width; const pointHeight = screenFrame.height; // Generate unique file names with timestamp const ts = Date.now(); const rawPng = path.join(TMP_ROOT_DIR, `ui-view-${ts}-raw.png`); const compressedJpg = path.join( TMP_ROOT_DIR, `ui-view-${ts}-compressed.jpg` ); // Capture screenshot as PNG await run("xcrun", [ "simctl", "io", actualUdid, "screenshot", "--type=png", "--", rawPng, ]); // Resize to match point dimensions and compress to JPEG using sips await run("sips", [ "-z", String(pointHeight), // height in points String(pointWidth), // width in points "-s", "format", "jpeg", "-s", "formatOptions", "80", // 80% quality rawPng, "--out", compressedJpg, ]); // Read and encode the compressed image const imageData = fs.readFileSync(compressedJpg); const base64Data = imageData.toString("base64"); return { isError: false, content: [ { type: "image", data: base64Data, mimeType: "image/jpeg", }, { type: "text", text: "Screenshot captured", }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: errorWithTroubleshooting( `Error capturing screenshot: ${toError(error).message}` ), }, ], }; } } ); }