# Projects and workflows

> Let an AI assistant build Nodaro workflows as JSON, edit them safely with version checks, move them with export and import, and run them in the mcp project.

Source: https://nodaro.ai/docs/mcp/tools/projects-and-workflows

The **project and workflow tools** let an assistant build Nodaro workflows the way the editor stores them: as JSON nodes and connections. The assistant learns the format with `start_workflow_editor` and `get_node_skill`, creates and edits workflows, moves them between projects with export and import, and runs them. Every workflow it creates or edits lives in the [mcp project](https://nodaro.ai/docs/mcp/tools#the-mcp-project), so your own projects stay untouched.

## A typical session

### Learn the format

Call `start_workflow_editor`. It returns the workflow JSON shape, the rules for wiring connections, and the catalog of node types. Call `get_node_skill` for each node type the workflow needs, and `get_picker_catalog` for the valid values of each picker.

### Create the workflow

Call `create_workflow` with a name and, if you like, the first nodes and connections. The workflow opens in the editor under **MCP Workflows**.

### Edit it safely

Read the current graph with `get_workflow_json`, then send a `delta` to `update_workflow_json` with the version you read. Only the nodes and connections you name change.

### Run it

Call `run_workflow` and follow the run with [`get_app_run`](https://nodaro.ai/docs/mcp/tools/gallery-and-assets#get_app_run). Each node's result is saved to your library.

## `start_workflow_editor`

Returns the guide an assistant reads before it builds or edits a workflow. The guide covers the workflow JSON shape, the wiring conventions for connections and inputs, and the rules of `update_workflow_json`. It also lists the result fields of every generation node and the catalog of node types.

**Permission:** none, always visible. **Credits:** free.

This tool has no parameters. It changes nothing and can be called any number of times.

## `get_node_skill`

Returns the full guide for one node type: its data fields with their defaults, when to use it, common mistakes, and a worked JSON example. Use it before writing a node of that type into a workflow.

**Permission:** none, always visible. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `node_type` | string | **Required.** The node type in kebab case, as listed by `start_workflow_editor`, for example `generate-image`, `list` or `trim-video`. |

**Returns:** the node's guide. An unknown type returns an error with the list of valid types.

## `get_picker_catalog`

Returns the valid values of a picker node, such as **Setting**, **Mood**, **Person** or **Lens**. Pickers add a phrase to the prompt of the node they feed, so a workflow must use a real catalog id. Call this tool before you write a picker's value into a workflow.

**Permission:** none, always visible. **Credits:** free.

| Parameter | Type | Notes |
| --- | --- | --- |
| `node_type` | string | The picker type in kebab case, for example `setting`. Omit it to list every picker. |
| `detail` | string | `compact` (default): `id`, `label`, `category`, `term`, `icon` and `imageUrl`. `full` also adds each option's `description` and `promptHint`, the full phrase it adds to the prompt. |
| `category` | string | For single-dimension pickers: only the options of one category. |
| `field` | string | Only one dimension of a multi-dimension picker, such as **Person**, **Styling** or **Framing**. Also the extra settings of a single-dimension picker, such as the position, duration and intensity of **Transition** and **Character FX**, or the position and pace of **Character Motion**. |

**Returns:** without `node_type`, a directory of every picker with its `nodeType`, `label`, `kind` (`single` or `multi`), its value field or fields, `optionCount` and `imageCount`. With `node_type`, that picker's options. An unknown type returns an error with the valid types.

Every option carries a `term`, the short professional phrase to write into a prompt, such as `whip pan left`. `label` is only for display. A no-op option such as `auto` or `none` has an empty `term`. Options with a picture carry an absolute `imageUrl`: show it as it is and never build one from an id. **Person** and **Styling** also return `sections`, their topics in order, each with a label, its fields and an optional picture.

```json
{
"nodeType": "person",
"sections": [
{ "label": "Identity", "fields": ["type", "age", "ethnicity", "regionalAesthetic"],
"imageUrl": "https://app.nodaro.ai/picker-art/character/sections/identity.2d5ec1a4.webp" }
],
"dimensions": [
{ "field": "type", "label": "Type", "options": [
{ "id": "man", "label": "Man", "term": "man",
"imageUrl": "https://app.nodaro.ai/picker-art/character/person/man.441363db.webp" }
] }
]
}
```

The pictures of the look pickers are returned on Nodaro Cloud only. [Picker catalogs](https://nodaro.ai/docs/developers/picker-catalogs) covers the same data for developers.

## `list_projects`

Lists every project in your account, ordered by name, with its id, name, description, workflow count and creation date. The assistant can read all your projects, but it edits only the mcp project.

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

This tool has no parameters.

**Returns:** `data`, the list of projects.

## `get_project`

Returns one project by id or by name.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `project_id` | string | **Required.** A project id, or a project name. A name must match exactly, including capital letters, for example `My Feature Film`. |

**Returns:** the project's id, name, description, workflow count and creation date.

## `list_workflows`

Lists the workflows in the mcp project, newest first.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `limit` | integer | From 1 to 100. Default `20`. |
| `cursor` | string | The `next_cursor` of the previous page. |
| `include_sub_workflows` | boolean | Default `false`, which hides sub-workflows that belong to another workflow, as the editor's project view does. Pass `true` to list them too. |

**Returns:** `data`, with each workflow's id, name, description, version, thumbnail and dates, and `next_cursor`. A `next_cursor` of `null` means the last page.

## `get_workflow`

Returns the details of one workflow in the mcp project: its name, description, version and dates.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** A workflow id in the mcp project. |

## `get_workflow_json`

Returns the full graph of a workflow in the mcp project: its nodes, connections, settings, name, `updated_at` and `version`.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** A workflow id in the mcp project. |

**Returns:** the graph. Keep `version` and send it back with your next change, so the change fails instead of overwriting someone else's edit.

## `create_workflow`

Creates a workflow in the mcp project, empty or with a first graph.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `name` | string | **Required.** From 1 to 200 characters. |
| `description` | string | Up to 2,000 characters. |
| `nodes` | array | The first nodes, in the editor's node format. |
| `edges` | array | The first connections. |
| `settings` | object | Workflow settings. |

**Returns:** the new workflow's `id` and `name`. Settings a model does not support are corrected, as described in [update_workflow_json](#update_workflow_json).

## `update_workflow_json`

Changes a workflow in the mcp project: its graph, its settings or its thumbnail. Every field except `workflow_id` is optional, so you can, for example, change only the thumbnail.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** A workflow id in the mcp project. |
| `delta` | object | A partial change, applied as one step against `delta.base_version`. The preferred way to edit. See below. |
| `nodes` | array | Replaces every node. Send it together with `edges`. |
| `edges` | array | Replaces every connection. Send it together with `nodes`. |
| `settings` | object | Replaces the workflow settings. |
| `thumbnail_url` | string or null | The URL of an image that is already hosted, or `null` to remove the thumbnail. |
| `expected_version` | integer | The `version` from `get_workflow_json`. The change is refused if the workflow changed since. |
| `expected_updated_at` | string | The `updated_at` from `get_workflow_json`, an older way to do the same check. Prefer `expected_version`. |

**Returns:** a confirmation with the node count, and the list of any settings Nodaro corrected.

### Edit with a delta

A `delta` names only what changes, by id. It cannot be combined with `nodes`, `edges`, `settings`, `thumbnail_url` or the `expected_` fields.

| Delta field | What it does |
| --- | --- |
| `base_version` | **Required.** The `version` from `get_workflow_json`. The change is refused if the workflow changed since. |
| `upsert_nodes` | Whole nodes to add or replace, matched by id. |
| `delete_node_ids` | Nodes to remove. Their connections are removed too. |
| `upsert_edges` | Whole connections to add or replace, matched by id. |
| `delete_edge_ids` | Connections to remove. |
| `set` | A new `name`, or new `settings` that replace the old ones. |

Prefer a delta to sending the whole graph. A full write based on an old copy erases the changes another session made in the meantime.

### When the workflow changed in between

With `expected_version`, `expected_updated_at` or a delta, a workflow that changed since you read it returns a conflict: "Workflow was modified since you last read it. Fetch the latest JSON with get_workflow_json and retry." Read it again and repeat the change. Without these fields, the write overwrites the workflow unconditionally.

### Settings a model does not support

Image nodes take model-specific settings, such as `aspectRatio`, `resolution` and `quality`, and each model allows different values. When a node asks for a value its model does not accept, Nodaro does not refuse the write. It changes the value to one the model supports, or removes it when the model has no such setting, and the reply lists each change:

```text
Updated workflow 4f0c… (12 nodes).

Adjusted 2 parameter(s) the selected model does not accept:
  - node_8 (gpt-image): aspectRatio "16:9" → "1:1" — GPT Image 1.5 does not
support aspect_ratio "16:9". Supported: 1:1, 3:2, 2:3.
  - node_8 (gpt-image): resolution "2K" → removed — GPT Image 1.5 has no
resolution setting.
```

The structured result carries the same list as `adjustments`. The stored value is not what you sent, so do not send the original value again. Check each model's allowed values with [`list_models`](https://nodaro.ai/docs/mcp/tools/models-and-credits#list_models), or choose a model that supports what you need. `create_workflow` and `import_workflow` correct settings in the same way. A node set to several models at once is left as it is.

### Prompt pre and post text

Any AI node's `data` can carry `promptPrefix` and `promptSuffix`, text that Nodaro adds before and after the node's prompt when it runs. See [Prompt pre and post text](https://nodaro.ai/docs/concepts/prompt-pre-post-text).

### Studio productions

A workflow that holds a studio production keeps its scenes and results in `settings.studio`. A settings change that alters or drops `settings.studio` is refused. Copy it unchanged from `get_workflow_json`, or leave `settings` out. To change a production, use the [studio production tools](https://nodaro.ai/docs/mcp/tools/studio-productions).

## `delete_workflow`

Deletes a workflow from the mcp project. Deleting is permanent.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** A workflow id in the mcp project. |

**Returns:** a confirmation, or an error when the workflow is not in the mcp project.

## `export_workflow`

Exports any of your workflows, from any project, as a portable JSON bundle. This is the one workflow tool that is not limited to the mcp project.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** Any of your workflows. |
| `with_assets` | boolean | Default `false`. `true` also bundles the characters, objects and locations the workflow uses. |

**Returns:** the bundle as a JSON string. Pass the whole string to `import_workflow`.

| Mode | What the bundle holds | Use it for |
| --- | --- | --- |
| Template, `with_assets: false` | The graph, without asset-specific content | Sharing a workflow structure as a reusable template |
| Full, `with_assets: true` | The graph and every character, object and location it uses | Moving a complete production to another account or instance |

When a node uses media that another instance cannot download, such as a file on a self-hosted install's local storage, the bundle lists it under `portability.unreachableMedia`, with the node, the field and the URL. The bundle still imports, but those nodes do not run elsewhere until the media is uploaded again.

## `import_workflow`

Imports a bundle from `export_workflow` into the mcp project.

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

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_json` | string | **Required.** The whole JSON string from `export_workflow`. |

**Returns:** the new workflow's `id` and `name`, and an `importReport` that says which media was copied, which was left as it is, and which was skipped.

- **Media is copied.** Media on other hosts is copied to this instance where it can be reached, so the workflow runs from the copies. The limits are 25 files for the graph and 25 more for the bundled assets, with images up to 20 MB and video or audio up to 50 MB. Media on a private host that this instance cannot reach is left as it is and listed as `unreachable`.
- **Assets are re-created.** Bundled characters, objects, creatures and locations are created again in your account with new ids. Asset nodes and every `@` mention in the graph or the settings point to the new copies, and `assetIdMap` maps each old id to its new one.
- **Copies count against your storage.** The images of bundled assets are copied into your own storage. When your storage is full, `assetsSkipped` names the assets that were not created; the workflow still lands.

## `run_workflow`

Runs a workflow from the mcp project, exactly as a run in the editor.

**Permission:** `workflows:execute`. **Credits:** the credits of every node that runs, at the same prices as the editor.

| Parameter | Type | Notes |
| --- | --- | --- |
| `workflow_id` | string | **Required.** A workflow id in the mcp project. |
| `inputs` | object | Changes for this run, keyed by node id. A plain value, such as `"blue car"`, goes to the node's main input field. An object, such as `{ "prompt": "..." }`, sets named fields. |
| `client_request_id` | string | A retry token: 8 to 128 characters of letters, digits and `_ - . :`. Reuse it when you retry after a timeout, so the run is not started or charged twice. Use a new value for a new run. |

**Returns:** `executionId` and `name`. Follow the run with [`get_app_run`](https://nodaro.ai/docs/mcp/tools/gallery-and-assets#get_app_run), or explain a failure with [`diagnose_run`](https://nodaro.ai/docs/mcp/tools/jobs#diagnose_run). Clients with MCP Apps show the run's progress in a card.

## Frequently asked questions

### Can an assistant edit the workflows in my own projects?

No. The workflow tools edit and run only the workflows in the mcp project. To work on another workflow, the assistant exports it with export_workflow and imports a copy with import_workflow.

### How does an assistant learn the workflow format?

It calls start_workflow_editor first, which returns the workflow JSON shape, the wiring rules and the list of node types. Then it calls get_node_skill for each node type it wants to use.

### What happens if two sessions edit the same workflow?

Pass the version from get_workflow_json as expected_version, or send a delta with base_version. If the workflow changed in between, the write is refused and nothing is overwritten.

### What if a workflow asks a model for a setting it does not support?

Nodaro corrects it instead of failing. An unsupported aspect ratio, resolution or quality is changed to a supported value or removed, and the reply lists every change under adjustments.

### Does running a workflow through MCP cost more than in the editor?

No. run_workflow spends the same credits as a run in the editor. Building, reading and editing workflows is free.
