# Deck, Card and Image Tools for AI Agents

> Deck, card and image tools let an agent build custom decks, set card data and layouts, and crop, resize, filter and save images in the DiceyTable editor.

- Question: Which tools let an agent build decks and cards and edit images?
- Source: https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images
- Last verified: 2026-10-09

These tools turn card art into decks and edit images. They create decks, set each card and its data, design card layouts, and use the image editors to crop, resize, filter and save a picture.

## Tools in this family

10 tools. The [tool reference](https://diceytable.com/docs/ai-agents/reference/tools) lists every family. An MCP client shows each tool as `mcp__diceytable__<name>`.

| Tool | Class | Surfaces | Scopes | Summary |
|---|---|---|---|---|
| [`deck_create`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#deckcreate) | **W** | editor | editor:write | Create deck |
| [`deck_set_cards`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#decksetcards) | **W** | editor | editor:write | Set deck cards |
| [`card_data_set`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#carddataset) | **W** | editor | editor:write | Set card data |
| [`card_layout_set`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#cardlayoutset) | **W** | editor | editor:write | Set card layout |
| [`image_open`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageopen) | **R** | editor | read | Open image |
| [`image_apply`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageapply) | **W** | editor | editor:write | Apply image filter |
| [`image_resize`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageresize) | **W** | editor | editor:write | Resize image |
| [`image_crop`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagecrop) | **W** | editor | editor:write | Crop image |
| [`image_export`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageexport) | **W** | editor | editor:write | Save image |
| [`image_quick_edit`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagequickedit) | **W** | editor | editor:write | Quick-edit image |

`→ D` / `→ H`: the call escalates with certain arguments (see the tool). `+`: the call takes the class of the tool or action it dispatches to. `bridge`: answered by the bridge, on any surface, with no tab.

## `deck_create`

**Create deck** — Create a custom deck in the editor project from a card sheet (rows x columns), or an empty deck to fill later.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__deck_create` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `name` | `string` | **yes** | — | 1–120 chars | — |
| `sheetPath` | `string` | no | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `backPath` | `string` | no | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `rows` | `integer` | no | — | ≥ 1, ≤ 100 | — |
| `columns` | `integer` | no | — | ≥ 1, ≤ 100 | — |
| `cardCount` | `integer` | no | — | ≥ 1, ≤ 1000 | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `deckId` | `string` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Creates a custom deck the way the Deck tab does, and writes a new deck file. The deck can start empty, or come from a
card sheet and a card back. For a sheet, pass `sheetPath` with `rows` and `columns`, and pass the back as `backPath`.
Add `cardCount` when the last row of the sheet is not full.

**When to use it.** After importing the sheet and back images with [`asset_import`](https://diceytable.com/docs/ai-agents/reference/tools/assets-and-credits#assetimport). Then place the deck in the
scene with [`entity_create`](https://diceytable.com/docs/ai-agents/reference/tools/scene#entitycreate) and check its cards with [`screenshot_card`](https://diceytable.com/docs/ai-agents/reference/tools/screenshots#screenshotcard).

**Class.** W with `editor:write`.

**Gotchas.**
- `sheetPath` and `backPath` must be images already in the project (`png`, `jpg`, `webp`, `gif`, `bmp`, `avif`).
- A sheet needs `rows` and `columns`; `cardCount` larger than rows × columns is `out-of-range`.

### Example

A 60-card deck from a 10 × 7 sheet whose last row is partly empty:

```json
{
  "request": {
    "name": "Goods",
    "sheetPath": "cards/goods-sheet.webp",
    "backPath": "cards/goods-back.webp",
    "rows": 7,
    "columns": 10,
    "cardCount": 60
  },
  "response": {
    "deckId": "deck_goods"
  }
}
```

## `deck_set_cards`

**Set deck cards** — Set a deck's cards in the editor project through the deck tab's saver.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__deck_set_cards` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `deckId` | `string` | **yes** | — | 1–256 chars | — |
| `cards` | `Record<string, any>[]` | **yes** | — | ≤ 1000 items | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `deckId` | `string` | yes | — |
| `count` | `integer` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Replaces a deck's card list and saves the deck file, just as the Deck tab saves it. The tool checks the whole deck
against the deck schema before it writes anything.

**When to use it.** To name the cells of a deck's card sheet, set how many copies of each card the deck holds, give
each card its data, or reorder the list, in one call.

**Class.** W with `editor:write`.

**Gotchas.**
- `deckId` is the id [`deck_create`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#deckcreate) returned or the deck's `.deck.json` path.
- The list replaces the deck's cards whole. Each entry is a card record: `label`, `faceIndex` (the sheet cell,
  row-major from 0; defaults to the entry's position), `count` (copies, default 1), `data` (field values),
  `backIndex`, `rotationQuarter`, `assetPath` (the source image the cell was built from). `cardId` defaults to
  `card-<n>`.
- Cards address cells of the deck's sheet. Per-card `image` / `imagePath` entries are refused (`invalid`, reason
  `per-card-images`): composing individual images into a sheet is the Deck tab's job.
- A `faceIndex` past the sheet's last cell makes the deck invalid and nothing is written.

### Example

Three goods on the first three cells of the sheet, with copies and data:

```json
{
  "request": {
    "deckId": "assets/decks/goods.deck.json",
    "cards": [
      {
        "label": "Wheat",
        "faceIndex": 0,
        "count": 3,
        "data": {
          "cost": 1,
          "kind": "grain"
        }
      },
      {
        "label": "Ore",
        "faceIndex": 1,
        "count": 2,
        "data": {
          "cost": 2,
          "kind": "mineral"
        }
      },
      {
        "label": "Silk",
        "faceIndex": 2,
        "data": {
          "cost": 4,
          "kind": "luxury"
        }
      }
    ]
  },
  "response": {
    "deckId": "assets/decks/goods.deck.json",
    "count": 3
  }
}
```

## `card_data_set`

**Set card data** — Set a card's data fields in the editor project through the card data tab's saver.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__card_data_set` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `deckId` | `string` | **yes** | — | 1–256 chars | — |
| `cardIndex` | `integer` | **yes** | — | ≥ 0 | — |
| `data` | `Record<string, any>` | **yes** | — | — | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `deckId` | `string` | yes | — |
| `cardIndex` | `integer` | yes | — |
| `applied` | `string[]` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Sets one card's data fields (the values a card layout's text regions read, such as a cost or rules text) and saves the
deck file the way the Deck tab saves it. The values are merged into the card's existing data.

**When to use it.** When cards are rendered from a layout plus data, to fill in or correct one card.

**Class.** W with `editor:write`.

**Gotchas.**
- `cardIndex` is zero-based over the deck's card ENTRIES (a card with `count: 3` is one entry), in the deck's order.
- Keys are field keys (a letter or `_`, then letters, digits and `_`, up to 40 characters); values are strings,
  numbers, booleans or `null`. A key not listed is left as it was.
- Card text is what other players will read; it is also what agents read back as untrusted data, so keep it plain.

### Example

```json
{
  "request": {
    "deckId": "assets/decks/goods.deck.json",
    "cardIndex": 2,
    "data": {
      "cost": 5,
      "rules": "Worth 2 points at the end of the game."
    }
  },
  "response": {
    "deckId": "assets/decks/goods.deck.json",
    "cardIndex": 2,
    "applied": [
      "cost",
      "rules"
    ]
  }
}
```

## `card_layout_set`

**Set card layout** — Create or update a card layout (text and image regions) in the editor project through the card layouts tab.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__card_layout_set` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `layoutId` | `string` | no | — | 1–256 chars | — |
| `deckId` | `string` | no | — | 1–256 chars | — |
| `layout` | `Record<string, any>` | **yes** | — | — | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `layoutId` | `string` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Creates or updates a card layout in the project's card schema, `data/cardSchema.json`. A card layout is a template of
text and counter regions that draws cards from their data. The schema file is the one the Card Layouts tab edits. The
tool checks the layout before it writes it. Omit `layoutId` to make a new layout: it takes `layout.id`, or else
`layout-<n>`. An existing id is replaced whole.

**When to use it.** For games whose cards share a frame and differ in text and art. Preview the result with
[`screenshot_surface`](https://diceytable.com/docs/ai-agents/reference/tools/screenshots#screenshotsurface) on the `card-layout-preview` surface or [`screenshot_card`](https://diceytable.com/docs/ai-agents/reference/tools/screenshots#screenshotcard).

**Class.** W with `editor:write`.

**Gotchas.**
- The card schema must exist first (Mod ▸ New ▸ Card Data); without it the call is `not-found`.
- Region `rect`s are normalised 0 to 1 of the card face, origin top-left, and must stay inside it.
- A layout applies to the cards its `match` clauses (and `types`) select, not to a deck: `deckId` is accepted but
  not used. Only the last layout may be unconditional.
- Layout and region ids are lowercase letters, digits and `-`.

### Example

A layout for luxury goods: a static banner, and the card's cost and rules text from its data:

```json
{
  "request": {
    "layoutId": "luxury",
    "layout": {
      "name": "Luxury goods",
      "match": [
        {
          "fieldKey": "kind",
          "op": "equals",
          "value": "luxury"
        }
      ],
      "regions": [
        {
          "id": "banner",
          "rect": {
            "x": 0.08,
            "y": 0.05,
            "w": 0.66,
            "h": 0.08
          },
          "binding": {
            "kind": "static",
            "text": "Luxury"
          },
          "style": {
            "weight": "bold",
            "sizePct": 5
          }
        },
        {
          "id": "cost",
          "rect": {
            "x": 0.78,
            "y": 0.05,
            "w": 0.14,
            "h": 0.08
          },
          "binding": {
            "kind": "field",
            "fieldKey": "cost"
          },
          "style": {
            "align": "center",
            "sizePct": 5
          }
        },
        {
          "id": "rules",
          "rect": {
            "x": 0.08,
            "y": 0.62,
            "w": 0.84,
            "h": 0.3
          },
          "binding": {
            "kind": "field",
            "fieldKey": "rules"
          },
          "style": {
            "sizePct": 3
          }
        }
      ]
    }
  },
  "response": {
    "layoutId": "luxury"
  }
}
```

## `image_open`

**Open image** — Open an image asset in the editor's miniPaint image editor and report its size and layers.

| Property | Value |
|---|---|
| Class | **R** — read. No mutation. |
| Scopes | `read` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_open` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `path` | `string` | **yes** | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `path` | `string` | yes | — |
| `width` | `integer` | yes | — |
| `height` | `integer` | yes | — |
| `layers` | `string[]` | no | — |

A newer site may add fields; ignore ones you do not recognise.

Opens an image asset in the editor's deep image editor and reports its size. That editor is miniPaint, in the texture's
item tab. The other `image_*` tools work on the image you open this way, except
[`image_quick_edit`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagequickedit).

**When to use it.** Before [`image_apply`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageapply), [`image_resize`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageresize), [`image_crop`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagecrop) and [`image_export`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageexport).
For a one-shot crop, rotate or colour adjustment that saves straight away, [`image_quick_edit`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagequickedit) needs no open
editor.

**Class.** R: opening an editor changes nothing until you export. It waits up to 20 seconds for the editor to load.

**Gotchas.**
- Only `png`, `jpg` / `jpeg` and `webp` images can be opened.
- `layers` is not reported yet; filters apply to the whole image unless you pass a miniPaint layer id.

### Example

A request and the structured result it returns.

```json
{
  "request": {
    "path": "textures/board.webp"
  },
  "response": {
    "path": "textures/board.webp",
    "width": 4096,
    "height": 4096
  }
}
```

## `image_apply`

**Apply image filter** — Apply a miniPaint filter or effect by name to the image open in the editor's image editor.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_apply` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `filter` | `string` | **yes** | — | 1–64 chars | — |
| `params` | `Record<string, any>` | no | — | — | — |
| `layer` | `string` | no | — | ≤ 128 chars | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `ok` | `boolean` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Applies one of miniPaint's layer filters to the open image, by name: `blur`, `brightness`, `contrast`, `grayscale`,
`hue-rotate`, `invert`, `saturate` or `sepia`. The filter goes into miniPaint's own history, so you can undo it in the
editor. Nothing is written to the asset until [`image_export`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageexport).

**When to use it.** To adjust art in place (tone down a texture, desaturate a card back).

**Class.** W with `editor:write`.

**Gotchas.**
- `params.value` is the strength in miniPaint's units: `blur` 0 to 50 px, `hue-rotate` 0 to 360 degrees,
  `brightness`, `contrast` and `saturate` 0 to 300 %, `grayscale`, `invert` and `sepia` 0 to 100 %. Out of range is
  refused, never clamped. Without `value` the filter's default is used.
- `layer` is a miniPaint layer id (an integer as a string); omit it for the whole image.
- Needs [`image_open`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageopen) first; otherwise `not-mounted`.

### Example

A request and the structured result it returns.

```json
{
  "request": {
    "filter": "saturate",
    "params": {
      "value": 80
    }
  },
  "response": {
    "ok": true
  }
}
```

## `image_resize`

**Resize image** — Resize the image open in the editor's image editor.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_resize` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `width` | `integer` | **yes** | — | ≥ 1, ≤ 16384 | — |
| `height` | `integer` | **yes** | — | ≥ 1, ≤ 16384 | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `width` | `integer` | yes | — |
| `height` | `integer` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Resizes the open image to an exact width and height in pixels. Then the editor opens the result as its document.

**When to use it.** To bring an oversized texture down before exporting (2048 px is plenty for a board, 1024 px for a
card).

**Class.** W with `editor:write`.

**Gotchas.**
- It does not keep the aspect ratio for you: compute `height` from the size [`image_open`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageopen) reported.
- miniPaint's undo history restarts with the resized document. The asset itself is untouched until
  [`image_export`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageexport).

### Example

A request and the structured result it returns.

```json
{
  "request": {
    "width": 2048,
    "height": 2048
  },
  "response": {
    "width": 2048,
    "height": 2048
  }
}
```

## `image_crop`

**Crop image** — Crop the image open in the editor's image editor to a pixel rectangle [x, y, w, h].

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_crop` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `rect` | `[integer, integer, integer, integer]` | **yes** | — | each ≥ 0; each > 0 | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `width` | `integer` | yes | — |
| `height` | `integer` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Crops the open image to a pixel box, `[x, y, w, h]`. Then it reopens the result as the editor's document.

**When to use it.** To trim borders or cut one card out of a scan before exporting.

**Class.** W with `editor:write`.

**Gotchas.**
- The rectangle must lie inside the image; otherwise `out-of-range` with the image's size.
- As with [`image_resize`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageresize), miniPaint's history restarts, and nothing is saved until [`image_export`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageexport).

### Example

A request and the structured result it returns.

```json
{
  "request": {
    "rect": [
      64,
      64,
      1920,
      1920
    ]
  },
  "response": {
    "width": 1920,
    "height": 1920
  }
}
```

## `image_export`

**Save image** — Save the image open in the editor's image editor back to its asset, or to a new path.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_export` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `path` | `string` | no | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `format` | `"png"` \| `"webp"` \| `"jpeg"` | no | — | — | — |
| `quality` | `number` | no | — | ≥ 0.1, ≤ 1 | — |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `path` | `string` | yes | — |
| `bytes` | `integer` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Saves the open image. With no arguments it does the editor's own "Save to texture". The texture tab encodes the image
again and writes it back to the same asset. With `path`, `format` or `quality`, the tool encodes the merged image and
writes it to that path, through the texture editor's save path.

**When to use it.** After [`image_apply`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageapply), [`image_resize`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageresize) or [`image_crop`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imagecrop): nothing reaches the
project until you export.

**Class.** W with `editor:write`.

**Gotchas.**
- `format` must agree with the path's extension (`png`, `webp`, `jpeg` for `.jpg` / `.jpeg`).
- A new `path` creates a new asset, which needs a credit before publishing; check [`credits_list`](https://diceytable.com/docs/ai-agents/reference/tools/assets-and-credits#creditslist).
- The stored-size rule applies (over 50 MB refused).

### Example

Saving back to the open asset (the editor's Save to texture):

```json
{
  "request": {},
  "response": {
    "path": "textures/board.webp",
    "bytes": 611204
  }
}
```

## `image_quick_edit`

**Quick-edit image** — Apply quick-editor operations (crop, rotate, flip, adjust, filter) to an image asset in the editor and save it.

| Property | Value |
|---|---|
| Class | **W** — write. A reversible draft edit, or a table action your role permits. Rate-limited. |
| Scopes | `editor:write` |
| Surfaces | `editor` |
| Untrusted output | no |
| Bridge-local | no — routed to a paired tab |
| MCP name | `mcp__diceytable__image_quick_edit` |

**Input**

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `path` | `string` | **yes** | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `operations` | `object[]` | **yes** | — | 1–50 items | — |
| `operations[].op` | `string` | **yes** | — | 1–32 chars | — |
| `operations[].params` | `Record<string, any>` | no | — | — | — |
| `saveAs` | `string` | no | — | 1–300 chars | Repo-relative path, e.g. models/board.glb. |
| `tab` | `string` | no | — | 1–64 chars | Target tab id from session_list_tabs, or "all" where a tool supports it; defaults to the selected tab. |

**Output** (structured content)

| Field | Type | Always present | Description |
|---|---|---|---|
| `path` | `string` | yes | — |
| `bytes` | `integer` | yes | — |

A newer site may add fields; ignore ones you do not recognise.

Applies a list of quick edits to an image asset and saves the result. No editor opens. The edits run in order. They are
`crop` (`rect: [x, y, w, h]`), `rotate` (`degrees`, a multiple of 90), `flip` (`axis`: `horizontal` or `vertical`),
`resize` (`width`, `height`), `adjust` (`brightness`, `contrast`, `saturation`, each 0 to 300 %) and `filter` (`name`
and `value`, the same filters as [`image_apply`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageapply)).

**When to use it.** For quick fixes in one call, such as rotating a sideways card scan or cropping a screenshot. For
work you want to inspect step by step, use miniPaint through [`image_open`](https://diceytable.com/docs/ai-agents/reference/tools/decks-cards-images#imageopen).

**Class.** W with `editor:write`.

**Gotchas.**
- `saveAs` writes a new file and leaves the original alone; without it the original is overwritten.
- Only `png`, `jpg` / `jpeg` and `webp` can be read and written.
- The quick editor's own interface is a third-party component, so this tool performs the same operations on a canvas
  and saves through the same path as the quick editor's Save. The quick editor's own undo history is not involved.

### Example

Rotating a sideways card scan and saving it as a new file:

```json
{
  "request": {
    "path": "scans/spice-card.jpg",
    "operations": [
      {
        "op": "rotate",
        "params": {
          "degrees": 90
        }
      },
      {
        "op": "crop",
        "params": {
          "rect": [
            12,
            12,
            750,
            1050
          ]
        }
      }
    ],
    "saveAs": "cards/spice.webp"
  },
  "response": {
    "path": "cards/spice.webp",
    "bytes": 98412
  }
}
```
