@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
@@ -11,26 +11,30 @@ cai flow get <flowId> --json
11
11
 
12
12
  Node runs use development. Flow runs default to development; `cai run flow <flowId> --target live --confirm-live` runs the published version. Trigger replay also defaults to development and uses the same flags for live. Every rail can call real providers and create external effects.
13
13
 
14
+ MCP: `run_flow` takes `waitSeconds` and may return before the execution is terminal.
15
+
14
16
  ## 2. Find the first divergence
15
17
 
16
18
  ```bash
17
- cai exec tree <workflowExecutionId> --json
19
+ cai exec tree <workflowExecutionId> --limit 50 --json
18
20
  ```
19
21
 
20
- Classify each node as completed, failed, skipped intentionally, skipped unexpectedly, or absent. The first divergence is usually the cause; later failures are often consequences.
22
+ Follow `nextCursor` with `--cursor`, and use repeatable `--status` or `--flow <flowId>` when the
23
+ run is large. Classify each node as completed, failed, skipped intentionally, skipped unexpectedly,
24
+ or absent. The first divergence is usually the cause; later failures are often consequences.
21
25
 
22
26
  ## 3. Inspect the node boundary
23
27
 
24
28
  ```bash
25
- cai exec ports <nodeExecutionId> --json
29
+ cai exec node <nodeExecutionId> --full --json
26
30
  ```
27
31
 
28
32
  Check:
29
33
 
30
- 1. Inputs: did the expected upstream value arrive?
31
- 2. Configs: did each expression resolve, and to the correct type/value?
32
- 3. Outputs: did the component return the promised shape?
33
- 4. Status/error: did the provider or engine reject the call?
34
+ 1. Resolved configs: did each expression resolve, and to the correct type/value?
35
+ 2. Output: did the component return the promised shape and value?
36
+ 3. Status/error: did the provider or engine reject the call?
37
+ 4. Upstream execution rows and wiring: did every expected producer run and connect to this node?
34
38
 
35
39
  ## 4. Fix by category
36
40
 
@@ -1,25 +1,53 @@
1
1
  ---
2
2
  name: controllerai-start
3
- description: Connect, orient, and route work across Controller AI agents and no-code automations. Use when starting a Controller AI coding-agent session, after `cai connect`, or when deciding whether an outcome should be a ready integration action, a workflow, an agent, or a combination.
3
+ description: Connect, orient, and route work across Controller AI agents and no-code automations. Use when starting a Controller AI coding-agent or MCP session, after `cai connect`, or when deciding whether an outcome should be a ready integration action, a workflow, an agent, or a combination.
4
4
  ---
5
5
 
6
6
  # Start with Controller AI
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
8
+ ## Transports
9
9
 
10
- Use the installed `cai` CLI as the supported platform interface. Do not call Controller AI REST or MCP routes directly.
10
+ The `cai ...` examples are canonical grammar. Use either the CLI or the typed MCP tools for a task; never mix transports within one task.
11
+
12
+ MCP tool names are domain-first snake_case derived from CLI command paths (`cai flow input add` -> `flow_input_add`). Read [references/mcp-tool-map.md](references/mcp-tool-map.md) for every command and reviewed exception. MCP has no workflow pin: pass `workflowId` on every workflow-scoped tool. Long-running MCP tools take `waitSeconds` (default 60, maximum 120) instead of CLI wait or timeout flags.
13
+
14
+ Local CLI setup commands do not exist on MCP. Use `account_status` for `auth status` and `doctor`, `account_claim_start`/`account_claim_verify` for email claiming, and `guide_list`/`guide_get` for bundled skills. `cai connect`, root `cai signup`, `cai auth login` and other local auth mutations, `cai skills install`, `cai skills update`, `cai use`, `cai config reset`, and `cai connection request` remain local-only; `cai agent present` and `cai file share` stay available to the in-app builder while hosted MCP uses their equivalents below.
15
+
16
+ - **Connect:** Call `connection_connect_url`, show its `url` as a markdown link, ask the user to finish connecting, then confirm with `connection_list` using its `integration`.
17
+ - **Finished agent:** Call `agent_present` and relay the returned agent card, including its link.
18
+ - **File for the user:** Call `file_share` and relay its returned link; Claude Code users may also just read it from the terminal.
19
+
20
+ ## Your account on MCP
21
+
22
+ Call `account_status` first. During OAuth, the user explicitly chose **My Controller account** or **Separate agent account**; do not infer that choice from browser state. In your first reply, say which account `account_status` reports they are using. If it is an unclaimed agent account, offer to claim it with their email at any time. Never ask for passwords—the claim uses the 6-digit code sent to their email. After a successful claim, tell them they can open the app URL from `account_status`, choose **Forgot password** with that email, set a password, and sign in to the same workspace.
11
23
 
12
24
  ## Confirm the setup
13
25
 
14
- Run:
26
+ On the CLI, run:
15
27
 
16
28
  ```bash
17
29
  cai doctor
18
30
  ```
19
31
 
20
- If authentication is missing and the human already has an account, run `cai connect`. If no account exists, run `cai signup` to create a provisional workspace and start building immediately. An unclaimed signup has the same functional access as a free account, including workflow and agent publishing; its workspace is not automatically deleted, and it has a $1 monthly usage cap (`cai signup` prints the exact amount). Email claiming is optional: run `cai signup email <address>`, ask the human account owner for the 6-digit code delivered to their inbox (never guess it), then run `cai signup verify <code>` to raise the monthly cap to $5 and enable durable account recovery. If agent signup is disabled, ask the human to register at https://app.getcontroller.ai/register, then run `cai connect`.
32
+ For a new terminal assistant, `cai agent setup` detects Claude Code, Codex, and
33
+ Cursor, ensures login, and installs the best available plugin or MCP-and-skills
34
+ fallback; use `cai agent setup --status --json` for a read-only machine plan.
35
+ Use `cai doctor` to compare installed version stamps and see the exact update
36
+ command, and `cai docs [path]` (or `cai docs --list`) to read platform docs in
37
+ the terminal.
38
+
39
+ MCP: use `account_status`; local diagnosis, login, and `cai connect` do not exist.
40
+
41
+ On the CLI, if authentication is missing and the human already has an account, run `cai connect`. If no account exists, run `cai signup` to create a provisional workspace and start building immediately. An unclaimed signup has the same functional access as a free account, including workflow and agent publishing; its workspace is not automatically deleted, and it has a $1 monthly usage cap (`cai signup` prints the exact amount). Email claiming is optional: run `cai signup email <address>`, ask the human account owner for the 6-digit code delivered to their inbox (never guess it), then run `cai signup verify <code>` to raise the monthly cap to $5 and enable durable account recovery. If agent signup is disabled, ask the human to register at https://app.getcontroller.ai/register, then run `cai connect`.
42
+
43
+ MCP: the OAuth caller is already provisioned; use `account_claim_start` and `account_claim_verify` for optional email claiming.
44
+
45
+ On the CLI, if `cai doctor` reports missing, stale, or damaged managed skills, run `cai skills update`, then run `cai doctor` again. When the `CLI version` row says a newer cai is available, run `cai upgrade` before continuing — it prints the explicit CLI install command and updates detected skills, and new versions carry fixes the rest of these skills assume. Skill updates are setup maintenance, not a step to repeat during every build.
46
+
47
+ MCP: use `guide_list` and `guide_get`; skill installation, updates, and CLI upgrades are not hosted-session steps. Never ask the user to paste a password, provider token, or Controller AI credential into chat.
21
48
 
