---
title: "Screentack Docs — MCP tools for Mac screen capture"
canonical: https://screentack.com/docs
---

# Screentack for AI agents

Screentack exposes 14 MCP tools, so a coding agent can capture, zoom, record and read text from your Mac screen itself — instead of waiting for you to paste a screenshot.

## Install

**Download:** https://screentack.com/Screentack.dmg

Native macOS app. macOS 14 Sonoma or later · Apple Silicon. Free 7-day trial, then $29 once. Drag to Applications, and grant Screen Recording and Accessibility permission when prompted — both are required to capture windows and read window positions.

## No account. Nothing uploaded.

- **No sign-up, no sign-in.** There is no Screentack account. You buy once and get a license key — no email/password, no profile, nothing to cancel.
- **Your screen never leaves your Mac.** Screenshots, recordings, region crops and OCR are all captured and processed on-device. Nothing is uploaded to us or to any cloud service — the only thing that moves is what *you* paste or send into your own agent or chat app.
- **One exception, stated plainly.** Activating a license contacts LemonSqueezy, the payment provider, to validate the key. That request carries the license key and a device identifier — never your captures.

## Register with your agent

The MCP server ships inside the app. Start with the stdio transport — the agent launches the server itself and nothing else needs to be running:

```
claude mcp add --scope user screentack -- /path/to/screentack --mcp
```

For an always-on setup where the app and agent share live state, use the HTTP transport. It requires the app running and a bearer token from Settings → AI Agent:

```
claude mcp add --transport http screentack http://127.0.0.1:PORT/mcp --header "Authorization: Bearer <token>"
```

## MCP tools (14)

Generated from the app's own tool catalog, so this list matches exactly what the server advertises.

### `list_windows`

List all visible application windows with their app name, title, position, and dimensions.

_No parameters._

### `capture_window`

Capture a screenshot of a specific application window. Returns the image as base64 PNG. Use list_windows first to find the app name.

- `app_name` (string) **required** — Name of the application (case-insensitive substring match, e.g. 'chrome', 'terminal')

### `capture_region`

Capture a screenshot of a specific screen region in pixel coordinates. Pass ocr:true to also return text recognized in the region.

- `height` (integer) **required** — Height in pixels
- `width` (integer) **required** — Width in pixels
- `x` (integer) **required** — Left edge X coordinate in pixels
- `y` (integer) **required** — Top edge Y coordinate in pixels
- `ocr` (boolean) — If true, also OCR the region and include recognized text in the result (default false)

### `activate_window`

Bring an application's windows to the front. Call this before capture_window if other windows might be blocking the target. Returns the number of windows raised.

- `app_name` (string) **required** — Name of the application to bring to front (case-insensitive substring match)

### `capture_window_region`

Capture a specific region within a window at readable resolution. Coordinates are relative to the window (not the screen). The cropped area is returned at up to 1024px — great for reading text, UI details, or small elements. Use this instead of capture_region when you know which window you want and need to zoom into a part of it. Pass ocr:true to also return recognized text.

- `app_name` (string) **required** — Name of the application
- `height` (integer) **required** — Height in pixels
- `width` (integer) **required** — Width in pixels
- `x` (integer) **required** — Left edge X in pixels, relative to window top-left
- `y` (integer) **required** — Top edge Y in pixels, relative to window top-left
- `ocr` (boolean) — If true, also OCR the region and include recognized text in the result (default false)

### `capture_annotated`

Capture a full window screenshot with highlighted regions. The regions are rendered as colored overlay markers on the screenshot, so the LLM sees both the full context and the specific areas of interest. This is the primary tool for visual debugging — it solves the 'zoomed-in loses context, zoomed-out dilutes signal' problem.

- `app_name` (string) **required** — Name of the application
- `regions` (array) **required** — Regions to highlight on the screenshot

### `capture_diff`

Capture before/after screenshots of a window. First call stores 'before' state. Second call with same app returns both 'before' and 'after' images with timestamps. Use this to show what changed after an action.

- `app_name` (string) **required** — Name of the application

### `start_recording`

Start recording visual changes of an application window. Captures at ~1fps and detects which screen regions changed using grid-based diff. Saves start frame, end frame, and crops of changed regions. Returns the session ID.

- `app_name` (string) **required** — Name of the application to record
- `interval_ms` (integer) — Capture interval in milliseconds (default: 1000)

### `stop_recording`

Stop the current recording session. Saves end frame and writes SESSION.md with the full timeline of visual changes. Returns the session ID and path.

_No parameters._

### `poll_recording`

Poll for new visual change events during an active recording. Returns text-only event list with frame filenames (no images). Use this to check what changed, then use read_frame on specific frames if needed.

_No parameters._

### `read_frame`

Return a raw recording frame as an image. Use to visually inspect recording frames. Note: puts the image into your context window.

- `frame` (string) **required** — Frame filename (e.g. 'change-001.png', 'frame-000-start.png')
- `session_id` (string) — Session ID (default: latest)

### `get_annotations`

Read what the HUMAN marked — the latest session data, either annotations from the interactive overlay (Cmd+Ctrl+P) or human-initiated recordings (Cmd+Ctrl+R). Returns SESSION.md content with timeline, key area readings, and region images. Use when the user says they've annotated, recorded, or captured something. This is the human→agent half of the feedback loop; its inverse is annotate_understanding (you draw for the human). Human recordings include Source: human in the metadata. Pass ocr:true to also OCR each region and include recognized text.

- `ocr` (boolean) — If true, OCR each region image and include recognized text (default false)

### `annotate_understanding`

Draw YOUR understanding/intent onto the user's LIVE screen as labeled shapes (boxes/arrows/ellipses/highlights/text) and reference images, so the human can confirm or correct it before you act. Each stroke declares the frame it was authored against — a window (from list_windows/capture_window), a display, or a screen region (from capture_region) — plus pixel coords within the image you reasoned over. Strokes appear on a present/draw overlay as EDITABLE shapes the human can move, relabel, or delete. Use it to show 'this is the primary CTA I'll restyle', 'I read this value as $69.23', or 'make it look like this <image>'. This is the agent→human half of the feedback loop; its inverse is get_annotations (read what the human marked). Returns a JSON result block with sessionId/name/path. Free — no license required.

- `strokes` (array) **required** — The shapes to draw onto the live screen.
- `title` (string) — Short name for this annotation set (shown to the human in History as the session Name).

### `get_annotation_feedback`

Read the human's review of a drawing you presented with annotate_understanding. Poll this with the sessionId from that call. Returns status ('pending' until the human submits, then 'submitted'), the human's `comments` (their feedback marks — the actual signal: what they typed and where it points, with displayIndex + normalized x/y), and your own `agentStrokes` with their state (removed:true means the human cleared that mark — treat as context, NOT as a rejection verdict). Interpret meaning from the comments and the conversation, not from which marks were removed. A composited image is also returned, but it covers only the PRIMARY display — comments on a secondary monitor appear in `comments` (with their displayIndex) but not in the image; capture_region that display if you need to see it. Free — no license required.

- `sessionId` (string) **required** — The sessionId returned by annotate_understanding.

## The SESSION.md manifest

Every capture writes a session folder under `~/.screentack/sessions/<id>/` containing the annotated full screenshot, one PNG per marked region, and a `SESSION.md` manifest naming each region and where it sits.

Coordinates are in points with a top-left origin, relative to each region's own display. Region crops are saved at native pixels (points x the display's backing scale), and each region carries a global desktop position for automation, since macOS click coordinates are in points.
