# Locations

> Create locations from an AI assistant, generate and approve their establishing shots, add time of day, weather and angle variants, and animate atmosphere clips.

Source: https://nodaro.ai/docs/mcp/tools/locations

The **location tools** let an assistant build and use the places in your library: a street, a room or a landscape with a locked look that stays the same in every shot. The assistant creates a location, generates and approves its establishing shot, adds variants for time of day, weather, seasons, angles and lighting, animates atmosphere clips, and passes the pictures as references to other generations. Read [Locations](https://nodaro.ai/docs/guides/locations) for the same work in the app.

The lifecycle matches the [character tools](https://nodaro.ai/docs/mcp/tools/characters): create, generate a main image, approve it, then generate variants and motion from it.

## `list_locations`

Lists your locations, newest first, with their name, description, main image, the number of variants of each kind, and their identity: canonical description, category, style and style lock. Archived locations are left out unless you ask for them.

**Permission:** `assets:read`. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `search` | string | Part of the location's name, not case-sensitive, up to 100 characters. |
| `archived` | boolean | `true` lists the archived locations instead. |

**Returns:** the locations. Call `get_location` for the picture URLs.

## `get_location`

Returns one location in full: every time of day, weather, angle, lighting, season and atmosphere clip with its name and URL, the reference photos, and the identity fields.

**Permission:** `assets:read`. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `id` | string | **Required.** The location id from `list_locations`. |

**Returns:** the location, including `updatedAt` for `update_location`, and the generations still running for it. An error when the location does not exist or is not yours.

## `create_location`

Creates a location with its identity. It has no main image yet: generate one with `generate_location` next.

**Permission:** `assets:write`. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `name` | string | **Required.** The display name, such as `Rainy Tokyo Alley`, up to 200 characters. |
| `description` | string | Up to 2,000 characters. |
| `category` | string | A category tag, such as `interior`, `exterior` or `urban`, up to 50 characters. |
| `style` | string | A style tag, such as `cinematic`, `documentary` or `noir`, up to 50 characters. |
| `projectId`, `workflowId`, `nodeId` | string | Optional links to a project, a workflow or a canvas node. Usually left out. |

**Returns:** the new location's id.

## `update_location`

Changes a location's identity. Only the fields you pass are written. The variants are not editable here; the generation tools add them.

**Permission:** `assets:write`. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `id` | string | **Required.** The location id. |
| `name`, `description`, `category`, `style` | string | As on `create_location`. |
| `canonicalDescription` | string | The scene description, up to 4,000 characters. Your text replaces the automatic caption. |
| `styleLock` | boolean | When `true`, every variant generation also receives the main image as a reference, for a consistent layout. |
| `expectedUpdatedAt` | string | The `updatedAt` from `get_location`. The change is refused when the location changed since you read it. |

**Returns:** a confirmation, or a conflict error when `expectedUpdatedAt` is out of date.

## `approve_main_image`

Makes a finished `generate_location` result the location's main image, and has a vision model describe it to fill the location's canonical description.

**Permission:** `assets:write`. **Credits:** one short LLM run for the description.

| Parameter | Type | Notes |
| --- | --- | --- |
| `location_id` | string | **Required.** The location. |
| `candidate_job_id` | string | **Required.** A completed `generate_location` job of yours. |

**Returns:** the main image URL and the description. When the description fails, the image is still set and the description is empty; run `recaption_location`.

## `recaption_location`

Has the vision model describe the current main image again, and saves the new canonical description.

**Permission:** `assets:write`. **Credits:** one short LLM run.

| Parameter | Type | Notes |
| --- | --- | --- |
| `location_id` | string | **Required.** The location. |

**Returns:** the new description. `400 no_source_image` when the location has no main image.

## `generate_location`

Generates a location's establishing shot (`kind: "main"`) or a variant (`kind: "asset"`).

**Permission:** `workflows:execute`. **Credits:** the price of the image model.

| Parameter | Type | Notes |
| --- | --- | --- |
| `name` | string | **Required.** The location's name. |
| `kind` | string | `main` (default) or `asset`. |
| `description`, `style` | string | The identity, for a main image. |
| `category` | string | `indoor`, `outdoor`, `urban`, `nature`, `fantasy`, `sci-fi`, `historical`, `futuristic` or `other`. |
| `model` | string | The image model. Default `nano-banana`. |
| `asset_type` | string | For `asset`: `timeOfDay`, `weather`, `seasons`, `angles`, `lighting` or `custom`. |
| `variant` | string | For `asset`: for example `dawn`, `noon`, `dusk` or `night`; `rain`, `snow` or `fog`; `spring` to `winter`; `aerial`, `street-level` or `wide`; `golden-hour`, `overcast` or `neon`; or a short label of your own. |
| `attach_to_location_id` | string | Saves the result on this location and uses its approved main image as the source. Without one, the call returns `main_image_required`. |
| `attach_to_column` | string | Required with `attach_to_location_id` for a `custom` variant: `time_of_day`, `weather`, `seasons`, `angles`, `lighting`, `atmosphere_motions`, `sheets` or `detail_closeups`. |
| `attach_name` | string | The name of the saved variant. Default: the variant. |
| `source_image_url` | string | A source picture, when you do not attach to a location. |

**Returns:** a job id. For a main image, pass the job to `approve_main_image` when you like the result.

## `generate_location_motion`

Animates a location into an atmosphere clip: a camera move with subtle motion in the world, such as "slow dolly-in, leaves drift across frame" or "drone fly-over, neon signs flicker".

**Permission:** `workflows:execute`. **Credits:** the price of the video model.

| Parameter | Type | Notes |
| --- | --- | --- |
| `motion_prompt` | string | **Required.** The camera move and the motion, up to 2,000 characters. |
| `source_image_url` | string | **Required.** The first frame, usually the location's approved main image. |
| `name` | string | **Required.** The location's name, used as context in the prompt. |
| `provider` | string | `kling` (default), `kling-turbo`, `kling-3.0`, `wan-i2v`, `wan-2.7-i2v` or `seedance-2`. |
| `attach_to_location_id` | string | Saves the clip in the location's atmosphere clips. |
| `attach_name` | string | The name of the saved clip. |
| `refine_from_video_url` | string | Refines an existing clip with a new prompt, as video to video, instead of starting from the image. |
| `canonical_description`, `category`, `style` | string | Extra context for the prompt. |

**Returns:** a job id. The card plays the clip when it is ready.

## Frequently asked questions

### How do I keep the same place in every shot?

Create a location, approve one establishing shot as its main image, and generate its variants from that image. Pass the main image or a variant as a reference in every image or video that shows the place.

### What variants can a location have?

Time of day, weather, seasons, camera angles and lighting, plus custom variants you name yourself. Each one is generated from the approved main image and saved on the location.

### What does styleLock do?

With styleLock on, every variant generation also receives the main image as a reference, which keeps the layout of the place consistent between variants.

### How do I refine an atmosphere clip without starting over?

Call generate_location_motion again with refine_from_video_url set to the clip and a new prompt, such as the same shot with light rain instead of fog. It runs video to video on that clip.