22
- If `cai doctor` reports missing, stale, or damaged managed skills, run `cai skills update`, then run `cai doctor` again. When the `CLI version` row says a newer cai is available, upgrade before continuing (`npm install -g @controllerai/cli@latest`, then `cai skills update`) — new versions carry fixes the rest of these skills assume. Skill updates are setup maintenance, not a step to repeat during every build. Never ask the user to paste a password, provider token, or Controller AI credential into chat.
49
+ 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`).
50
+ Deleting a connection immediately removes authorization from bound nodes and agent tools.
23
51
 
24
52
  ## Route the outcome
25
53
 
@@ -38,14 +66,14 @@ If the user's outcome does not reveal whether they want an agent or an automatio
38
66
 
39
67
  ## Platform docs
40
68
 
41
- The platform reference lives at https://docs.getcontroller.ai. Fetch https://docs.getcontroller.ai/llms.txt for the machine-readable index of every page; append `.md` to any page path for raw markdown (for example https://docs.getcontroller.ai/start/safety.md), or fetch /llms-full.txt for the whole corpus at once. Skills remain the procedural authority — consult the docs for what they do not carry: the execution and cost models, type-system and version-rail contracts, the full CLI and expression-operation references, and the workflow API. When a docs page and a skill disagree, prefer the skill and its live CLI queries (`cai expr ops`, `cai node find`).
69
+ The platform reference lives at https://docs.getcontroller.ai. Fetch https://docs.getcontroller.ai/llms.txt for the machine-readable index of every page; append `.md` to any page path for raw markdown (for example https://docs.getcontroller.ai/start/safety.md), or fetch /llms-full.txt for the whole corpus at once. Skills remain the procedural authority — consult the docs for what they do not carry: the execution and cost models, type-system and version-rail contracts, the full CLI and expression-operation references, and the workflow API. When a docs page and a skill disagree, prefer the skill and its live platform queries (`cai expr ops`, `cai integration actions`).
42
70
 
43
71
  ## Keep rails explicit
44
72
 
45
73
  - Agent Test mode uses the owner's mutable draft, current workflow development heads, current draft knowledge, and live runtime files overlaid by development/test runtime files. Live mode uses the latest published agent version, each workflow's latest live release, frozen published knowledge, and live runtime files only.
46
74
  - Agent draft edits require another agent publish to reach Live. Publishing restamps existing live conversations; shared users always receive the latest published version and never the draft.
47
75
  - Workflow publishes and direct-action connection/authorization grants are live bindings: a rebind can redirect Live, while revocation or detachment can block Live without another agent publish.
48
- - Local coding-agent subscriptions cover builder reasoning, not Controller AI hosted-agent runtime usage.
76
+ - Coding-agent subscriptions cover builder reasoning, not Controller AI hosted-agent runtime usage.
49
77
  - Provider actions can send messages, mutate or delete records, and incur provider charges. Decide the per-action confirmation policy before attaching one.
50
78
  - Never publish, share with the organization, replay a live trigger, or perform a consequential external test without clear user intent.
51
79
  - When a platform limitation blocks the outcome, STOP and report the partial result with the blocking error; never keep probing until the clock expires.
@@ -0,0 +1,170 @@
1
+ <!-- Generated by cli/scripts/generate-mcp-tool-map.mjs; do not edit by hand. -->
2
+
3
+ # CLI to typed MCP tool map
4
+
5
+ This registry-derived map covers 162 CLI commands and 149 typed MCP tools. CLI examples remain the canonical grammar; typed MCP calls use the tool and camelCase parameters shown here. Global `--json` and `--api-url` flags are host-controlled and omitted.
6
+
7
+ | `cai` command | MCP tool | Parameter mapping | Notes |
8
+ | --- | --- | --- | --- |
9
+ | `cai agent add-action` | `agent_tool_action_add` | `<agentId>` → `agentId`; `--action` → `action`; `--connection` → `connectionId`; `--description` → `description`; `--integration` → `integration`; `--require-confirmation` → `requireConfirmation` | — |
10
+ | `cai agent add-file` | `agent_knowledge_file_add`<br>`agent_workspace_file_add` | `agent_knowledge_file_add`: `<agentId>` → `agentId`; `--file` → `content` (inline content); `--name` → `name`; `--type` → `type`<br>`agent_workspace_file_add`: `<agentId>` → `agentId`; `--file` → `content` (inline content); `--name` → `name`; `--space` → `space`; `--type` → `type` | split across typed tools |
11
+ | `cai agent add-workflow` | `agent_tool_workflow_add` | `<agentId>` → `agentId`; `--description` → `description`; `--flow` → `flow`; `--require-confirmation` → `requireConfirmation`; `--workflow-id` → `workflowId` | — |
12
+ | `cai agent conversation approve` | `agent_conversation_approve` | `<conversationId>` → `conversationId`; `--request` → `requestId` | — |
13
+ | `cai agent conversation create` | `agent_conversation_create` | `<agentId>` → `agentId`; `--model` → `model`; `--title` → `title`; `--draft` → `rail=draft`; `--live` → `rail=live` | — |
14
+ | `cai agent conversation deny` | `agent_conversation_deny` | `<conversationId>` → `conversationId`; `--message` → `message`; `--request` → `requestId` | — |
15
+ | `cai agent conversation history` | `agent_conversation_history` | `<conversationId>` → `conversationId`; `--last` → `last` | — |
16
+ | `cai agent conversation list` | `agent_conversation_list` | `<agentId>` → `agentId`; `--mode` → `mode` | — |
17
+ | `cai agent conversation send` | `agent_conversation_send` | `<conversationId>` → `conversationId`; `--message` → `message`; `--timeout` → `waitSeconds` | `waitSeconds` default 60, max 120 |
18
+ | `cai agent conversation status` | `agent_conversation_status` | `<conversationId>` → `conversationId` | — |
19
+ | `cai agent create` | `agent_create` | `--disabled` → `disabled`; `--instructions` / `--instructions-file` → `instructions` (inline content); `--name` → `name` | — |
20
+ | `cai agent delete` | `agent_delete` | `<agentId>` → `agentId` | — |
21
+ | `cai agent files` | `agent_file_list` | `<agentId>` → `agentId`; `--cursor` → `cursor`; `--environment` → `environment`; `--folder-prefix` → `folderPrefix`; `--limit` → `limit`; `--live` → `live`; `--search` → `search`; `--space` → `space` | — |
22
+ | `cai agent get` | `agent_get` | `<agentId>` → `agentId` | — |
23
+ | `cai agent list` | `agent_list` | `--ownership` → `ownership`; `--search` → `search` | — |
24
+ | `cai agent present` | `agent_present` | `<agentId>` → `agentId`; `note` (MCP-only) → `note` | hosted: Returns a hosted agent summary and app link for the MCP host to present. |
25
+ | `cai agent publish` | `agent_publish` | `<agentId>` → `agentId`; `--name` → `name` | — |
26
+ | `cai agent publish-preflight` | `agent_publish_preflight` | `<agentId>` → `agentId` | — |
27
+ | `cai agent remove-tool` | `agent_tool_remove` | `<agentId>` → `agentId`; `--tool` → `toolId` | — |
28
+ | `cai agent test` | `agent_test` | `<agentId>` → `agentId`; `--message` → `message`; `--model` → `model`; `--timeout` → `waitSeconds`; `--title` → `title`; `--draft` → `rail=draft`; `--live` → `rail=live` | `waitSeconds` default 60, max 120 |
29
+ | `cai agent tools` | `agent_tool_list` | `<agentId>` → `agentId` | — |
30
+ | `cai agent update` | `agent_set_enabled`<br>`agent_update` | `agent_set_enabled`: `<agentId>` → `agentId`; `--enabled` / `--disabled` → `enabled`<br>`agent_update`: `<agentId>` → `agentId`; `--instructions` / `--instructions-file` → `instructions` (inline content); `--name` → `name` | split across typed tools |
31
+ | `cai agent update-tool` | `agent_tool_update` | `<agentId>` → `agentId`; `--connection` → `connectionId`; `--description` → `description`; `--require-confirmation` / `--no-confirmation` → `requireConfirmation`; `--tool` → `toolId` | — |
32
+ | `cai agent versions` | `agent_version_list` | `<agentId>` → `agentId` | — |
33
+ | `cai agent visibility` | `agent_visibility_set` | `<agentId>` → `agentId`; `--value` → `value` | — |
34
+ | `cai approval resume` | `approval_resume` | `<id>` → `approvalId`; `waitSeconds` (MCP-only) → `waitSeconds` | `waitSeconds` default 60, max 120 |
35
+ | `cai auth key` | — | — | dropped: Mints a long-lived local credential and is not an MCP account operation. |
36
+ | `cai auth login` | — | — | dropped: Starts a local device-code login even though the MCP request is already OAuth-authorized. |
37
+ | `cai auth logout` | — | — | dropped: Deletes local CLI credentials; it is not integration connection revocation. |
38
+ | `cai auth password` | — | — | dropped: Accepts a development email/password credential on the local machine. |
39
+ | `cai auth status` | `account_status` | — | hosted: The host reports the authenticated grant and combines it with server health facts. |
40
+ | `cai auth token` | — | — | dropped: Writes a bearer token into local CLI configuration. |
41
+ | `cai branch add` | `branch_add` | `<nodeId>` → `nodeId`; `--allow-duplicate` → `allowDuplicate`; `--condition-json` → `conditionJson`; `--js` / `--js-file` → `js` (inline content); `--name` → `name`; `--workflow` → `workflowId` | — |
42
+ | `cai branch connect` | `branch_connect` | `<nodeId>` → `nodeId`; `--flow` → `flow`; `--route` → `branchId`; `--to` → `to`; `--workflow` → `workflowId` | — |
43
+ | `cai branch delete` | `branch_delete` | `<nodeId>` → `nodeId`; `--route` → `branchId`; `--workflow` → `workflowId` | — |
44
+ | `cai branch list` | `branch_list` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
45
+ | `cai branch reorder` | `branch_reorder` | `<nodeId>` → `nodeId`; `--order` → `order`; `--workflow` → `workflowId` | — |
46
+ | `cai branch update` | `branch_update` | `<nodeId>` → `nodeId`; `--condition-json` → `conditionJson`; `--js` / `--js-file` → `js` (inline content); `--name` → `name`; `--route` → `branchId`; `--workflow` → `workflowId` | — |
47
+ | `cai config reset` | — | — | dropped: Clears a local workflow pin; typed MCP calls are stateless. |
48
+ | `cai connect` | — | — | dropped: Installs local skills, opens a browser, and verifies a local project. |
49
+ | `cai connection connect` | `connection_connect_url` | `<nodeSlug>` → `nodeSlug` | — |
50
+ | `cai connection delete` | `connection_delete` | `<connectionId>` → `connectionId` | — |
51
+ | `cai connection list` | `connection_list` | `--integration` → `integration` | — |
52
+ | `cai connection request` | — | — | dropped: Posts a connect card into build chat; connection_connect_url supplies the hosted outcome. |
53
+ | `cai connection update` | `connection_update` | `<connectionId>` → `connectionId`; `--name` → `displayName`; `--default` / `--no-default` → `isDefault` | — |
54
+ | `cai data collection create` | `schema_type_create` | `<dataType>` → `name`; `--display` → `display`; `--field` → `field`; `--from-json` → `fromJson` (inline content); `--workflow` → `workflowId` | merged: The CLI command is sugar over schema create; no separate collection-create route exists. |
55
+ | `cai data collections` | `data_collection_list` | `--env` → `env`; `--workflow` → `workflowId` | — |
56
+ | `cai data copy-to-live` | `data_copy_to_live` | `--type` → `type`; `--workflow` → `workflowId`; `env` (MCP-only) → `env` | `env` required |
57
+ | `cai data create` | `data_record_create` | `--env` → `env`; `--fields` → `fields`; `--type` → `type`; `--workflow` → `workflowId` | `env` required |
58
+ | `cai data delete` | `data_record_delete` | `<recordId>` → `recordId`; `--env` → `env`; `--type` → `type`; `--workflow` → `workflowId` | `env` required |
59
+ | `cai data delete-many` | `data_record_delete_many` | `--all` → `all`; `--env` → `env`; `--records` → `recordIds`; `--type` → `type`; `--workflow` → `workflowId` | `env` required |
60
+ | `cai data fields` | `data_field_list` | `--type` → `type`; `--workflow` → `workflowId` | — |
61
+ | `cai data get` | `data_record_get` | `<recordId>` → `recordId`; `--env` → `env`; `--type` → `type`; `--workflow` → `workflowId` | — |
62
+ | `cai data import` | `data_record_import_commit`<br>`data_record_import_validate` | `data_record_import_commit`: `--env` → `env`; `--file` → `content` (inline content); `--type` → `type`; `--workflow` → `workflowId`<br>`data_record_import_validate`: `--env` → `env`; `--file` → `content` (inline content); `--type` → `type`; `--workflow` → `workflowId` | split across typed tools; `env` required |
63
+ | `cai data query` | `data_record_query` | `--env` → `env`; `--limit` → `limit`; `--offset` → `offset`; `--query` → `query`; `--type` → `type`; `--workflow` → `workflowId` | — |
64
+ | `cai data update` | `data_record_update` | `<recordId>` → `recordId`; `--env` → `env`; `--fields` → `fields`; `--type` → `type`; `--workflow` → `workflowId` | `env` required |
65
+ | `cai deps` | `dependency_map` | `--workflow` → `workflowId` | — |
66
+ | `cai doctor` | `account_status` | — | hosted: Local runtime checks do not apply; useful account and version facts are in account_status. |
67
+ | `cai events` | `event_list` | `--cursor` → `cursor`; `--limit` → `limit`; `--since` → `since`; `--type` → `type`; `--for-workflow` / `--workflow` → `workflowId` | — |
68
+ | `cai exec flow` | `execution_flow_get` | `<flowExecutionId>` → `flowExecutionId`; `--workflow` → `workflowId` | — |
69
+ | `cai exec get` | `execution_get` | `<workflowExecutionId>` → `workflowExecutionId`; `--workflow` → `workflowId` | — |
70
+ | `cai exec list` | `execution_list` | `--limit` → `limit`; `--workflow` → `workflowId` | — |
71
+ | `cai exec node` | `execution_node_get` | `<nodeExecutionId>` → `nodeExecutionId`; `--full` → `full`; `--workflow` → `workflowId` | — |
72
+ | `cai exec tree` | `execution_tree` | `<workflowExecutionId>` → `workflowExecutionId`; `--cursor` → `cursor`; `--flow` → `flowId`; `--limit` → `limit`; `--status` → `status`; `--workflow` → `workflowId` | — |
73
+ | `cai expr context` | `expr_context` | `<nodeId>` → `nodeId`; `--methods` → `methods`; `--prop` → `prop`; `--workflow` → `workflowId` | — |
74
+ | `cai expr decompile` | `expr_decompile` | `<nodeId>` → `nodeId`; `--prop` → `prop`; `--workflow` → `workflowId` | — |
75
+ | `cai expr ops` | `expr_operation_list` | `--type` → `type`; `--workflow` → `workflowId` | — |
76
+ | `cai expr set` | `node_prop_set` | `<nodeId>` → `nodeId`; `--js` / `--js-file` → `js` (inline content); `label` (MCP-only) → `label`; `--prop` → `prop`; `rawExpressionJson` (MCP-only) → `rawExpressionJson`; `value` (MCP-only) → `value`; `--workflow` → `workflowId`; `valueJson` (MCP-only) → `valueJson` | merged: node_prop_set exposes the same expression write alongside literal and raw-expression forms. |
77
+ | `cai expr validate` | `expr_validate` | `<nodeId>` → `nodeId`; `--js` / `--js-file` → `js` (inline content); `--mode` → `mode`; `--prop` → `prop`; `--workflow` → `workflowId` | — |
78
+ | `cai file share` | `file_share` | `--name` → `name`; `content` (MCP-only) → `content`; `encoding` (MCP-only) → `encoding`; `mimeType` (MCP-only) → `mimeType` | hosted: Stores inline bytes as a private artifact and returns its browser-openable link. |
79
+ | `cai flow create` | `flow_create` | `--name` → `name`; `--workflow` → `workflowId` | — |
80
+ | `cai flow delete` | `flow_delete` | `<flowId>` → `flowId`; `--workflow` → `workflowId` | — |
81
+ | `cai flow duplicate` | `flow_duplicate` | `<flowId>` → `flowId`; `--workflow` → `workflowId` | — |
82
+ | `cai flow for-each` | `flow_for_each_scaffold` | `--continue-on-error` → `continueOnError`; `--flow` → `flow`; `--from` → `from`; `--item-field` → `itemField`; `--item-name` → `itemName`; `--item-type` → `itemType`; `--list-field` → `listField`; `--list-js` / `--js-file` → `listJs` (inline content); `--max-items` → `maxItems`; `--name` → `name`; `--source-output` → `sourceOutput`; `--workflow` → `workflowId` | — |
83
+ | `cai flow get` | `flow_get` | `<flowId>` → `flowId`; `--workflow` → `workflowId` | — |
84
+ | `cai flow input add` | `flow_input_add` | `<flowId>` → `flowId`; `--description` → `description`; `--display` → `display`; `--list` → `list`; `--optional` → `optional`; `--type` → `type`; `--workflow` → `workflowId` | — |
85
+ | `cai flow input delete` | `flow_input_delete` | `<flowId>` → `flowId`; `--input` → `input`; `--workflow` → `workflowId` | — |
86
+ | `cai flow input update` | `flow_input_update` | `<flowId>` → `flowId`; `--default-value` → `defaultValue`; `--description` → `description`; `--display` → `display`; `--input` → `input`; `--name` → `name`; `--optional` / `--required` → `optional`; `--type` → `type`; `--workflow` → `workflowId` | — |
87
+ | `cai flow layout` | `flow_layout` | `<flowId>` → `flowId`; `--workflow` → `workflowId` | — |
88
+ | `cai flow list` | `flow_list` | `--workflow` → `workflowId` | — |
89
+ | `cai flow output add` | `flow_output_add` | `<flowId>` → `flowId`; `--description` → `description`; `--display` → `display`; `--name` → `name`; `--type` → `type`; `--workflow` → `workflowId` | — |
90
+ | `cai flow output delete` | `flow_output_delete` | `<flowId>` → `flowId`; `--output` → `output`; `--workflow` → `workflowId` | — |
91
+ | `cai flow output update` | `flow_output_update` | `<flowId>` → `flowId`; `--description` → `description`; `--display` → `display`; `--name` → `name`; `--output` → `output`; `--type` → `type`; `--workflow` → `workflowId` | — |
92
+ | `cai flow outputs` | `flow_output_list` | `<flowId>` → `flowId`; `--workflow` → `workflowId` | — |
93
+ | `cai flow rename` | `flow_rename` | `<flowId>` → `flowId`; `--name` → `name`; `--workflow` → `workflowId` | — |
94
+ | `cai flow reorder` | `flow_reorder` | `--order` → `order`; `--workflow` → `workflowId` | — |
95
+ | `cai integration action` | `integration_action_get` | `--integration` → `integration`; `--key` → `key` | — |
96
+ | `cai integration actions` | `integration_action_list` | `<query>` → `query`; `--integration` → `integration`; `--limit` → `limit` | — |
97
+ | `cai integration search` | `integration_search` | `<query>` → `query`; `--limit` → `limit`; `--actions` → `kind=actions`; `--events` → `kind=events`; `` → `kind=all` | — |
98
+ | `cai label list` | `label_list` | — | — |
99
+ | `cai label set` | `label_set` | `--agent` → `agentId`; `--labels` / `--label` / `--none` → `labels`; `--workflow` → `workflowId` | — |
100
+ | `cai node add` | `node_add` | `--after` → `after`; `--connection` → `connection`; `--enable-prop` → `enableProp`; `--flow` → `flow`; `--key` → `key`; `--name` → `name`; `--node` → `node`; `--output` → `output`; `--props` → `props`; `--workflow` → `workflowId` | — |
101
+ | `cai node connect` | `node_connect` | `--flow` → `flow`; `--from` → `from`; `--output` → `output`; `--to` → `to`; `--workflow` → `workflowId` | — |
102
+ | `cai node continue-on-error` | `node_continue_on_error_set` | `<nodeId>` → `nodeId`; `--enable` / `--disable` → `enabled`; `--workflow` → `workflowId` | — |
103
+ | `cai node declare-output` | `node_output_type_declare` | `<nodeId>` → `nodeId`; `--sample-file` → `sample` (inline content); `--workflow` → `workflowId` | — |
104
+ | `cai node delete` | `node_delete` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
105
+ | `cai node disable-prop` | `node_optional_prop_set` | `<nodeId>` → `nodeId`; `--prop` → `prop`; `--workflow` → `workflowId`; `enabled` (MCP-only) → `enabled` | merged: The explicit enabled boolean replaces the separate disabling command. |
106
+ | `cai node disconnect` | `node_disconnect` | `--edge` → `edge`; `--workflow` → `workflowId` | — |
107
+ | `cai node duplicate` | `node_duplicate` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
108
+ | `cai node enable-prop` | `node_optional_prop_set` | `<nodeId>` → `nodeId`; `--prop` → `prop`; `--workflow` → `workflowId`; `enabled` (MCP-only) → `enabled` | merged: The explicit enabled boolean replaces the separate enabling command. |
109
+ | `cai node get` | `node_get` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
110
+ | `cai node only-when` | `node_only_when_set` | `<nodeId>` → `nodeId`; `--clear` → `clear`; `--js` / `--js-file` → `js` (inline content); `--workflow` → `workflowId` | — |
111
+ | `cai node optional-props` | `node_optional_prop_list` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
112
+ | `cai node options` | `node_prop_options` | `<nodeId>` → `nodeId`; `--for` → `for`; `--page` → `page`; `--prev-context` → `prevContext`; `--prop` → `prop`; `--query` → `query`; `--workflow` → `workflowId` | — |
113
+ | `cai node props` | `node_prop_list` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
114
+ | `cai node reload` | `node_prop_reload` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
115
+ | `cai node rename` | `node_rename` | `<nodeId>` → `nodeId`; `--name` → `name`; `--workflow` → `workflowId` | — |
116
+ | `cai node set` | `node_prop_set` | `<nodeId>` → `nodeId`; `--js` / `--js-file` → `js` (inline content); `--label` → `label`; `--prop` → `prop`; `--raw-expression-json` → `rawExpressionJson` (inline content); `--value` → `value`; `--workflow` → `workflowId`; `--value` → `valueJson` | — |
117
+ | `cai node set-connection` | `node_connection_set` | `<nodeId>` → `nodeId`; `--connection` → `connection`; `--workflow` → `workflowId` | — |
118
+ | `cai node set-flow` | `node_subflow_set` | `<nodeId>` → `nodeId`; `--flow` → `flow`; `--workflow` → `workflowId` | — |
119
+ | `cai node status` | `node_status` | `<nodeId>` → `nodeId`; `--workflow` → `workflowId` | — |
120
+ | `cai run discover` | `run_discover` | `--connection` → `connection`; `--enable` → `enable`; `--key` → `key`; `--node` → `node`; `--props` → `props`; `--workflow` → `workflowId` | — |
121
+ | `cai run flow` | `run_flow` | `<flowId>` → `flowId`; `--confirm-live` → `confirmLive`; `--inputs` → `inputs`; `--target` → `target`; `--timeout` → `waitSeconds`; `--workflow` → `workflowId` | `waitSeconds` default 60, max 120 |
122
+ | `cai run inputs` | `run_inputs` | `<nodeIdOrFlowId>` → `nodeIdOrFlowId`; `--flow` → `flow`; `--workflow` → `workflowId` | — |
123
+ | `cai run node` | `run_node` | `<nodeId>` → `nodeId`; `--inputs` → `inputs`; `--timeout` → `waitSeconds`; `--workflow` → `workflowId` | `waitSeconds` default 60, max 120 |
124
+ | `cai run workflow` | — | — | dropped: Excluded dead stub whose handler always throws NOT_IMPLEMENTED. |
125
+ | `cai schema create` | `schema_type_create` | `<name>` → `name`; `--display` → `display`; `--field` → `field`; `--from-json` → `fromJson` (inline content); `--workflow` → `workflowId` | — |
126
+ | `cai schema delete` | `schema_type_delete` | `<name>` → `name`; `--workflow` → `workflowId` | — |
127
+ | `cai schema get` | `schema_type_get` | `<name>` → `name`; `--workflow` → `workflowId` | — |
128
+ | `cai schema list` | `schema_type_list` | `--all` → `all`; `--workflow` → `workflowId` | — |
129
+ | `cai schema resolve` | `schema_type_resolve` | `<typeId>` → `typeId`; `--workflow` → `workflowId` | — |
130
+ | `cai schema update` | `schema_type_update` | `<name>` → `name`; `--display` → `display`; `--field` → `field`; `--from-json` → `fromJson` (inline content); `--workflow` → `workflowId` | — |
131
+ | `cai signup` | — | — | dropped: The OAuth-authorized caller already has a provisioned account; root signup is local bootstrap. |
132
+ | `cai signup email` | `account_claim_start` | `<address>` → `email` | hosted: Uses the OAuth grant durable email-claim adapter instead of local CLI credential replacement. |
133
+ | `cai signup verify` | `account_claim_verify` | `<code>` → `code` | hosted: Uses the OAuth grant durable email verification adapter. |
134
+ | `cai skills install` | — | — | dropped: Writes guidance into a caller local project, which the hosted server cannot access. |
135
+ | `cai skills status` | `guide_get`<br>`guide_list` | `guide_get`: `name` (MCP-only) → `name`<br>`guide_list`: — | hosted: guide_list and guide_get serve the bundled server guidance without inspecting a local project. |
136
+ | `cai skills update` | — | — | dropped: Updates guidance files in a caller local project. |
137
+ | `cai trigger audit` | `trigger_audit` | `--workflow` → `workflowId` | — |
138
+ | `cai trigger create` | `trigger_create` | `--connection` → `connection`; `--dynamic-props-id` → `dynamicPropsId`; `--event` → `event`; `--flow` → `flow`; `--node` → `node`; `--props` → `props`; `--source-basis` → `sourceBasis`; `--workflow` → `workflowId` | — |
139
+ | `cai trigger delete` | `trigger_delete` | `<triggerId>` → `triggerId`; `--workflow` → `workflowId` | — |
140
+ | `cai trigger event` | `trigger_event_get` | `<eventId>` → `eventId`; `--workflow` → `workflowId` | — |
141
+ | `cai trigger events` | `trigger_event_list` | `--limit` → `limit`; `--trigger` → `triggerId`; `--workflow` → `workflowId` | — |
142
+ | `cai trigger get` | `trigger_get` | `<triggerId>` → `triggerId`; `--workflow` → `workflowId` | — |
143
+ | `cai trigger list` | `trigger_list` | `--workflow` → `workflowId` | — |
144
+ | `cai trigger options` | `trigger_prop_options` | `--configured` → `configured`; `--connection` → `connection`; `--dynamic-props-id` → `dynamicPropsId`; `--event` → `event`; `--node` → `node`; `--page` → `page`; `--prev-context` → `prevContext`; `--prop` → `prop`; `--query` → `query`; `--workflow` → `workflowId` | — |
145
+ | `cai trigger props` | `trigger_component_props` | `--configured` → `configured`; `--connection` → `connection`; `--dynamic-props-id` → `dynamicPropsId`; `--event` → `event`; `--node` → `node`; `--workflow` → `workflowId` | — |
146
+ | `cai trigger rename` | `trigger_rename` | `<triggerId>` → `triggerId`; `--name` → `name`; `--workflow` → `workflowId` | — |
147
+ | `cai trigger replay` | `trigger_replay` | `--confirm-live` → `confirmLive`; `--event` → `eventId`; `--payload` → `payload`; `--target` → `target`; `--trigger` → `triggerId`; `--workflow` → `workflowId` | — |
148
+ | `cai trigger search` | `trigger_search` | `<query>` → `query`; `--events-per-node` → `eventsPerNode`; `--limit` → `limit`; `--node` → `node`; `--workflow` → `workflowId` | — |
149
+ | `cai trigger select-event` | `trigger_event_select` | `--event` → `eventId`; `--node` → `triggerNodeId`; `--workflow` → `workflowId` | — |
150
+ | `cai trigger set-enabled` | `trigger_set_enabled` | `<triggerId>` → `triggerId`; `--enable` / `--disable` → `enabled`; `--workflow` → `workflowId` | merged: The explicit enabled boolean combines the mutually exclusive enable and disable flags. |
151
+ | `cai trigger test-events` | `trigger_test_events_set` | `<triggerId>` → `triggerId`; `--acknowledge-dual-run` → `acknowledgeDualRun`; `--allow` / `--disallow` → `allowed`; `--workflow` → `workflowId` | — |
152
+ | `cai use` | — | — | dropped: Persists a local workflow pin; every typed workflow call carries an explicit id. |
153
+ | `cai workflow create` | `workflow_create` | `--name` → `name` | — |
154
+ | `cai workflow delete` | `workflow_delete` | `<workflowId>` / `--workflow` → `workflowId` | — |
155
+ | `cai workflow document` | `workflow_document_get` | `--state` → `stateId`; `--workflow` → `workflowId` | — |
156
+ | `cai workflow duplicate` | `workflow_duplicate` | `<workflowId>` / `--workflow` → `workflowId` | — |
157
+ | `cai workflow get` | `workflow_get` | `<workflowId>` / `--workflow` → `workflowId` | — |
158
+ | `cai workflow history` | `workflow_history` | `--group` → `group`; `--version` → `version`; `--workflow` → `workflowId` | — |
159
+ | `cai workflow list` | `workflow_list` | `--limit` → `limit` | — |
160
+ | `cai workflow outline` | `workflow_outline` | `<workflowId>` / `--workflow` → `workflowId` | — |
161
+ | `cai workflow publish` | `workflow_publish` | `--acknowledge-dual-dispatch` → `acknowledgeDualDispatch`; `--acknowledge-validation-errors` → `acknowledgeValidationErrors`; `--name` → `name`; `--workflow` → `workflowId` | — |
162
+ | `cai workflow releases` | `workflow_release_list` | `<workflowId>` / `--workflow` → `workflowId` | — |
163
+ | `cai workflow rename` | `workflow_rename` | `--name` → `name`; `<workflowId>` / `--workflow` → `workflowId` | — |
164
+ | `cai workflow restore` | `workflow_state_restore` | `--state` → `stateId`; `--version` → `version`; `--workflow` → `workflowId` | — |
165
+ | `cai workflow save` | `workflow_state_save` | `--name` → `name`; `--workflow` → `workflowId` | — |
166
+ | `cai workflow set-description` | `workflow_description_set` | `--description` → `description`; `<workflowId>` / `--workflow` → `workflowId` | — |
167
+ | `cai workflow state` | `workflow_state_get` | `--flow` → `flowId`; `--state` → `stateId`; `--workflow` → `workflowId` | — |
168
+ | `cai workflow status` | `workflow_status` | `--workflow` → `workflowId` | — |
169
+ | `cai workflow validate` | `workflow_validate` | `--workflow` → `workflowId` | — |
170
+ | `cai workflow versions` | `workflow_version_list` | `<workflowId>` / `--workflow` → `workflowId` | — |
@@ -5,7 +5,7 @@ description: Discover, configure, create, sample, enable, test, and debug Contro
5
5
 
6
6
  # Controller AI triggers
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 trigger targets exactly one flow. Its source may capture events before publish, but ordinary event execution uses the live workflow. Creating the source is therefore separate from mapping, development testing, publishing, and live replay.
11
11
 
@@ -35,6 +35,8 @@ cai connection list --node <nodeSlug> --json
35
35
  cai connection connect <nodeSlug>
36
36
  ```
