@controllerai/cli 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +13 -4
  2. package/dist/assistantHosts.js +234 -0
  3. package/dist/assistantHosts.js.map +1 -0
  4. package/dist/commands/agent.js +2 -0
  5. package/dist/commands/agent.js.map +1 -1
  6. package/dist/commands/agentSetup.js +627 -0
  7. package/dist/commands/agentSetup.js.map +1 -0
  8. package/dist/commands/connect.js +29 -26
  9. package/dist/commands/connect.js.map +1 -1
  10. package/dist/commands/connection.js +98 -13
  11. package/dist/commands/connection.js.map +1 -1
  12. package/dist/commands/data.js +26 -15
  13. package/dist/commands/data.js.map +1 -1
  14. package/dist/commands/docs.js +95 -0
  15. package/dist/commands/docs.js.map +1 -0
  16. package/dist/commands/doctor.js +357 -13
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/exec.js +284 -133
  19. package/dist/commands/exec.js.map +1 -1
  20. package/dist/commands/integration.js +170 -49
  21. package/dist/commands/integration.js.map +1 -1
  22. package/dist/commands/node.js +11 -287
  23. package/dist/commands/node.js.map +1 -1
  24. package/dist/commands/organize.js +182 -219
  25. package/dist/commands/organize.js.map +1 -1
  26. package/dist/commands/run.js +1 -1
  27. package/dist/commands/run.js.map +1 -1
  28. package/dist/commands/skills.js +2 -3
  29. package/dist/commands/skills.js.map +1 -1
  30. package/dist/commands/trigger.js +14 -8
  31. package/dist/commands/trigger.js.map +1 -1
  32. package/dist/commands/upgrade.js +69 -0
  33. package/dist/commands/upgrade.js.map +1 -0
  34. package/dist/commands/workflow.js +203 -61
  35. package/dist/commands/workflow.js.map +1 -1
  36. package/dist/index.js +9 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/nodeProps.js +1 -1
  39. package/dist/nodeProps.js.map +1 -1
  40. package/package.json +2 -2
  41. package/skills/controllerai-agents/SKILL.md +26 -18
  42. package/skills/controllerai-agents/references/instructions-and-versioning.md +2 -0
  43. package/skills/controllerai-ai-nodes/SKILL.md +9 -5
  44. package/skills/controllerai-ai-nodes/references/selection-and-testing.md +2 -0
  45. package/skills/controllerai-data/SKILL.md +17 -7
  46. package/skills/controllerai-data/references/data-rails.md +4 -2
  47. package/skills/controllerai-expressions/SKILL.md +17 -5
  48. package/skills/controllerai-expressions/references/dsl-and-recipes.md +5 -1
  49. package/skills/controllerai-flow-control/SKILL.md +11 -4
  50. package/skills/controllerai-flow-control/references/patterns.md +4 -0
  51. package/skills/controllerai-integration-actions/SKILL.md +20 -12
  52. package/skills/controllerai-node-config/SKILL.md +30 -9
  53. package/skills/controllerai-node-config/references/prop-and-readiness.md +9 -3
  54. package/skills/controllerai-runs/SKILL.md +20 -10
  55. package/skills/controllerai-runs/references/debugging.md +11 -7
  56. package/skills/controllerai-start/SKILL.md +36 -8
  57. package/skills/controllerai-start/references/mcp-tool-map.md +170 -0
  58. package/skills/controllerai-triggers/SKILL.md +13 -7
  59. package/skills/controllerai-triggers/references/lifecycle.md +5 -3
  60. package/skills/controllerai-workflows/SKILL.md +16 -10
  61. package/skills/controllerai-workflows/references/command-map.md +21 -6
  62. package/skills/manifest.json +79 -73
@@ -5,7 +5,7 @@ description: Define Controller AI custom data types and safely read, write, impo
5
5
 
6
6
  # Controller AI data
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
10
  Controller AI has two separate concerns:
11
11
 
@@ -52,7 +52,9 @@ cai schema create custom.customer \
52
52
 
53
53
  Creating the schema creates/synchronizes its collection. `cai data collection create` is only an alias for schema creation.
54
54
 
55
- `schema update --field` replaces the complete field list; it does not append — this is deliberate, so a subset CAN intentionally replace the whole schema. Read the current schema, preserve intended fields, and disclose any removals. The CLI warns about every field being dropped and echoes back the COMPLETE stored shape after the write — always read that echo and confirm it matches intent. Deleting a schema hides its collection and records and breaks dependent expressions — tell the user, and know it is recoverable (see below).
55
+ MCP: `cai data collection create` is merged into `schema_type_create`.
56
+
57
+ `schema update --field` replaces the complete field list; it does not append — this is deliberate, so a subset CAN intentionally replace the whole schema. Read the current schema, preserve intended fields, and disclose any removals. The transport response warns about every field being dropped and echoes back the COMPLETE stored shape after the write — always read that echo and confirm it matches intent. Deleting a schema hides its collection and records and breaks dependent expressions — tell the user, and know it is recoverable (see below).
56
58
 
57
59
  ## How schema changes affect stored records
58
60
 
@@ -93,13 +95,15 @@ cai data query --type custom.customer --env dev --json
93
95
  cai data create --type custom.customer --fields '{"email":"a@example.com","score":5}' --env dev --json
94
96
  ```
95
97
 
98
+ MCP: every data write requires explicit `env`; reads default to `dev` when `env` is omitted.
99
+
96
100
  Use `--env live` only when the user intends to inspect or mutate production state. Before a live write, say that published/triggered runs read this store.
97
101
 
98
102
  `data query --query` is plain-text search over serialized records and metadata, not a field predicate. Perform exact field filtering inside workflow expressions or inspect results explicitly.
99
103
 
100
104
  ## Delete records explicitly
101
105
 
102
- Record deletion is CLI/REST-only; no workflow data node exposes it. Delete one known record or an explicit set of IDs:
106
+ Record deletion is available only through the control surface; no workflow data node exposes it. Delete one known record or an explicit set of IDs:
103
107
 
104
108
  ```bash
