---
title: "read_project"
description: "A project’s full current state — frame order, per-locale caption words, styling."
canonical: "https://shotops.dev/docs/mcp/reference/read_project"
last_updated: "2026-09-07"
shotops_mcp_version: "0.9.6"
result_contract_version: "2.0.0"
---
# read_project

A project’s full current state — frame order, per-locale caption words, styling.

## What it does

- Read-only
- Idempotent
- Account required

What the designer actually changed. This returns the project file itself: the frame order they settled on, the caption words they typed for each locale, the locale list and the styling. It also answers whether the project holds its own screenshots, which decides whether render_project needs anything attached at all. Read-only, and it never returns screenshot bytes.

You can ask: “Check whether the Tidebook project can render with nothing attached.”

## 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.
- `screenshots`objectoptional
  - `available`booleanrequired True when render_project on THIS server can render the project with NO `screenshots` argument, from the screenshots the project already holds. Token-backed local stdio uses the Studio control plane; unsigned local mode cannot read account projects.
  - `count`numberrequired How many shot × device-family × locale cells resolve to a screenshot, including inherited cells.
  - `total`numberrequired Total shot × distinct target-family × project-locale cells in the project’s render grid.
  - `names`arrayrequired Filenames with a screenshot available in at least one project variant. each item string
  - `missing`arrayrequired Shots with no stored screenshot — supply these by `name`, or have the user drop them into the project. each item string
  - `reach`string or nullrequired How far the project’s screenshots reach: "account" (readable here), "device", "shared", or null.
  - `cells`arrayrequired One row per shot × target-family × locale. `resolvedAt` names the manifest cell used; `inherited` says which requested axes fell back. This is the authoritative coverage report. each item object - `name`stringrequired - `variant`objectrequired Which screenshot cell this image belongs to. Empty {} is the project's base device family + base locale; a missing cell inherits through ShotOps' pixel fallback rules. - `family`stringoptionalat least 1 characterat most 80 characters Device screenshot family (for example "android"). Omit for the project's base family; the two currently advertised iPhone outputs share that base family. - `locale`stringoptionalat least 1 characterat most 80 characters App Store locale for these pixels. Omit for the project's base locale. - `available`booleanrequired - `resolvedAt`one of 2 shapesrequired Which screenshot cell this image belongs to. Empty {} is the project's base device family + base locale; a missing cell inherits through ShotOps' pixel fallback rules. 1`object` Which screenshot cell this image belongs to. Empty {} is the project's base device family + base locale; a missing cell inherits through ShotOps' pixel fallback rules. - `family`stringoptionalat least 1 characterat most 80 characters Device screenshot family (for example "android"). Omit for the project's base family; the two currently advertised iPhone outputs share that base family. - `locale`stringoptionalat least 1 characterat most 80 characters App Store locale for these pixels. Omit for the project's base locale. 2`null` - `inherited`arrayrequired each item string one of`family``locale`
- `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_project",
  "arguments": {
    "project": "Tidebook 2.4 launch"
  }
}
```

The project file, its updatedAt stamp, and a screenshots block whose `available` flag tells you whether render_project can run with no screenshots argument.

## Access and cost

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

## When it refuses

- **You want to know whether the strip changed since last time.**
  Remember `updatedAt` and compare on the next read. A newer value means somebody edited it.

- **You were about to ask the user to re-upload their screenshots.**
  Check the screenshots block first. If it says they are available, render_project needs nothing from the conversation.

## Where this fits

- [Reading before refining](https://shotops.dev/docs/mcp/workflows/saved-project)
- [Polling a project from CI](https://shotops.dev/docs/mcp/workflows/automation)

## 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 full project

Find out what the designer changed in a strip: returns a project's FULL current state — the frame order they settled on (panels), the caption words they typed for each locale (captionText), the locale list, and the styling — as an opaque ProjectFile, not just the look. To answer a recurring "any updates?", remember the returned `updatedAt` and re-read later; a newer value means the strip was edited since. It ALSO answers whether the project already holds its own screenshots: `screenshots.available` true means render_project can render it with NO `screenshots` argument and nothing attached — check that before concluding you need the files. Read-only, never returns screenshot bytes, no store credential.