37
37
 
38
+ MCP: call `connection_connect_url`; it returns the URL immediately and has no `open` or `wait` parameter.
39
+
38
40
  ## Resolve trigger props
39
41
 
40
42
  ```bash
@@ -45,9 +47,9 @@ cai trigger props \
45
47
  --json
46
48
  ```
47
49
 
48
- Use the returned shape-correct `propsExample` as a starting point. Hidden props remain unset. `readyForCreate` must be true before using it in `trigger create`; the CLI intentionally omits unresolved required option props rather than emitting a plausible placeholder.
50
+ Use the returned shape-correct `propsExample` as a starting point. Hidden props remain unset. `readyForCreate` must be true before using it in `trigger create`; the response intentionally omits unresolved required option props rather than emitting a plausible placeholder.
49
51
 
50
- For each name in `unresolvedOptionProps`, run the complete option command printed by the CLI, or equivalently:
52
+ For each name in `unresolvedOptionProps`, run the complete canonical option command returned by the transport, or equivalently:
51
53
 
52
54
  ```bash
53
55
  cai trigger options \
@@ -75,7 +77,7 @@ cai trigger props \
75
77
  --json
76
78
  ```
77
79
 
78
- Keep the same node, event, connection, and configured values on every reload, but always pass the LATEST `dynamicPropsId` the backend returned — a reload can mint a new ID, and reusing a stale one resolves against a stale schema. The CLI prints this complete command; do not shorten it to only `--configured`.
80
+ Keep the same node, event, connection, and configured values on every reload, but always pass the LATEST `dynamicPropsId` the backend returned — a reload can mint a new ID, and reusing a stale one resolves against a stale schema. The response provides the complete canonical command; do not shorten it to only `--configured`.
79
81
 