105
109
  cai data delete <recordId> --type custom.customer --env dev --json
@@ -112,18 +116,22 @@ Delete every record in a collection only with explicit user intent; `--all` also
112
116
  cai data delete-many --type custom.customer --all --yes --env dev --json
113
117
  ```
114
118
 
115
- The default rail is development. Use `--env live` only for an intentional production deletion, then query that same rail to verify the result.
119
+ MCP: `data_record_delete_many` requires explicit `env: dev|live` and exactly one of `recordIds` or `all: true`; it has no `yes` parameter.
120
+
121
+ The CLI default rail is development. Targeted and `--all --yes` bulk deletions also support `--env live`; a live deletion immediately changes the data read by the published workflow, so use it only with explicit production intent and query that rail afterward.
116
122
 
117
123
  ## Import and promote
118
124
 
119
125
  Validate CSV before writing:
120
126
 
121
127
  ```bash
122
- cai data import --type custom.customer --file customers.csv --mode dryRun --json
123
- cai data import --type custom.customer --file customers.csv --mode commit --json
128
+ cai data import --type custom.customer --file customers.csv --mode dryRun --env dev --json
129
+ cai data import --type custom.customer --file customers.csv --mode commit --env dev --json
124
130
  ```
125
131
 
126
- The commit appends. Verify result counts and query the imported rows.
132
+ MCP: pass CSV text inline as `content` with explicit `env: dev|live` to `data_record_import_validate`, then use `data_record_import_commit` to write the validated content.
133
+
134
+ Both CLI modes support `--env live`: dry-run remains non-writing, while a live commit appends rows immediately visible to the published workflow. Verify result counts and query the imported rows on the same rail.
127
135
 
128
136
  To seed live from development:
129
137
 
@@ -133,6 +141,8 @@ cai data copy-to-live --type custom.customer --json
133
141
  cai data collections --env live --json
134
142
  ```
135
143
 
144
+ MCP: call `data_copy_to_live` with the explicit acknowledgement `env: live`.
145
+
136
146
  The live schema must exist through a publish before copying. Treat copy-to-live as a production mutation and report counts/results.
137
147
 
138
148
  ## Workflow expressions
@@ -10,6 +10,8 @@
10
10
 
11
11
  Use `cai data copy-to-live --type <custom.type>` only for an intentional data promotion.
12
12
 
13
+ MCP: `data_copy_to_live` requires the explicit acknowledgement `env: live`.
14
+
13
15
  ## Safe schema update
14
16
 
15
17
  1. `cai schema get <type> --json`
@@ -25,9 +27,9 @@ Field IDs are contracts. Prefer keeping an ID stable and changing only its displ
25
27
  ## Destructive operations
26
28
 
27
29
  - `data delete` soft-deletes one record.
28
- - `data delete-many --all --yes` is broad, REST-backed, and DEVELOPMENT-ONLY — `--env live` is refused (`DEV_ONLY_ROUTE`). The only live write paths are single-record `data create/update/delete --env live` and `copy-to-live`.
30
+ - `data delete-many --all --yes` is broad and REST-backed on either rail. With `--env live`, the deletion immediately changes what the published workflow reads.
29
31
  - `schema delete` removes access to the whole collection and breaks its type references.
30
- - CSV `--mode commit` appends rows.
32
+ - CSV `--mode commit` appends rows on the selected rail; a live commit is immediately visible to the published workflow. `--mode dryRun` writes nothing on either rail.
31
33
  - `copy-to-live` changes production data.
32
34
 
33
35
  Resolve exact workflow, environment, type, and record targets before these actions. Do not use a broad deletion to repair a schema mistake.
@@ -5,7 +5,7 @@ description: Author, validate, persist, and debug Controller AI expressions for
5
5
 
6
6
  # Controller AI expressions
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
10
  Controller AI uses a restricted JavaScript-like authoring language that is compiled into the workflow engine's expression AST. It is not general JavaScript. Discover the real scope and compile before every write.
11
11
 
@@ -24,7 +24,7 @@ An empty input is not "nothing" — it evaluates to the type's empty form: empty
24
24
  - **A filter comparing against an empty value still filters — and matches NO records.** This is deliberate (fail-closed; matching everything by accident would be worse). If "empty should mean skip this filter", opt that constraint into ignore-empty mode explicitly (`ignoreEmptyConstraints`, see [references/dsl-and-recipes.md](references/dsl-and-recipes.md)).
25
25
  - **An optional TEXT input left empty arrives as `""`**, so an `equals` constraint against it matches nothing — the classic symptom is "search finds zero results only when the optional filter is blank", which then cascades (e.g. a create-if-missing step makes duplicates).
26
26
 
27
- When a run unexpectedly returns zero results, check the resolved configs for empty comparison values first (`cai exec ports`).
27
+ When a run unexpectedly returns zero results, check the resolved configs for empty comparison values first (`cai exec node <nodeExecutionId> --full`).
28
28
 
29
29
  ## Required write loop
30
30
 
@@ -61,9 +61,11 @@ When compilation reports an unknown field, copy a typeable display-derived acces
61
61
  Get the current operation catalog when needed:
62
62
 
63
63
  ```bash
64
- cai expr ops --type <text|number|date|list|boolean|file|custom> --json
64
+ cai expr ops --workflow <workflowId> --type <text|number|date|list|boolean|file|custom> --json
65
65
  ```
66
66
 
67
+ The catalog is workflow-scoped because it is read from expression context. On CLI, an existing `cai use` or `CAI_WORKFLOW` selection can replace the explicit flag; MCP `expr_operation_list` always requires `workflowId`.
68
+
67
69
  Keep the program to optional `const` declarations followed by one final expression. Do not use loops, assignments, `new`, regular expressions, optional chaining, arbitrary library methods, or object construction unless the current compiler catalog explicitly supports them.
68
70
 
