---
title: MCP tool reference
description: Every tool, resource and prompt the Snaps MCP server exposes, with inputs, outputs and examples.
---

Server URL: `https://mcp.snaps.design/mcp`. Auth: `Authorization: Bearer ass_…`. Limit: 60 requests per minute per key. Install steps are in [MCP: installation](/mcp/installation).

Device, platform and category strings are the ones in [Devices and stores](/devices-and-stores#device-taxonomy).

| Tool                                    | Use it to                               | Scope |
| --------------------------------------- | --------------------------------------- | ----- |
| [`search_apps`](#search_apps)           | Find apps by name, platform or category | read  |
| [`get_app`](#get_app)                   | Get one app's details and screen counts | read  |
| [`list_screens`](#list_screens)         | List an app's screens                   | read  |
| [`search_screens`](#search_screens)     | Find screens across apps                | read  |
| [`get_screen_image`](#get_screen_image) | Fetch a screenshot as an image          | read  |
| [`list_categories`](#list_categories)   | List categories with counts             | read  |
| [`request_app`](#request_app)           | Ask for a missing app                   | write |
| [`list_og_sites`](#list_og_sites)       | Find sites with OG history              | read  |
| [`get_og_timeline`](#get_og_timeline)   | Get every OG image a site has used      | read  |
| [`get_og_image`](#get_og_image)         | Get one OG image version by id          | read  |
| [`open_link`](#open_link)               | Resolve a pasted Snaps link             | read  |
| [`add_og_site`](#add_og_site)           | Start OG history for a website          | write |

## search_apps

Search apps by name, with optional platform and category filters.

| Input      | Type             | Notes                                              |
| ---------- | ---------------- | -------------------------------------------------- |
| `query`    | string           | App name or part of it                             |
| `platform` | string, optional | `ios`, `android` or `desktop` (the interface tabs) |
| `category` | string, optional | A name from `list_categories`                      |
| `limit`    | number, optional | Up to 25 (default 10)                              |

Returns `{ apps: [...] }`. Each app has `slug`, `name`, `developer`, `category`, `platforms` (`ios`, `android`, `desktop`), `formFactors`, `screenCount`, `iconUrl` and `url` (its page on the site).

```json
{ "name": "search_apps", "arguments": { "query": "notion", "platform": "ios", "limit": 5 } }
```

## get_app

Get one app by slug: metadata, store links, captures (versions) and a count of screens per device. An unknown slug returns a tool error.

| Input  | Type   | Notes                |
| ------ | ------ | -------------------- |
| `slug` | string | For example `notion` |

```json
{ "name": "get_app", "arguments": { "slug": "notion" } }
```

Returns `slug`, `name`, `developer`, `category`, `description`, `platforms`, `formFactors`, `screenCount`, `latestCapturedAt` (ISO 8601), `iconUrl`, `url`, `stores` (per store: `url` and ids), `devices` (`[{ device, count }]`) and `captures` (`[{ captureId, store, version, capturedAt, screenCount }]`, newest first).

## list_screens

List the screens of one app, with full and thumbnail URLs and pixel dimensions.

| Input       | Type             | Notes                                                                   |
| ----------- | ---------------- | ----------------------------------------------------------------------- |
| `slug`      | string           | The app                                                                 |
| `device`    | string, optional | `iphone`, `ipad`, `android_phone`, `android_tablet`, `mac` or `windows` |
| `captureId` | string, optional | An earlier capture from `get_app`                                       |
| `limit`     | number, optional | 1 to 200 (default 50)                                                   |

```json
{ "name": "list_screens", "arguments": { "slug": "notion", "device": "iphone", "limit": 10 } }
```

Returns `{ app: { slug, name }, total, screens: [...] }`, in store order. Each screen has `screenId`, `device`, `order`, `width`, `height`, `captureId`, `thumbUrl`, `fullUrl` and `url`. `total` counts every matching screen before `limit`.

## search_screens

Search screens across all apps. Until AI tags exist, this matches on app name and category only. It cannot find "paywall" or "bottom sheet" by what is in the image yet.

| Input     | Type             | Notes                                 |
| --------- | ---------------- | ------------------------------------- |
| `query`   | string           | Matched against app name and category |
| `pattern` | string, optional | Reserved for pattern tags; ignored    |
| `device`  | string, optional | One of the device strings             |
| `limit`   | number, optional | 1 to 50 (default 20)                  |

```json
{ "name": "search_screens", "arguments": { "query": "finance", "device": "iphone" } }
```

Returns `{ screens: [...] }` (plus a `note` when `pattern` was ignored). Each screen has `screenId`, `device`, `width`, `height`, `thumbUrl`, `fullUrl`, `app` (`{ slug, name, category }`), `matchedOn` (`name` or `category`) and `url`. Name matches come first, and results are spread across the matching apps.

## get_screen_image

Return one screenshot as MCP `image` content (base64 with the right MIME type), so a vision model can look at it. Thumbnails are the default. Ask for `full` when you need detail. Images over 5 MB are refused.

| Input      | Type                            | Notes                                   |
| ---------- | ------------------------------- | --------------------------------------- |
| `screenId` | string                          | From `list_screens` or `search_screens` |
| `size`     | `"thumb"` or `"full"`, optional | Defaults to `thumb`                     |

```json
{ "name": "get_screen_image", "arguments": { "screenId": "…", "size": "thumb" } }
```

Returns two content items: the `image` (`data` in base64, `mimeType` such as `image/jpeg`), then a `text` item with `{ screenId, app, device, size, width, height, url }`.

## list_categories

List categories with the number of apps in each, most apps first. Takes no input. Returns `{ categories: [{ category, count }] }`.

```json
{ "name": "list_categories", "arguments": {} }
```

## request_app

Ask for an app that is not in the library. Needs a key with the `write` scope and is rate-limited (the same per-account limit as requesting an app on the site). Returns `{ jobId, status: "queued" }`. Store URLs must be on the App Store, Google Play or Microsoft Store, and apps that were taken down cannot be requested. The app shows up once the ingest job finishes, which can take a few minutes or longer if a store is slow.

| Input   | Type   | Notes                                  |
| ------- | ------ | -------------------------------------- |
| `input` | string | A store URL, a store ID or an app name |

```json
{
  "name": "request_app",
  "arguments": { "input": "https://apps.apple.com/us/app/notion/id1232780281" }
}
```

## list_og_sites

List websites with [OG history](/og-history): every Open Graph image a site has used, from the Wayback Machine.

| Input      | Type             | Notes                                                                      |
| ---------- | ---------------- | -------------------------------------------------------------------------- |
| `query`    | string, optional | Part of a site name or host, such as `linear`                              |
| `category` | string, optional | A name from `list_categories` (a site takes its app's category)            |
| `sort`     | string, optional | `latest` (most recent change, default), `versions` (most versions) or `az` |
| `limit`    | number, optional | 1 to 50 (default 20)                                                       |

```json
{ "name": "list_og_sites", "arguments": { "query": "linear", "sort": "versions" } }
```

Returns `{ sites: [...] }`. Each site has `host`, `name`, `origin`, `category`, `status`, `versionCount`, `latestChangedAt` (ISO 8601), `latestImage` (`{ imageUrl, width, height }` or null), `app` (`{ slug, url }` or null), `slug` (the site's page is `/apps/<slug>?view=og`: its app's slug, or its own for a website with no app), `iconUrl` (the site's own icon, or null) and `url` (that page). `status` is `queued`, `live` (current image only so far), `backfilling`, `done` or `failed`. A `query` is matched against the first 2000 sites in `sort` order.

## get_og_timeline

Get every OG image one website has used, newest first. Pass exactly one of `host` or `app`. An unknown host, an unknown app, or an app with no tracked website returns a tool error.

| Input  | Type             | Notes                                                                                           |
| ------ | ---------------- | ----------------------------------------------------------------------------------------------- |
| `host` | string, optional | A host or URL, such as `linear.app`                                                             |
| `app`  | string, optional | An app slug from `search_apps` (uses the app's website), or the `slug` of a website with no app |

```json
{ "name": "get_og_timeline", "arguments": { "host": "linear.app" } }
```

Returns `{ site, versions, note? }`.

- `site` has the `list_og_sites` fields plus `coverage` (`{ firstCapture, lastCapture, monthsArchived, pagesRead }`: what the archive held), `notes` and `lastLiveCheckAt`.
- `note` is there while past versions are still being read (`status` `queued`, `live` or `backfilling`), or when the archive pass failed. Call again in a few minutes for the full timeline.
- Each version has `index` (1 is the oldest), `from` and `until` (ISO 8601, month-level; `until` is null and `current` true for the image in use now), `changedBetween` (`{ from, to }`: the range the change happened in, or null), `approximate`, `seenOnce`, `pagesSeen`, `source`, `imageUrl`, `width`, `height`, `mime`, `originalUrl`, `archivedUrl`, `title` and `description`.

How to read the flags (more in [OG history](/og-history#how-dates-work)):

- `approximate: true`: the archive has a gap of more than 90 days around the change. Say "about" with the date.
- `seenOnce: true`: the image was on one archived page only.
- `source`: `wayback` (from the archive), `live` (from the live homepage) or `missing` (the archive never saved the file, so `imageUrl` is null).

## get_og_image

Get one Open Graph image version by id: the id at the end of an `/og/<id>` link, or a version from `get_og_timeline`. An unknown id returns a tool error.

| Input | Type   | Notes                                       |
| ----- | ------ | ------------------------------------------- |
| `id`  | string | From a Snaps link or from `get_og_timeline` |

```json
{ "name": "get_og_image", "arguments": { "id": "…" } }
```

Returns the `get_og_timeline` version fields (`index`, `from`, `until`, `current`, `changedBetween`, `approximate`, `seenOnce`, `pagesSeen`, `source`, `imageUrl`, `width`, `height`, `mime`, `originalUrl`, `archivedUrl`, `title`, `description`) plus `id`, `site` (`{ host, name, origin, slug, url }`), `app` (`{ slug, url }` or null) and `url` (the image's page on the site).

## open_link

Resolve a Snaps page URL and return what the matching tool returns. Use it when someone pastes a link from the site.

| Input | Type   | Notes                                               |
| ----- | ------ | --------------------------------------------------- |
| `url` | string | A `https://snaps.design` URL; the `https://` can be left off |

```json
{ "name": "open_link", "arguments": { "url": "https://snaps.design/apps/notion/screens/…" } }
```

| Link                                      | Returns the same as                                       |
| ----------------------------------------- | --------------------------------------------------------- |
| `/apps/<slug>/screens/<id>`               | `get_screen_image` with `size` `thumb`                    |
| `/apps/<slug>/og/<id>`, `/og/<host>/<id>` | `get_og_image`                                            |
| `/og/<host>` (old site links)             | `get_og_timeline` with `host`                             |
| `/apps/<slug>?view=og`                    | `get_og_timeline` with `app`                              |
| `/apps/<slug>`                            | `get_app`, or `get_og_timeline` for a website with no app |

Links to other websites, other pages on the site and malformed URLs return a tool error that names the link shapes it reads. A link to a screen, app or image that no longer exists returns the matching tool's error.

## Paste a Snaps link into your prompt

In the screenshot viewer, **Copy link** (or the **L** key) copies a short block you can paste into a chat with an AI agent:

```text
Notion · iPhone screen 2 of 8 · Snaps
https://snaps.design/apps/notion/screens/…
Image: https://…/screens/notion/….jpg
MCP: get_screen_image {"screenId":"…"}
```

An Open Graph image copies the same shape:

```text
Linear · Open Graph image · Mar 2025 – now · Snaps
https://snaps.design/apps/linear/og/…
Image: https://…/og/linear.app/….png
MCP: get_og_image {"id":"…"}
```

The first line says what it is. The second is the page, which `open_link` resolves. `Image:` is the public file, for agents that read images from a URL. `MCP:` is the exact tool call, for agents connected to this server.

## add_og_site

Start OG history for a website that is not tracked yet. Needs a key with the `write` scope. Each account can add about 10 new sites per hour, the same limit as adding one on the site. A site that is already tracked returns at once and does not count. Only public websites are accepted: no IP addresses, local names or custom ports.

| Input | Type   | Notes                               |
| ----- | ------ | ----------------------------------- |
| `url` | string | A host or URL, such as `granola.ai` |

```json
{ "name": "add_og_site", "arguments": { "url": "granola.ai" } }
```

Returns `{ host, slug, url }`, where `url` is the site's page, `/apps/<slug>?view=og`. The current image usually shows up within seconds and past versions within minutes. Read them with `get_og_timeline`.

## Resources

`app://{slug}` is a resource template. Reading `app://notion` returns the same details as `get_app`.

## Prompts

`find_ui_references` takes a `feature` (and an optional `platform`), for example "onboarding for a budgeting app", and gives the model a starting plan: which search tools to call and how to narrow the results by platform and device.

## Calling a tool over raw HTTP

```bash
curl -sS https://mcp.snaps.design/mcp \
  -H "Authorization: Bearer ass_…" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "search_apps",
      "arguments": { "query": "notion", "limit": 3 }
    }
  }'
```

## Errors

Tool results are JSON in a `text` content item. Tool failures (unknown slug, screen or site, refused request) come back as a result with `isError: true` and a message.

- HTTP 401 with a JSON-RPC error: missing, invalid or revoked key.
- HTTP 429 with a `Retry-After` header: more than 60 requests in a minute on one key.
- HTTP 400: the body is not valid JSON, or is a JSON-RPC batch. Send one message per request.
- HTTP 405 for `GET /mcp`: the server is stateless and has no event stream. Use `POST`.
- HTTP 503: the server could not reach its auth backend. Try again shortly.
- `request_app` or `add_og_site` with a read-only key: refused because it lacks the `write` scope.
- Invalid inputs (an unknown device string, a `limit` over 25 on `search_apps`) are rejected with a validation error naming the field.