80
82
  Timer values are objects:
81
83
 
@@ -107,7 +109,7 @@ cai trigger create \
107
109
  --json
108
110
  ```
109
111
 
110
- Capture all returned IDs. `triggerId` is the canvas ID used for get/rename/toggle/delete. `backendTriggerId` is numeric and used for captured events and replay. They are not interchangeable.
112
+ Capture all returned IDs. `triggerId` is the canvas ID used for get/rename/set-enabled/delete. `backendTriggerId` is numeric and used for captured events and replay. They are not interchangeable.
111
113
 
112
114
  Read a single trigger back with `cai trigger get <triggerId> --json` — the full record: node, event, connection, props, lifecycle. Read-back is always `get`; the CLI has no `describe` read command anywhere (`cai workflow set-description` is a setter).
113
115
 
@@ -115,7 +117,9 @@ Follow returned `nextSteps` in order. Trigger payload does not automatically pop
115
117
 
116
118
  ## Remove or disable an automatic start
117
119
 
118
- `cai trigger delete <triggerId>` removes the automatic start from the development canvas; use it when the start should no longer exist. `cai trigger toggle <triggerId>` disables it reversibly by flipping its enabled state; read `cai trigger list --json` before and after because toggle is not a setter.
120
+ `cai trigger delete <triggerId>` removes the automatic start from the development canvas; use it when the start should no longer exist. `cai trigger set-enabled <triggerId> --enable|--disable` changes the enabled state reversibly and idempotently; pass exactly one state flag.
121
+
122
+ MCP: call `trigger_set_enabled` with `enabled: true` or `enabled: false`.
119
123
 
120
124
  Both are development edits. Publish after either so production follows; until then, the previous live trigger can still start the published workflow.
121
125
 
@@ -139,13 +143,15 @@ Armed test events let real events reach the DEV version while you set the trigge
139
143
  cai trigger test-events --id <triggerId> --disallow
140
144
  ```