69
71
  Date values are ISO-8601 strings on the wire (`"2026-06-05"` or `"2026-06-05T12:30:00Z"`). A `date`-typed flow input or field is used directly with date operations; only `text` values need `.toDate()` first. For epoch text, pass the unit literal explicitly: `flow.timestamp.toDate("epoch_seconds")` or `flow.timestamp.toDate("epoch_millis")`. The ops table renders that argument generically; never guess the unit from digit count.
@@ -78,14 +80,20 @@ For a node prop, prefer:
78
80
  cai expr set <nodeId> --prop <propName> --js '<expression>' --json
79
81
  ```
80
82
 
81
- For multiline expressions or shell-sensitive templates, put the exact source in a UTF-8 file and use `--js-file <path>`. Use `--js-file -` to read stdin. It is mutually exclusive with inline `--js` and is available on `expr validate/set`, `node set/only-when`, and `branch add/update`.
83
+ MCP: use `node_prop_set` with `js`; it merges `cai expr set` with `cai node set`.
84
+
85
+ For multiline expressions or shell-sensitive templates on CLI, put the exact source in a UTF-8 file and use `--js-file <path>`. Use `--js-file -` to read stdin. It is mutually exclusive with inline `--js` and is available on `expr validate/set`, `node set/only-when`, and `branch add/update`.
82
86
 
83
87
  ```bash
84
88
  cai expr set <nodeId> --prop <propName> --js-file expression.js --json
85
89
  ```
86
90
 
91
+ MCP: pass the file contents inline as `js`; the hosted process does not read the local path or stdin.
92
+
87
93
  This fetches target metadata, auto-enables a catalog-only optional target when needed, compiles before writing the value, persists to the correct channel, and verifies read-back. If validation or the value write then fails, the prop stays enabled; repair with `cai node disable-prop <nodeId> --prop <propName>`.
88
94
 
95
+ MCP: repair with `node_optional_prop_set` and `enabled: false`.
96
+
89
97
  Array channels are not interchangeable. On a value-channel `SHORT_TEXT_ARRAY`, a scalar expression replaces the whole array with one dynamic element; it does not append. List-typed expressions on value-channel array props are rejected. Use `cai node set <nodeId> --prop <propName> --value '["a","b"]'` for a static list, or use a list-typed expression only where prop metadata exposes whole-array expression mode.
90
98
 
91
99
  For a side-effect-free check:
@@ -110,13 +118,17 @@ cai expr decompile <nodeId> --prop <propName> --json
110
118
  cai run node <nodeId> --inputs <values.json> --json
111
119
  ```
112
120
 
121
+ MCP: `run_node` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
122
+
113
123
  Use `run node` to isolate the destination's own configuration. It never executes wired upstream nodes. If the expression consumes `inputs.<name>`, also run its containing flow:
114
124
 
115
125
  ```bash
116
126
  cai run flow <flowId> --inputs <values.json> --json
117
127
  ```
118
128
 
119
- Inspect `runScope` and `resolvedConfigs` in the run result. A null or missing dynamic config is an expression failure, not success; a partially empty value is equally suspect. Only the full flow run proves an upstream-derived value. Use `cai exec ports <nodeExecutionId> --json` to compare inputs, resolved configs, and outputs.
129
+ MCP: `run_flow` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
130
+
131
+ Inspect `runScope` and `resolvedConfigs` in the run result. A null or missing dynamic config is an expression failure, not success; a partially empty value is equally suspect. Only the full flow run proves an upstream-derived value. Use `cai exec node <nodeExecutionId> --full --json` to inspect the final status, resolved configs, and untruncated output.
120
132
 
121
133
  ## Hard rules
122
134
 
@@ -27,6 +27,8 @@ cai expr validate <httpNodeId> --prop <jsonBodyProp> --js-file body-expression.j
27
27
  cai expr set <httpNodeId> --prop <jsonBodyProp> --js-file body-expression.js --json
28
28
  ```
29
29
 
30
+ MCP: pass the file contents inline as `js`; the set call uses `node_prop_set`.
31
+
30
32
  ## Same-type fallback
31
33
 
32
34
  ```js
@@ -115,6 +117,8 @@ Confirm the exact binding and field path in context.
115
117
  5. `cai expr decompile ...`
116
118
  6. `cai run node ... --json` for isolated destination configuration
117
119
  7. `cai run flow <flowId> ... --json` when the expression consumes a wired upstream input
118
- 8. `cai exec ports <nodeExecutionId> --json`
120
+ 8. `cai exec node <nodeExecutionId> --full --json`
121
+
122
+ MCP: step 4 uses `node_prop_set`; pass expression source and run inputs inline, and set `waitSeconds` on `run_node` or `run_flow` from 0 through 120.
119
123
 
120
124
  If compilation succeeds but runtime is null or partially empty, inspect `runScope`, the actual input value, and `resolvedConfigs`; do not keep rewriting syntax blindly. A node-only run cannot prove an `inputs.<name>` binding because it does not execute upstream nodes.
@@ -5,7 +5,7 @@ description: Design and configure Controller AI execution paths using only-when
5
5
 
6
6
  # Controller AI flow control
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
10
  Choose the primitive from the intended execution semantics before adding nodes.
11
11
 
@@ -73,7 +73,7 @@ For If/Else, order is behavior:
73
73
  cai branch reorder <ifElseNodeId> --order <conditionId1,conditionId2> --json
74
74
  ```
75
75
 
76
- List every condition branch exactly once and omit Else; the CLI keeps Else last. Router routes cannot be reordered because every match runs.
76
+ List every condition branch exactly once and omit Else; the operation keeps Else last. Router routes cannot be reordered because every match runs.
77
77
 
78
78
  After edits, run `cai branch list` again. Treat its warnings about missing conditions or unwired paths as blockers: an unwired selected path can end with an apparently green execution.
79
79
 
@@ -97,9 +97,12 @@ Use repeatable `--item-field <id:type[:display]>` only when creating a new `cust
97
97
  Copy `--source-output` from the selected node's exact `outputs[].id`. It is an opaque ID, not `displayName`, and there is no first-output default. This matters for Router, If/Else, and error outputs as well as ordinary action nodes.
