---
title: "read_look"
description: "The styling a human already approved on a project, with its full version history."
canonical: "https://shotops.dev/docs/mcp/reference/read_look"
last_updated: "2026-09-07"
shotops_mcp_version: "0.9.6"
result_contract_version: "2.0.0"
---
# read_look

The styling a human already approved on a project, with its full version history.

## What it does

- Read-only
- Idempotent
- Account required

Match a design instead of inventing one. This returns the saved ShotOps look on a project — the device, background and caption styling somebody tuned in the web app — along with the latest version, the held version if there is one, and the whole version list. Styling only: no screenshots, no caption words, no credentials.

You can ask: “Show me the Look the designer settled on for Tidebook.”

## Input

- `project`stringoptionalat least 1 character Which ShotOps project to target: its id (as returned by read_look/save_project), OR its NAME as the user says it — matched exactly, ignoring case and surrounding spaces. Omit = your most recently edited project. A name that matches none or several is refused with the account's projects listed, never resolved by guessing.

## Result

- `saved`booleanoptional
- `project`objectoptional
  - `id`stringrequired
  - `name`stringrequired
- `message`stringoptional
- `layout`objectoptional Which layout template this strip is composed on, DERIVED from the values it holds rather than stored — so it cannot go stale, and it reports the near miss when a template was nudged. Absent when there is nothing to derive it from.
  - `layout`string or nullrequired The layout template this composition is on ("standard" | "bleed" | "top-bleed"), or null when it matches none — including when a multi-device panel’s devices disagree, or the strip’s panels are on different templates (read `panels` then).
  - `closestLayout`string or nulloptional Only when `layout` is null: the nearest template by fewest differing fields, or null when even that is contested. Apply it with style.layout and re-apply your adjustment.
  - `differs`objectoptional Alongside a `closestLayout`: exactly which fields keep it from being an exact match.
  - `panels`objectrequired The same answer per panel id, in strip order — a strip may mix compositions.
- `history`objectoptional Structured access decision for retained Look history. When unavailable, versions and heldVersion are omitted while the current saved Look remains readable.
  - `available`booleanrequired
  - `capability`stringrequired
  - `reason`stringoptional
  - `requiredPlan`stringoptional
- `ok`booleanoptional

## Example

That request maps to this call:

```
{
  "name": "read_look",
  "arguments": {
    "project": "Tidebook 2.4 launch"
  }
}
```

The look object, the version it came from, which version is held, and the list of versions with their timestamps.

## Access and cost

- Needs an account. Not available to an anonymous hosted caller.
- Free. Reading spends no cloud credits.

## When it refuses

- **The project has no saved look.**
  Nothing was ever saved on it. Compose a look yourself — describe_look has the catalog — and save_look once the user likes it.

- **The project name did not resolve.**
  Names are matched exactly. Use the project id from save_project or from the URL in the web app.

## Where this fits

- [Reading a project before you change it](https://shotops.dev/docs/mcp/workflows/saved-project)

## What the agent is told

The title and description the server publishes on `tools/list` — this is the copy a model chooses between, reproduced verbatim.

Read saved look

Match a design the user already approved instead of inventing a new one: returns the saved ShotOps look on a project — the device, background and caption styling a human tuned in the web app — so the next render comes out looking like theirs. Styling only: no screenshots, no caption words, no credentials. Comes with the latest version, the held version (if any) and the full `versions` history. Feed the returned look back into render_strip/emit_bundle as `look`, or just pass `useSavedLook: true`; render an older entry with `version`, or make one the default with hold_look.