141
145
 
146
+ MCP: call `trigger_test_events_set` with `allowed: false`, or `allowed: true` to arm it.
147
+
142
148
  The armed state is sticky: nothing disarms it for you, and dev dispatch and live dispatch are independent gates. A trigger that is armed while the workflow is also live runs ONE real event TWICE — both executions real, both billed. The starkest case is a schedule trigger: armed + enabled + published, the cron fires BOTH dev and live at every interval, forever, with no external event involved — until someone edits and republishes.
143
149
 
144
150
  Keeping a trigger armed alongside live on purpose (side-by-side comparison on real events) is legitimate but uncommon; it is a user decision, never a default.
145
151
 
146
152
  ## Verify development, then publish
147
153
 
148
- Use `cai run flow` for direct development verification, then replay one captured event through the development trigger path:
154
+ Use `cai run flow` for direct development verification, then replay one captured event through the development trigger path. MCP `run_flow` calls take `waitSeconds`.
149
155
 
150
156
  ```bash
151
157
  cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
@@ -23,12 +23,12 @@ Skipping capture/sample selection commonly leaves downstream output untyped. Ski
23
23
 
24
24
  | ID | Used by |
25
25
  | --- | --- |
26
- | Canvas `triggerId` | `trigger get`, `rename`, `toggle`, `delete` |
26
+ | Canvas `triggerId` | `trigger get`, `rename`, `set-enabled`, `delete` |
27
27
  | Numeric `backendTriggerId` | `trigger events`, `replay` |
28
28
  | `triggerNodeId` | `trigger select-event` |
29
29
  | Captured `eventId` | `trigger event`, `select-event`, `replay --event` |
30
30
 
31
- Always copy these from CLI output.
31
+ Always copy these from the transport output.
32
32
 
33
33
  Development replay is the normal pre-publish check:
34
34
 
@@ -40,7 +40,9 @@ Use `--target live --confirm-live` only for an intentional post-publish live ver
40
40
 
41
41
  ## Enable/disable
42
42
 
43
- `cai trigger toggle <triggerId>` flips state; it is not a setter. Read `cai trigger list --json` before and after. Do not toggle blindly.
43
+ `cai trigger set-enabled <triggerId> --enable|--disable` sets the requested state idempotently. Pass exactly one state flag.
44
+
45
+ MCP: call `trigger_set_enabled` with `enabled: true` or `enabled: false`.
44
46
 
45
47
  ## Debugging a missing run
46
48
 
@@ -1,13 +1,11 @@
1
1
  ---
2
2
  name: controllerai-workflows
3
- description: Build, inspect, edit, test, recover, and publish Controller AI workflows through the cai CLI. Use when a user asks to create or change an automation, workflow, flow, or workflow release, or when another Controller AI skill needs the shared lifecycle and safety rules.
3
+ description: Build, inspect, edit, test, recover, and publish Controller AI workflows through the cai CLI or typed MCP tools. Use when a user asks to create or change an automation, workflow, flow, or workflow release, or when another Controller AI skill needs the shared lifecycle and safety rules.
4
4
  ---
5
5
 
6
6
  # Controller AI workflows
7
7
 
8
- In MCP hosts, send each exact literal `cai ...` command through the single `exec` tool; never translate it into another grammar.
9
-
10
- Use `cai` as the control surface. Never call Controller AI REST or MCP routes directly; when the CLI lacks a capability, say so and name the UI path instead of bypassing it.
8
+ The `cai ...` examples are canonical grammar. Follow the transport rules and MCP map in `controllerai-start`; never mix transports within one task. Do not call private REST endpoints or invoke MCP routes outside the typed tools. When the selected transport lacks a capability, say so and name the UI path instead of bypassing it.
11
9
 
12
10
  ## Establish context
13
11
 
@@ -18,17 +16,19 @@ cai use <workflowId>
18
16
  cai workflow status --json
19
17
  ```