98
98
 
99
99
  - If the source's whole output is the list, omit both `--list-field` and `--list-js`.
100
- - If the list is nested in the source payload, use `--list-field` with the dot-delimited path below `.data`; the CLI derives the not-yet-created loop input binding deterministically.
100
+ - If the list is nested in the source payload, use `--list-field` with the dot-delimited path below `.data`; the operation derives the not-yet-created loop input binding deterministically.
101
101
  - Use `--list-js` only for an advanced exact expression. For multiline or shell-sensitive source, use `--js-file <path|->` instead. Both are mutually exclusive with `--list-field` and with each other; copy the wrapper/binding shape from expression context rather than guessing it.
102
- - The runtime cap defaults to 500 items and accepts 1 through 10000. Set `--max-items` explicitly when the product requirement differs. The CLI creates the core scaffold first, then materializes and verifies this optional prop. The cap is all-or-nothing at runtime: a list larger than the cap throws and NOTHING iterates — there is no partial truncation.
102
+
103
+ MCP: pass expression source inline as `listJs` to `flow_for_each_scaffold`; the server cannot read a local `--js-file` path.
104
+
105
+ - The runtime cap defaults to 500 items and accepts 1 through 10000. Set `--max-items` explicitly when the product requirement differs. The scaffold operation creates the core graph first, then materializes and verifies this optional prop. The cap is all-or-nothing at runtime: a list larger than the cap throws and NOTHING iterates — there is no partial truncation.
103
106
 
104
107
  Changing an existing loop: update its loop-node props directly:
105
108
 
@@ -108,6 +111,8 @@ cai node set <loopNodeId> --prop maxItems --value <n> --json
108
111
  cai node set <loopNodeId> --prop continueOnIterationError --value true --json
109
112
  ```
110
113
 
114
+ MCP: use `node_prop_set` for both writes.
115
+
111
116
  This is not `cai node continue-on-error`, which configures the node-level Error output — a different feature.
112
117
 
113
118
  Read every returned warning. A list/item type mismatch means the scaffold is not verified even though it was created. Follow the returned `nextSteps` in order.
@@ -127,6 +132,8 @@ cai node set-flow <runFlowNodeId> --flow <calledFlowId> --json
127
132
  cai node props <runFlowNodeId> --json
128
133
  ```
129
134
 
135
+ MCP: `cai node set-flow` maps to `node_subflow_set`.
136
+
130
137
  Setting the target flow creates mapping props from the target's current inputs. If those inputs later change, run `set-flow` again and reconfigure mappings.
131
138
 
132
139
  When paths converge, inspect the concrete graph and execution behavior. Do not assume wiring two paths to one action creates a barrier or waits for both. If the requirement is a true join, discover a join-capable component and verify it with representative branch timing.
@@ -40,6 +40,8 @@ One order may take all three routes. If that is not acceptable, use If/Else.
40
40
 
41
41
  Use `cai flow for-each` to create the item flow, typed item input, loop node, and list wiring atomically. First run `cai node get <sourceNodeId> --json`, choose the intended `outputs[]` entry, and pass its exact opaque `id` as `--source-output`; never pass its label or assume the first output. Omit list-selection flags when the whole selected output payload is a list; use `--list-field <nested.path>` for a list below `.data`; reserve `--list-js` for an exact advanced expression or `--js-file <path|->` for that expression in a UTF-8 file/stdin. The three selection forms are mutually exclusive.
42
42
 
43
+ MCP: call `flow_for_each_scaffold` and pass expression source inline as `listJs`.
44
+
43
45
  The runtime limit defaults to 500 items and supports 1 through 10000. Use `--max-items` when the intended bound differs, then verify the returned read-back. Put meaningful work inside the generated body flow and declare body outputs before consuming aggregate results.
44
46
 
45
47
  Decide explicitly whether one child-flow failure should stop the sequential loop. Use `--continue-on-error` only when partial completion is acceptable and downstream logic handles failed iteration records. It does not recover a list or mapping expression that fails before an iteration starts.
@@ -52,6 +54,8 @@ Continue-on-error is for steps whose failure must not block the main path — no
52
54
  cai node continue-on-error <nodeId> --enable --json
53
55
  ```
54
56
 
57
+ MCP: call `node_continue_on_error_set` with `enabled: true` or `enabled: false`.
58
+
55
59
  Wiring the Error output is OPTIONAL — add it when a failure needs explicit handling, not as a precondition:
56
60
 
57
61
  ```bash
@@ -5,9 +5,9 @@ description: Discover, connect, attach, update, and verify ready integration act
5
5
 
6
6
  # Controller AI integration actions
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
- Ready integration actions give a hosted agent one app operation without first building a workflow. Use only the `cai` commands below; do not call Controller AI REST or MCP routes directly.
10
+ Ready integration actions give a hosted agent one app operation without first building a workflow. Use the canonical operations below through the selected transport; do not call Controller AI REST routes directly.
11
11
 
12
12
  ## Choose direct action or workflow
13
13
 
@@ -19,10 +19,11 @@ Use a workflow tool instead when the capability needs multiple operations, trans
19
19
 
20
20
  ```bash
21
21
  cai integration search "<app or capability>" --json
22
- cai integration actions <integrationSlug> --search "<operation>" --json
22
+ cai integration actions "<operation>" --integration <integrationSlug> --json
23
+ cai integration action --integration <integrationSlug> --key <actionKey> --json
23
24
  ```
24
25
 
25
- Preserve the returned integration `slug` and action `key` exactly. Never derive either from a display label. Continue with `--after <nextCursor>` when pagination reports more results.
26
+ Preserve each returned `nodeSlug` and `key` pair exactly, then inspect that action's static props before using it. Never derive either identifier from a display label. Narrow the query or raise `--limit` when more matches exist.
26
27
 
