# Populate letter part demo colours (`populate_letter_part_demo_colours`)

Adds the Sign Customiser demo colours for the customiser sign category to one empty letter part of one letter type, and returns the colours it created. A letter part that already holds colours is refused rather than merged, and a part with no demo colours for its sign category is refused. It requires the customisers:write scope and an idempotency_key, and supports dry_run.

- Source URL: https://www.signcustomiser.com/help/mcp/tools/populate_letter_part_demo_colours/
- Markdown URL: https://www.signcustomiser.com/help/mcp/tools/populate_letter_part_demo_colours.md
- MCP endpoint: https://mcp.signcustomiser.com
- Required scope: `customisers:write`
- Behaviour: write

## Purpose

Give an empty letter part a ready-made set of colours in one call, instead of creating each colour with create_customiser_option.

## Annotations

| Hint | Value |
| --- | --- |
| readOnlyHint | false |
| destructiveHint | false |
| idempotentHint | true |
| openWorldHint | false |

## Prerequisites

- A customiser id from list_customisers and a letter type id from list_customiser_options with option_type letter_type.
- A letter part the letter type declares in its letter_parts, and that holds no colours yet.
- A merchant has connected this store and approved the customisers:write scope.

## Side effects

- Creates the letter part colour selection when it does not exist, and adds the demo colours to it.
- Clears the customiser cached storefront configuration.
- Claims the idempotency_key for at least 24 hours.

## Arguments

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `customiser_id` | integer | yes | The customiser id, from list_customisers. |
| `letter_type_id` | integer | yes | The letter type that owns the letter part, from list_customiser_options with option_type letter_type. |
| `letter_part` | string | yes | The letter part to fill. It must be one of the letter type own letter_parts and hold no colours yet. One of: `face`, `back`, `side`, `top`, `bottom`, `left`, `right`, `halo`, `trim`, `tube`. |
| `idempotency_key` | string | unless `dry_run` is true | A client-generated key unique to this logical write, such as a UUID. Required: repeating the call with the same key and the same arguments replays the original result instead of writing twice, and the same key with different arguments is an idempotency_key_conflict. |
| `dry_run` | boolean | no | When true, the letter part is checked for existing colours and for demo colours of the customiser sign category is checked and nothing is written: the result is the same verdict the apply would have reached, and a problem the apply would have raised comes back as the same tool error. Defaults to false. A dry run claims no key. |

## Result

Every colour the call created, in storefront order, with the field names list_customiser_options returns for the letter_part_colour family. A dry run returns the populate verdict instead and writes nothing.

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `request_id` | string | yes |  |
| `store` | object | yes |  |
| `store.id` | integer | yes |  |
| `store.name` | string | yes |  |
| `customiser_id` | integer | yes |  |
| `letter_type_id` | integer | yes |  |
| `letter_part` | string | yes | One of: `face`, `back`, `side`, `top`, `bottom`, `left`, `right`, `halo`, `trim`, `tube`. |
| `colours` | array of object | no | Every colour the call created, in storefront order, with the field names of the letter_part_colour family. Absent on a dry run. |
| `dry_run` | boolean | no | Present and true only when dry_run was requested. |
| `valid` | boolean | no | Present only on a dry run, and always true: a failing dry run returns a tool error instead. |
| `verdict` | object | no | Present only on a dry run: the populate verdict. |
| `idempotent_replay` | boolean | no | True when this call replayed a previously recorded response for the same idempotency_key instead of applying the write again. |

## Error cases

| Code | Recovery |
| --- | --- |
| `demo_colours_not_available` | There are no demo colours for this sign category and letter part. Add colours one at a time with create_customiser_option. |
| `idempotency_key_conflict` | That key was used for a different letter type or letter part. Re-send the original arguments or issue a new key. |
| `insufficient_scope` | The connection was approved without customisers:write. |
| `letter_part_colours_not_empty` | The letter part already holds colours. Delete them first, or add colours one at a time with create_customiser_option. |
| `letter_part_not_declared` | The letter type does not declare that part. Read the letter type and use one of its declared letter_parts. |
| `rate_limited` | The store option-write budget is spent. Wait retry_after seconds. |
| `resource_not_found` | No customiser or letter type with that id exists in this store. |

## Example: Fill an empty face with demo colours

Request:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "populate_letter_part_demo_colours",
    "arguments": {
      "customiser_id": 42,
      "letter_type_id": 7,
      "letter_part": "face",
      "idempotency_key": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f"
    }
  }
}
```

Response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t",
      "store": {
        "id": 12,
        "name": "Demo Signs"
      },
      "customiser_id": 42,
      "letter_type_id": 7,
      "letter_part": "face",
      "colours": [
        {
          "id": 301,
          "name": "White",
          "colour_type": "single",
          "hexcode": "#FFFFFF",
          "sort_order": 1
        }
      ],
      "idempotent_replay": false
    }
  }
}
```

## Example: Check the populate without writing

Request:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "populate_letter_part_demo_colours",
    "arguments": {
      "customiser_id": 42,
      "letter_type_id": 7,
      "letter_part": "face",
      "dry_run": true
    }
  }
}
```

Response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t",
      "store": {
        "id": 12,
        "name": "Demo Signs"
      },
      "customiser_id": 42,
      "letter_type_id": 7,
      "letter_part": "face",
      "dry_run": true,
      "valid": true,
      "verdict": {
        "operation": "populate_demo",
        "customiser_id": 42,
        "letter_type_id": 7,
        "letter_part": "face",
        "colour_id": null
      }
    }
  }
}
```

## Example: A letter part that already holds colours (error)

Request:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "populate_letter_part_demo_colours",
    "arguments": {
      "customiser_id": 42,
      "letter_type_id": 7,
      "letter_part": "face",
      "idempotency_key": "d5e6f7a8-b9c0-4d1e-8f2a-3b4c5d6e7f80"
    }
  }
}
```

Response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "isError": true,
    "structuredContent": {
      "error": {
        "code": "letter_part_colours_not_empty",
        "title": "Letter part colours not empty",
        "detail": "The face letter part already holds colours, so demo colours would mix into them. Delete its colours first, or add colours one at a time.",
        "recovery": "The letter part already holds colours, so demo colours would mix into them. Delete its colours with delete_customiser_option first, or add colours one at a time with create_customiser_option.",
        "pointer": ""
      }
    }
  }
}
```