20
18
 
19
+ MCP: use `account_status`, then call `workflow_list` and `workflow_status` with explicit `workflowId`; there is no `cai use` or stored pin.
20
+
21
21
  If no workflow exists, create it with its final name:
22
22
 
23
23
  ```bash
24
24
  cai workflow create --name "<clear outcome-oriented name>" --json
25
25
  ```
26
26
 
27
- Read `selected`, `effectiveWorkflowId`, and `pinSource` from the result; creation does not guarantee that the new workflow won the effective pin. If `selected` is false, rerun without `--workflow` when `pinSource` is `flag`; otherwise run `cai use <id>` for a stored pin or clear an inherited `CAI_WORKFLOW` pin in the parent environment, then re-check context. Use `cai config reset` to clear stale stored pins; it cannot clear an environment pin. `cai doctor` verifies that the effective workflow pin and its development head are readable. Do not create and then rename: `workflow create --name` submits the name directly.
27
+ On the CLI, read `selected`, `effectiveWorkflowId`, and `pinSource` from the result; creation does not guarantee that the new workflow won the effective pin. If `selected` is false, rerun without `--workflow` when `pinSource` is `flag`; otherwise run `cai use <id>` for a stored pin or clear an inherited `CAI_WORKFLOW` pin in the parent environment, then re-check context. Use `cai config reset` to clear stale stored pins; it cannot clear an environment pin. `cai doctor` verifies that the effective workflow pin and its development head are readable. On MCP, capture the created `workflowId` and pass it explicitly thereafter. Do not create and then rename: `workflow create --name` submits the name directly.
28
28
 