27
28
  ## Select a connection
28
29
 
@@ -30,25 +31,28 @@ Preserve the returned integration `slug` and action `key` exactly. Never derive
30
31
  cai connection list --integration <integrationSlug> --json
31
32
  ```
32
33
 
33
- Use an active connection whose `nodeSlug` exactly matches the integration. If none exists:
34
+ Use an active connection whose `integration` exactly matches the integration slug. If none exists:
34
35
 
35
36
  ```bash
36
37
  cai connection connect <integrationSlug>
37
38
  ```
38
39
 
39
- The browser handoff keeps provider credentials out of the agent context. Re-list connections after the user finishes, then attach the action.
40
+ MCP: call `connection_connect_url`, show its `url` as a markdown link, ask the user to finish, then confirm with `connection_list` using its `integration`; it has no `open` or `wait` parameter.
40
41
 
41
- A missing connection is never a reason to substitute `registry_http-http-request` for a catalog component. For a workflow node, add the real component and leave it unconnected; `missingConnection: true` is a valid handoff state. For a direct action, preserve the selected integration and action and stop at the connection handoff. Give the user `cai connection connect <slug>`. A raw endpoint mentioned by the user is background context, not an instruction to hand-roll the call.
42
+ The connection handoff keeps provider credentials out of the agent context. The CLI may open the URL; MCP returns it. Re-list connections after the user finishes, then attach the action.
43
+
44
+ Rename or change the default with `cai connection update <id> [--name "<displayName>"] [--default|--no-default]` (MCP: `connection_update`); delete only intentionally with `cai connection delete <id> --yes` (MCP: `connection_delete`).
45
+ Deleting a connection immediately removes authorization from bound nodes and agent tools.
46
+
47
+ A missing connection is never a reason to substitute `registry_http-http-request` for a catalog component. For a workflow node, add the real component and leave it unconnected; `missingConnection: true` is a valid handoff state. For a direct action, preserve the selected integration and action and stop at the connection handoff. Give the user the returned connection URL; on CLI, `cai connection connect <slug>` obtains it. A raw endpoint mentioned by the user is background context, not an instruction to hand-roll the call.
42
48
 
43
49
  ## Decide approval before attaching
44
50
 
45
- The product default is to run without per-call approval. Do not accept that default mechanically. Inspect the action name, description, pricing, and intended use, then decide:
51
+ Attached actions run without a human approval step unless `requireConfirmation` is `true`. When attaching an action that sends, posts, spends, or deletes, choose `true` or explicitly tell the user that it will run unattended. Mention the confirmation choice in the report to the user.
46
52
 
47
- - Require confirmation for deletion, purchases or spend, external communications, permission changes, irreversible writes, or an ambiguous destination.
53
+ - Prefer confirmation for permission changes, irreversible writes, or an ambiguous destination.
48
54
  - Usually omit confirmation for read-only retrieval and low-risk, reversible operations the user clearly asked the agent to perform autonomously.
49
55
 
50
- Tell the user which policy was selected and why when it has a meaningful consequence.
51
-
52
56
  ```bash
53
57
  cai agent add-action <agentId> \
54
58
  --integration <integrationSlug> \
@@ -59,7 +63,7 @@ cai agent add-action <agentId> \
59
63
  --json
60
64
  ```
61
65
 
62
- Omit `--require-confirmation` only after making the decision; the CLI still sends an explicit `false`. Do not attach the same action twice.
66
+ MCP: call `agent_tool_action_add`; `requireConfirmation` is optional and defaults to `false`. On CLI, `--require-confirmation` selects `true` and omission preserves the `false` default. Do not attach the same action twice.
63
67
 
64
68
  Read the saved grant back:
65
69
 
@@ -77,6 +81,8 @@ cai agent update-tool <agentId> --tool <toolId> --require-confirmation --json
77
81
  cai agent update-tool <agentId> --tool <toolId> --no-confirmation --json
78
82
  ```
79
83
 
84
+ MCP: call `agent_tool_update`; use `connectionId` and `requireConfirmation: true` or `requireConfirmation: false`.
85
+
80
86
  `--connection` can redirect the published action immediately because authorization is live-bound. Description and confirmation-policy edits remain draft changes until the agent is published.
81
87
 
82
88
  ## Verify through the hosted agent
@@ -88,6 +94,8 @@ cai agent test <agentId> --draft --message "<request>" --json
88
94
  cai agent conversation history <conversationId> --json
89
95
  ```
90
96
 
97
+ MCP: call `agent_test` with `rail: draft` and `waitSeconds`.
98
+
91
99
  A direct action runs inline and does not create a workflow execution ID. Evidence is the persisted conversation, its direct-action tool/run events, the returned result, and any observed external side effect. Never invent a workflow execution ID for it.
92
100
 
93
101
  If confirmation is required, inspect the pending action and exact arguments before approving or denying its request. A successful assistant reply alone does not prove the intended action ran.
@@ -5,7 +5,7 @@ description: Discover, initialize, configure, connect, and verify Controller AI
5
5
 
6
6
  # Controller AI node configuration
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
10
  A node is ready only after its component, connection, dependency-ordered props, wiring, and output type are valid. Treat configuration as a state machine, not a bag of property writes.
11
11
 
@@ -14,15 +14,15 @@ A node is ready only after its component, connection, dependency-ordered props,
14
14
  ### 1. Find an exact component
15
15
 
16
16
  ```bash
17
- cai node find "<capability>" --json
18
- cai node component --node <nodeSlug> --key <nodeKey> --json
17
+ cai integration actions "<capability>" --json
18
+ cai integration action --integration <nodeSlug> --key <nodeKey> --json
19
19
  ```
20
20
 
21
- Use the returned `nodeSlug` and full `nodeKey`. Do not infer a component key from its display name. If discovery is broad, narrow it with:
21
+ Use the returned `nodeSlug` and full `key`. Do not infer a component key from its display name. If discovery is broad, narrow it with:
22
22
 
23
23
  ```bash