29
29
  A new workflow already ships with one empty flow. Rename that flow and build in it — do not add a second flow for the first piece of work; only add flows for genuinely separate canvases. A stray empty "Flow 1" left behind is clutter the user has to clean up.
30
30
 
31
- Use IDs returned by the CLI. Never invent workflow, flow, node, prop, event, field, route, or connection identifiers.
31
+ Use IDs returned by the selected transport. Never invent workflow, flow, node, prop, event, field, route, or connection identifiers.
32
32
 
33
33
  To orient inside a workflow, prefer one call over many:
34
34
 
@@ -36,6 +36,10 @@ To orient inside a workflow, prefer one call over many:
36
36
  cai workflow outline --json
37
37
  ```
38
38
 
39
+ `cai workflow state --json` is the bounded state projection; add `--flow <flowId>` for that
40
+ flow's node and edge identities. Use `cai workflow document --json` only when the complete opaque
41
+ workflow JSON is actually needed.
42
+
39
43
  It returns the whole map compactly — every flow with typed inputs/outputs, its nodes with upstream `deps` (the graph shape), triggers with source/enabled/armed state, and data types with per-rail record counts. Drill into a specific flow with `cai flow get <flowId>` only when you need props and expressions.
40
44
 
41
45
  ## Build protocol
@@ -67,7 +71,7 @@ Load the narrow skill when the task reaches that surface:
67
71
 
68
72
  - All graph edits target development. Live remains unchanged until `cai workflow publish`.
69
73
  - Email verification is not a publishing prerequisite. An unclaimed agent-created account may publish; email claiming only raises its monthly usage cap and enables account recovery.
70
- - Prefer `--json` for decisions and IDs; human tables are for presentation. If human output looks odd, re-run the same read with `--json` before acting.
74
+ - On the CLI, prefer `--json` for decisions and IDs; human tables are for presentation. MCP tools return typed JSON. If human output looks odd, re-run the same read with `--json` before acting.
71
75
  - A workflow contains flows; a flow is one canvas. Do not confuse their IDs.
72
76
  - For flow inputs, pass a human `--display` label and use the compiler-current binding from the latest `cai flow get` (`jsBinding`) or `cai workflow outline` (`binding`). An input rename can change it: re-read bindings after every rename and never cache their spellings across renames. `legacyBinding` is diagnostic-only; never use it in expressions.
73
77
  - Name nodes after the data they produce. Downstream input bindings are seeded from that name when wired.
@@ -75,10 +79,10 @@ Load the narrow skill when the task reaches that surface:
75
79
  - **Edit the graph with a plan-aware safety net.** Each save is a version state. `cai workflow history` has no age cutoff on Free, Max, or custom plans and a 90-day window on Pro/Starter; expand a group with `cai workflow history --group <groupId>` to get its state IDs. Restore with `cai workflow restore --state <stateId>` within 7 days on Free, 90 days on Pro/Starter, or without an age limit on Max/custom. Duplicate, delete, and refactor with that window in mind. Restore rolls back the DEFINITION (graph and schemas) only — record data is unversioned and stays as it is. External side effects (sent messages, provider calls) are equally outside the undo.
76
80
  - **Validate after structural edits, don't ask permission before them.** After deleting a flow, deleting a type, or a large refactor — and before every publish — run `cai workflow validate` and fix what it lists. It is deep: required props, connections, wiring, expressions, output types, subflows, branches, trigger issues, grouped per red node. Publish refuses when validation reports errors; `--acknowledge-validation-errors` may only be used after the user explicitly approved publishing with the listed issues. Deleting a flow deletes its nodes, edges, inputs/outputs, and attached triggers, and breaks callers in other flows — exactly like deleting a function breaks its call sites; validate shows every break.
77
81
  - On a conflict, re-read current state and reapply intent. Do not replay stale IDs or whole documents.
78
- - Never delete a workflow without the user's explicit intent; the CLI requires `--yes` but that is not a substitute for authorization. `cai workflow delete` tears down deployed triggers and soft-deletes the workflow row. Historical workflow/version data remains stored, but there is currently no CLI restore command for the deleted row.
82
+ - Never delete a workflow without the user's explicit intent; the CLI requires `--yes` but that is not a substitute for authorization. MCP: `workflow_delete` has no `yes` parameter, but still requires the same explicit intent. `cai workflow delete` tears down deployed triggers and soft-deletes the workflow row. Historical workflow/version data remains stored, but there is currently no restore command for the deleted row.
79
83
  - **Know the dependency graph before deleting or refactoring shared resources.** `cai deps` shows which agents attach this workflow as a tool (LIVE or draft), which workflows call it, and which connections it uses; `cai deps --account` maps the whole account. Deleting a workflow with agent dependents is refused server-side, and `--force` is a deprecated, inert compatibility flag. For a draft attachment, run `cai agent remove-tool <agentId> --tool <toolId>`. If it is also LIVE, publish that detached draft with `cai agent publish <agentId>`; if it is LIVE-only, publish the already-detached current draft or delete the agent. Publishing or deleting a dependent agent is its own live/destructive decision — get the user's explicit approval for that step first. Then retry the workflow delete.
80
- - **Check the account feed when recent activity matters.** `cai events` lists what happened in the account, newest first: connections created, workflow edits/publishes/runs, agents created/published, members added. Filter with `--type` (comma-separated), `--since 30m|2h|7d|<ISO>`, `--for-workflow <id>`; page with `--cursor`. Typical uses: `cai events --type connection.created --since 10m` to see whether the user finished connecting, `cai events --since 24h` to catch up at session start, `cai events --for-workflow <id> --type workflow.run` for recent run activity. The feed cannot show connection deletions, settings changes, member removals, or any label/folder/share activity — absence there proves nothing. When the user asks you to reconstruct a past change the platform does not record (e.g. which workflow a label was removed from), say it is not recorded and change nothing; names or current state that merely suggest an answer are not evidence, and acting on a guess is worse than reporting the limitation.
81
- - **Share the platform, not just text.** At the right moments, hand the user the real product page — command outputs include `appUrl` when the app origin is known: after `workflow publish` (the live builder view), after development `run flow`/`run node` (the run page; live flow runs omit it), after `agent publish`/`test` (agent and conversation pages), and `connection connect` prints the connect link (share the link first with `--no-open`; add `--wait` only after the link is already in front of the user). When the user asks for a link at any other time, don't guess URLs: `cai workflow get`, `cai workflow status`, and `cai agent get` include `appUrl`. When you cannot perform something (settings, product-only surfaces), give the link instead of apologizing.
84
+ - **Check the account feed when recent activity matters.** `cai events` lists what happened in the account, newest first: connections created, workflow edits/publishes/runs, agents created/published, members added. Filter with `--type` (comma-separated), `--since 30m|2h|7d|<ISO>`, `--for-workflow <id>`; page with `--cursor`. Typical uses: `cai events --type connection.created --since 10m` to see whether the user finished connecting, `cai events --since 24h` to catch up at session start, `cai events --for-workflow <id> --type workflow.run` for recent run activity. The feed cannot show connection deletions, settings changes, member removals, or label activity — absence there proves nothing. When the user asks you to reconstruct a past change the platform does not record (e.g. which workflow a label was removed from), say it is not recorded and change nothing; names or current state that merely suggest an answer are not evidence, and acting on a guess is worse than reporting the limitation.
85
+ - **Share the platform, not just text.** At the right moments, hand the user the real product page — command outputs include `appUrl` when the app origin is known: after `workflow publish` (the live builder view), after development `run flow`/`run node` (the run page; live flow runs omit it), and after `agent publish`/`test` (agent and conversation pages). On the CLI, `connection connect` prints the link; share it with `--no-open` before optionally adding `--wait`. MCP: `connection_connect_url` returns the link immediately and has no `open` or `wait` parameter. When the user asks for a link at any other time, don't guess URLs: `cai workflow get`, `cai workflow status`, and `cai agent get` include `appUrl`. When you cannot perform something (settings, product-only surfaces), give the link instead of apologizing.
82
86
  - Never silently weaken the request to make a test pass. Report an unsupported capability or ask about a real product decision.
83
87
 
84
88
  ## Completion gate
@@ -92,6 +96,8 @@ cai flow get <flowId> --json
92
96
  cai run flow <flowId> --inputs <values.json> --json
93
97
  ```
94
98
 
99
+ MCP: pass the parsed values in `inputs` and set `waitSeconds` on `run_flow`.
100
+
95
101
  Then confirm:
96
102
 
97
103
  - **`cai workflow validate` reports `errors: 0`.** Every error is fixed, or explicitly reported to the user with what it breaks — never summarized away, never called cosmetic. A red canvas and a "done" claim cannot coexist.
@@ -1,6 +1,6 @@
1
1
  # Workflow command map
2
2
 
3
- Read only the sections relevant to the requested work. Use `cai <domain> --help` as the authoritative flag reference.
3
+ Read only the sections relevant to the requested work. On the CLI, use `cai <domain> --help` for flags. On MCP, inspect the typed tool schema and [the generated map](../../controllerai-start/references/mcp-tool-map.md).
4
4
 
5
5
  ## Setup and workflow lifecycle
6
6
 
@@ -10,11 +10,13 @@ cai doctor
10
10
  cai config reset [--local|--global]
11
11
  cai auth status
12
12
  cai workflow list|create|get|rename|set-description|duplicate|delete
13
- cai workflow state|status|versions|releases|history|save|restore|publish
13
+ cai workflow document|state|status|versions|releases|history|save|restore|publish
14
14
  cai use <workflowId>
15
15
  ```
16
16
 
17
- `workflow save` creates a named development checkpoint. `workflow publish` promotes development to live. Version history may be plan-gated. `workflow delete --yes` undeploys triggers and soft-deletes the workflow row; it refuses while any draft or LIVE agent depends on the workflow. Detach draft tools with `agent remove-tool`, publish detached drafts that are still LIVE, then retry. `--force` is deprecated and inert. Deletion is not a permanent history purge, and deleted rows currently have no CLI restore command.
17
+ MCP: `account_status` replaces `auth status` and `doctor`; `cai connect`, `config reset`, and `use` are local-only, so pass `workflowId` explicitly.
18
+
19
+ `workflow state` is a bounded projection; use `--flow <flowId>` for node and edge identities. `workflow document` returns the complete opaque JSON. `workflow save` creates a named development checkpoint. `workflow publish` promotes development to live. Version history may be plan-gated. `workflow delete --yes` undeploys triggers and soft-deletes the workflow row; it refuses while any draft or LIVE agent depends on the workflow. Detach draft tools with `agent remove-tool`, publish detached drafts that are still LIVE, then retry. `--force` is deprecated and inert. Deletion is not a permanent history purge, and deleted rows currently have no CLI restore command.
18
20
 
19
21
  ## Canvas and graph
20
22
 
@@ -22,10 +24,12 @@ cai use <workflowId>
22
24
  cai flow list|get|create|rename|duplicate|delete|reorder|layout
23
25
  cai flow input add|update|delete
24
26
  cai flow output add|update|delete
25
- cai node find|search|components|component
27
+ cai integration search|actions|action
26
28
  cai node init|status|get|props|set|connect|disconnect|delete
27
29
  ```
28
30
 
31
+ MCP: `node set` and `expr set` are merged into `node_prop_set`.
32
+
29
33
  Declare flow outputs before adding a Return response node. Its props are derived from those outputs.
30
34
 
31
35
  `cai flow input add <flowId> --display "<human label>" --type <type>` returns the compiler-current `jsBinding`. Use the latest value from `flow get` (`jsBinding`) or `workflow outline` (`binding`), re-read it after every input rename, and never cache its spelling across renames. `legacyBinding` is diagnostic-only.
@@ -39,6 +43,8 @@ cai flow for-each
39
43
  cai node set-flow
40
44
  ```
41
45
 
46
+ MCP: use `flow_for_each_scaffold` for `flow for-each` and `node_subflow_set` for `node set-flow`; pass file-based loop source inline as `listJs` and branch condition source as `js`.
47
+
42
48
  Use branch-specific connection commands for Router and If/Else outputs. Generic `node connect` supports only `main` and `error` outputs.
43
49
 
44
50
  ## Verification
@@ -48,18 +54,27 @@ cai run inputs|node|flow|discover
48
54
  cai exec list|get|flow|node|ports|tree
49
55
  ```
50
56
 
57
+ MCP: `run_node` and `run_flow` take `waitSeconds` (default 60, maximum 120). `run_discover` never keeps its scratch graph.
58
+
51
59
  `run discover` executes the real integration action in a scratch flow and can incur third-party effects or usage. Do not use it casually for mutating actions.
52
60
 
53
61
  ## Product surfaces
54
62
 
55
63
  ```text
56
64
  cai connection list|connect
57
- cai trigger list|get|search|props|options|create|events|event|select-event|replay|toggle|rename|delete
65
+ cai trigger list|get|search|props|options|create|events|event|select-event|replay|set-enabled|rename|delete
58
66
  cai schema list|get|resolve|create|update|delete
59
67
  cai data collections|fields|query|get|create|update|delete|delete-many|import|copy-to-live
60
68
  cai agent list|get|create|update|add-workflow|remove-tool|add-file|tools|publish-preflight|publish|versions|visibility
61
69
  cai agent conversation list|create|status|history|send|approve|deny
62
70
  ```
63
71
 
64
- Connections are authorized in a browser. The CLI returns and opens the Controller AI connection URL.
72
+ Connections are authorized in a browser. The CLI returns and may open the URL; MCP returns it from `connection_connect_url`.
73
+
74
+ MCP: `trigger_set_enabled` takes the same explicit enabled state as the CLI setter.
75
+
76
+ MCP: every data write requires explicit `env`; pass CSV text inline as `content` to `data_record_import`, and pass `env: "live"` to `data_copy_to_live`.
77
+
78
+ MCP: `agent update` splits into `agent_update` and `agent_set_enabled`; `agent add-file` splits into `agent_knowledge_file_add` and `agent_workspace_file_add` with inline `content`. `agent_conversation_send` takes `waitSeconds`.
79
+
65
80
  Agent visibility supports only `private` and `organization`; organization is an explicit live access change after agent publish.