24
- cai node search "<integration>" --actions --json
25
- cai node components "<action>" --node <nodeSlug> --json
24
+ cai integration search "<integration>" --actions --json
25
+ cai integration actions "<action>" --integration <nodeSlug> --json
26
26
  ```
27
27
 
28
28
  Inspect static prop metadata before creating the node. `required`, `remoteOptions`, and `reloadProps` determine configuration order.
@@ -35,12 +35,19 @@ If the component requires auth:
35
35
  cai connection list --node <nodeSlug> --json
36
36
  ```
37
37
 
38
- - One active connection: use its exact `connectionId`.
38
+ - One active connection: use its exact `id` as the `connectionId`.
39
39
  - Several: use an explicit user preference; otherwise ask which account.
40
- - None: add the real component without `--connection`; `missingConnection: true` is a valid handoff state. Get the link with `cai connection connect <nodeSlug> --no-open` and share it with the user right away — do not start with `--wait`, which blocks until they finish and delays sharing the link. After they confirm, run `cai connection list --integration <nodeSlug> --json` and bind the new ID with `cai node set-connection <nodeId> --connection <connectionId>`.
40
+ - None: add the real component without `--connection`; `missingConnection: true` is a valid handoff state. On CLI, get the link with `cai connection connect <nodeSlug> --no-open` and share it right away; do not block on `--wait` before sharing.
41
+
42
+ MCP: call `connection_connect_url` with `nodeSlug`, show its `url` as a markdown link, ask the user to finish, then confirm with `connection_list` using its `integration`.
43
+
44
+ After they confirm, run `cai connection list --integration <nodeSlug> --json` and bind the new ID with `cai node set-connection <nodeId> --connection <connectionId>`.
41
45
 
42
46
  Never substitute a connection from a similar slug.
43
47
 
48
+ Rename or change the default with `cai connection update <id> [--name "<displayName>"] [--default|--no-default]` (MCP: `connection_update`); delete only intentionally with `cai connection delete <id> --yes` (MCP: `connection_delete`).
49
+ Deleting a connection immediately removes authorization from bound nodes and agent tools.
50
+
44
51
  A missing connection is never a reason to substitute `registry_http-http-request` for a catalog component. A raw endpoint mentioned by the user is background context, not an instruction to hand-roll the call.
45
52
 
46
53
  ### 3. Initialize once
@@ -56,6 +63,8 @@ cai node init \
56
63
  --json
57
64
  ```
58
65
 
66
+ MCP: use `node_add`; `cai node init` is the CLI alias of `cai node add`.
67
+
59
68
  Omit flags that do not apply. `--after` creates the ordinary main/error wire at creation. Use it when later props need upstream data. Initialization also accepts `--props`, but use it only for static, non-option values already present in the inspected component metadata. Never inline a `remoteOptions` value, a reload selector and its dependents, or a prop that has not materialized yet; initialize first and set those sequentially. Use `--enable-prop <name...>` only for optional props confirmed by component metadata.
60
69
 
61
70
  Capture the returned `nodeId`; do not rediscover it by name.
@@ -91,6 +100,8 @@ Static value:
91
100
  cai node set <nodeId> --prop <exactName> --value '<literal-or-json>' --json
92
101
  ```
93
102
 
103
+ MCP: use `node_prop_set` with `value`; it also handles expression writes through `js`.
104
+
94
105
  Optional prop:
95
106
 
96
107
  ```bash
@@ -99,8 +110,12 @@ cai node set <nodeId> --prop <exactName> --value '<literal-or-json>' --json
99
110
  # or: cai expr set <nodeId> --prop <exactName> --js '<expression>' --json
100
111
  ```
101
112
 
113
+ MCP: `cai expr set` is the `js` form of `node_prop_set`.
114
+
102
115
  `node set` and `expr set` auto-enable a catalog-only optional prop, refresh its metadata, then write. Do not run a separate enable step first. If validation or the later write fails, the prop stays enabled; repair with `cai node disable-prop <nodeId> --prop <exactName>` and re-read props. This is also the repair for the Update-data wipe footgun: that action writes every enabled field, so disable any accidentally enabled field before running it.
103
116
 
117
+ MCP: use `node_optional_prop_set` with `enabled: false` to disable or `enabled: true` to enable.
118
+
104
119
  Remote or dynamic option:
105
120
 
106
121
  ```bash
@@ -114,7 +129,7 @@ cai node set <nodeId> \
114
129
 
115
130
  `node options` also supports `--prev-context '<context JSON>'` from the preceding page and repeatable `--for '<earlierProp>=<value>'` overrides for read-only hypothetical resolution; JSON literals are accepted and bare text stays a string. If options are `blocked_upstream`, both `node options` and `node set` name the blocking prop and print the exact `cai node set` command to run first.
116
131
 
117
- For an ordinary remote option, preserve both fields from the same returned option. The label is not cosmetic: the CLI uses it to search providers that do not index opaque IDs, then verifies that the returned value still matches before writing. For a multi-select, pass a JSON array of returned values and one `--label` argument per value, in the same order. The CLI supplies the persisted label shape, chooses the correct expression storage channel, and verifies read-back.
132
+ For an ordinary remote option, preserve both fields from the same returned option. The label is not cosmetic: it is used to search providers that do not index opaque IDs, then the returned value is verified before writing. For a multi-select, pass a JSON array of returned values and one `--label` argument per value, in the same order. The write supplies the persisted label shape, chooses the correct expression storage channel, and verifies read-back.
118
133
 
119
134
  When an earlier selector makes the prop `dynamic_upstream`, no option list exists. Use a known exact ID or an expression:
120
135
 
@@ -146,14 +161,20 @@ cai node status <nodeId> --json
146
161
  cai run node <nodeId> --inputs <values.json> --json
147
162
  ```
148
163
 
164
+ MCP: `run_node` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
165
+
149
166
  If the node has a wired input or consumes `inputs.<name>`, the node test is only an isolated configuration check. Run `cai run flow <flowId> --inputs <values.json> --json` before declaring its upstream expressions verified.
150
167
 
168
+ MCP: `run_flow` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
169
+
151
170
  If a dynamic provider action cannot be run but its response is documented, declare an unverified output contract:
152
171
 
153
172
  ```bash
154
173
  cai node declare-output <nodeId> --sample-file provider-response.json --json
155
174
  ```
156
175
 
176
+ MCP: call `node_output_type_declare` with the parsed provider response in `sample`; the server cannot read `provider-response.json`.
177
+
157
178
  The sample must be a JSON object or a non-empty JSON array of provider items. Re-read status and expression context afterward; the first real completed run verifies the declaration.
158
179
 
159
180
  Read [references/prop-and-readiness.md](references/prop-and-readiness.md) when a prop is dynamic, option-backed, expression-capable, or unexpectedly absent.
@@ -13,7 +13,7 @@ The JSON response reports:
13
13
  - `readyForExpressions`: connection and required/reload props are complete. The source still must be wired before its binding appears in expression context.
14
14
  - `readyForRun`: connection and required/reload props are complete; running may be the step that discovers a concrete output type.
15
15
  - `readyForDownstreamExpressions`: the node is runnable and its actual process output type is concrete enough for downstream field bindings.
16
- - `next`: the CLI's exact next diagnostic command.
16
+ - `next`: the canonical next diagnostic command.
17
17
 
18
18
  Follow `next`, then read status again. Do not treat `readyForRun` as proof that downstream fields are typed; require `readyForDownstreamExpressions` for that.
19
19
 
@@ -26,6 +26,8 @@ cai node set-connection <nodeId> --connection <connectionId> --json
26
26
  cai node status <nodeId> --json
27
27
  ```
28
28
 
29
+ MCP: replace `cai connection connect` with `connection_connect_url { nodeSlug }`; the other calls map directly.
30
+
29
31
  ## Prop channels
30
32
 
31
33
  Use `cai node set`; it selects the persisted shape from live metadata.
@@ -36,6 +38,8 @@ Use `cai node set`; it selects the persisted shape from live metadata.
36
38
  | Dynamic text, JSON text, or custom data | `--js` | `valueJs` |
37
39
  | Dynamic non-text prop with expression mode | `--js` | `expressionValueJs` |
38
40
 
41
+ MCP: both `cai node set` and `cai expr set` use `node_prop_set`; pass exactly one of `value`, `js`, or `rawExpressionJson`.
42
+
39
43
  Do not force a channel with internal fields. `cai node set` and `cai expr set` compile first and verify the actual channel after writing.
40
44
 
41
45
  ## Option-backed props
@@ -55,7 +59,7 @@ cai node options <nodeId> --prop <name> --query "<specific search>" --json
55
59
  cai node set <nodeId> --prop <name> --value '<option.value>' --label '<option.label>' --json
56
60
  ```
57
61
 
58
- Pass the value and label from the same live option. Remote providers often search labels rather than opaque values, so omitting `--label` can make a valid copied ID impossible to re-verify. For multi-select, pass a JSON array of returned values plus one `--label` argument per value in matching order. The CLI constructs the required array of `{value,label}` records for read-back/UI compatibility.
62
+ Pass the value and label from the same live option. Remote providers often search labels rather than opaque values, so omitting `--label` can make a valid copied ID impossible to re-verify. For multi-select, pass a JSON array of returned values plus one `--label` argument per value in matching order. The write constructs the required array of `{value,label}` records for read-back/UI compatibility.
59
63
 
60
64
  Continue a provider page with the opaque context printed by the previous call:
61
65
 
@@ -103,4 +107,6 @@ An unresolved output blocks trustworthy downstream field expressions. Resolve it
103
107
 
104
108
  After the run, read `cai node status` and `cai expr context` again. Do not infer fields from an example response alone if the platform did not adopt a concrete type.
105
109
 
106
- `cai run node` and `cai run flow` pass the exact completed node-execution ID back to the backend. The backend verifies ownership, workflow, node, component snapshot, and terminal status, then derives the persisted output shape; callers never supply the type name. Adoption updates only that non-static node, so separate instances of generic components such as HTTP can learn different schemas. Inspect `outputTypeAdoption`/`outputTypeAdoptions` in the run result. If it reports `no_observed_output`, use a representative input that returns data and rerun. If it reports `error`, stop and surface that error rather than inventing a schema.
110
+ Completed node and flow runs pass the exact node-execution ID back for ownership, workflow, node, component-snapshot, and terminal-status checks before deriving the persisted output shape; callers never supply the type name. Adoption updates only that non-static node, so separate instances of generic components such as HTTP can learn different schemas. Inspect `outputTypeAdoption`/`outputTypeAdoptions` in the run result. If it reports `no_observed_output`, use a representative input that returns data and rerun. If it reports `error`, stop and surface that error rather than inventing a schema.
111
+
112
+ MCP: `run_node` and `run_flow` take `inputs` inline and `waitSeconds` from 0 through 120.
@@ -5,7 +5,7 @@ description: Run and debug Controller AI nodes on development and flows on devel
5
5
 
6
6
  # Controller AI runs
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
9
 
10
10
  Think "real run", not "simulation". `run node` always uses development; `run flow` defaults to development and can target the published live version. Both rails execute real integration actions (messages send, records change, provider usage is spent); development isolation covers the data store only. Running is a required part of building — one successful run is how a dynamic node's output type gets resolved for the next step — so mitigate risk before running.
11
11
 
@@ -23,6 +23,8 @@ If the user declines running the action, accept it. Then keep the build honest:
23
23
  cai node declare-output <nodeId> --sample-file shape.json
24
24
  ```
25
25
 
26
+ MCP: call `node_output_type_declare` with parsed JSON in `sample`; the server cannot read `shape.json`.
27
+
26
28
  — where `shape.json` is a representative response object from the provider's API reference. The contract is marked `declared (unverified)`; the first real completed run verifies and upgrades it automatically. State clearly that it is unverified until then, and make the first live run the explicit verification step. Never silently skip the question and never present an unrun action as verified.
27
29
 
28
30
  ## First live run is part of development
@@ -33,6 +35,8 @@ After publishing, run the published version directly under supervision:
33
35
  cai run flow <flowId> --inputs values.json --target live --confirm-live --json
34
36
  ```
35
37
 
38
+ MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_flow`.
39
+
36
40
  This command fires external actions and spends usage. For risky sends, build the safe-audience harness: branch on the `isLiveVersion` data source with If/Else — the false branch targets the developer (own email/channel), the true branch targets the real audience. Use this direct live run for explicit verification; do not wait for a real trigger event.
37
41
 
38
42
  ## Prepare exact run inputs
@@ -42,7 +46,7 @@ cai run inputs <nodeId> --json
42
46
  cai run inputs <flowId> --flow --json
43
47
  ```
44
48
 
45
- Use returned opaque input IDs. Flow mode lists EVERY declared input with a `used` flag: supply the used ones (an unsupplied used input falls back to its saved test value), while values keyed to unused inputs are accepted and ignored. A compact input file can be a flat map:
49
+ Use returned opaque input IDs. Flow mode lists EVERY declared input with a `used` flag: supply the used ones (an unsupplied used input falls back to its saved test value), while values keyed to unused inputs are accepted and ignored. The input object can be a flat map; the CLI may load it from a file:
46
50
 
47
51
  ```json
48
52
  {
@@ -65,9 +69,11 @@ cai run node <nodeId> --inputs values.json --json
65
69
  cai run flow <flowId> --inputs values.json --json
66
70
  ```
67
71
 
72
+ MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_node` or `run_flow`.
73
+
68
74
  `run node` is deliberately isolated: it does not execute wired upstream nodes. Read its `runScope`. If `endToEndValidationRequired` is true, values derived from upstream can be empty even when the selected node is green; do not accept that run as expression proof. `run flow` is the end-to-end check that executes upstream wiring.
69
75
 
70
- The CLI waits for a terminal execution state. Capture `workflowExecutionId` and `nodeExecutionId` from the result.
76
+ The CLI waits for a terminal execution state by default. MCP polling is bounded by `waitSeconds` and may return an unfinished execution ID. Capture `workflowExecutionId` and `nodeExecutionId` from the result.
71
77
 
72
78
  For every node test, inspect:
73
79
 
@@ -75,7 +81,7 @@ For every node test, inspect:
75
81
  - `skipReason`
76
82
  - `runScope`, especially `upstreamNodesExecuted` and `endToEndValidationRequired`
77
83
  - `resolvedConfigs`
78
- - `resolvedConfigs[].resolutionWarnings`: trust every structured entry; `[]` is authoritatively clean. Runs also surface entries on stderr, so read stderr even when the execution completed.
84
+ - `resolvedConfigs[].resolutionWarnings`: trust every structured entry; `[]` is authoritatively clean. Also read any transport warnings; CLI runs may mirror them on stderr.
79
85
  - `outputTypeAdoption`: the server verifies the exact completed `nodeExecutionId`, derives its persisted output shape, and updates only that non-static node. `adopted` or `already_typed` lets the next `node status` converge; `no_observed_output` means the representative run returned no reusable shape. `adoptedNodeIds` must be empty or contain only the tested node; stop if it names a sibling.
80
86
  - output shape and values
81
87
 
@@ -84,14 +90,16 @@ A dynamic prop with a null/empty resolved config is a failure even when status i
84
90
  ## Debug from the execution tree
85
91
 
86
92
  ```bash
87
- cai exec tree <workflowExecutionId> --json
93
+ cai exec tree <workflowExecutionId> --limit 50 --json
88
94
  cai exec get <workflowExecutionId> --json
89
95
  cai exec flow <flowExecutionId> --json
90
- cai exec node <nodeExecutionId> --json
91
- cai exec ports <nodeExecutionId> --json
96
+ cai exec node <nodeExecutionId> --full --json
92
97
  ```
93
98
 
94
- Use the tree to locate the first unexpected status. Use ports to compare actual inputs, resolved configuration, and outputs at that node. Read [references/debugging.md](references/debugging.md) for the fault-isolation order.
99
+ Page with the returned `nextCursor` via `--cursor`; narrow large runs with repeatable `--status`
100
+ or `--flow <flowId>`. Use the tree to locate the first unexpected status. Use the full node
101
+ execution to inspect its status, resolved configuration, and untruncated output. Read
102
+ [references/debugging.md](references/debugging.md) for the fault-isolation order.
95
103
 
96
104
  ## Output discovery
97
105
 
@@ -106,13 +114,15 @@ cai run discover \
106
114
  --json
107
115
  ```
108
116
 
109
- This calls the real third-party action and spends usage. For a destructive action, do not probe merely to learn its output — first ask the user for a safe target (see "Consequential actions" above); if they decline, declare the expected shape instead. Use `--keep` only when the user wants the scratch node retained.
117
+ MCP: `run_discover` always removes the scratch graph and exposes neither `keep` nor `waitSeconds`.
118
+
119
+ This calls the real third-party action and spends usage. For a destructive action, do not probe merely to learn its output — first ask the user for a safe target (see "Consequential actions" above); if they decline, declare the expected shape instead. On CLI, use `--keep` only when the user wants the scratch node retained.
110
120
 
111
121
  After successful output discovery, re-read `cai node status` and downstream `cai expr context`; verify the adopted output type is concrete.
112
122
 
113
123
  ## Completion gate
114
124
 
115
- - Gate scripts on `cai workflow validate`; it exits 1 when the response has `valid: false`.
125
+ - CLI scripts may gate on `cai workflow validate` exiting 1; MCP callers inspect `valid` and `errors`.
116
126
  - The test exercised the changed path with credible values.
117
127
  - The first unexpected node, if any, was identified rather than inferred from the final error.
118
128
  - All dynamic configs resolved to intended values.