describe_capabilities gives the vocabulary, draft_automation validates it and stores a draft, edit_automation publishes it (or runs, dry-runs, pauses it). What you publish is a normal automation: it appears on /automations, approvals land in its session, and a person can edit it there afterwards. The sidecars-automations skill teaches the loop.
Both scopes arrive by step-up consent the first time a tool needing them is called. Anything you cannot open — another person’s personal automation, a row in another workspace — is not found, never “forbidden”. Changing an automation needs the same right the page needs: its creator for a personal one, a workspace admin for a
workspace one.
The plan
A plan is{ "planVersion": 1, "name": "…", "description": "…", "nodes": [...], "edges": [...] } — name and description are required — with at most 200 nodes. Node shapes — capability, agent, transform, branch, map, subflow, approval, notify, delay — and the transform operations are returned verbatim by describe_capabilities; copy them. Inputs are bound with {"kind":"literal","value":…}, {"kind":"ref","node":"<upstream id>","path":"…"} or {"kind":"trigger","path":"…"}. Every write capability must sit downstream of an approval node unless the draft is submitted with write_approval: "automatic", in which case the plan may have no approval node at all.
The trigger on the wire:
list_automations
Scope:automations:read · Kind: read-only · Annotations: readOnlyHint: true, destructiveHint: false, openWorldHint: false
List the automations you can see in this workspace — your personal ones and the workspace’s — newest first.
Parameters
number
default:"50"
Rows to return, at most 200.
Returns
array
Rows with
automation_id, name, enabled, degraded_reason?, trigger, scope (personal | workspace), can_control, version?, step_count?, namespaces?, session_id?, next_fire_at?, last_fired_at?, consecutive_failures, created_at, url?.boolean
More rows exist than
limit returned.read_automation
Scope:automations:read · Kind: read-only · Annotations: readOnlyHint: true, destructiveHint: false, openWorldHint: false
Read one automation: the ask it implements, its numbered steps, what it writes to, its trigger, scope, state and live version.include_planadds the plan JSON;include_runsthe latest runs;run_idone run’s per-node detail.
Parameters
string
required
From
list_automations or a publish.boolean
default:"false"
Add
plan_json — the live FlowPlan, the best worked example for writing or revising one.boolean
default:"false"
Add the latest 20 runs (
run_id, status, dry_run, cause, error?, timestamps) and runs_truncated.string
Add one run’s detail:
nodes[] with node_id, status, attempt, error?, and the run’s output?. A run that is not this automation’s reads as null.Returns
…
Identity and the sentence the plan implements.
string[]
The live version’s steps, numbered as the page shows them.
string[]
Capability keys the plan writes with (
linear.createIssuesFromItems).string[]
Systems it touches;
personal_connectors names the creator’s own connections it depends on.…
State, as on the row.
…
The live version.
flow_version_id is what a schedule-only republish passes.string
Where its runs and approvals land.
…
When asked for.
describe_capabilities
Scope:automations:read · Kind: read-only · Annotations: readOnlyHint: true, destructiveHint: false, openWorldHint: false
Everything needed to write a FlowPlan: the workspace’s connectors, the node, transform, binding and trigger-input forms to copy verbatim, the write-approval rule, and the capability catalogue per namespace. Call it first with include_schemas: false, then narrowed to the namespaces your plan needs.
Parameters
string[]
Only these namespaces’ capabilities. Default: every namespace the workspace may use. A namespace listed with
connected: false exists but may not be used here.boolean
default:"true"
Include each capability’s
input and output JSON schema.Returns
number
1 and 200.array
provider, name, personal, namespace for each connected system. A workspace-scoped automation cannot use a personal one.string
The vocabulary, rendered from the same source the validator checks against.
array
namespace, connected, capabilities[] with key, kind (read | write), describe, large?, async?, input?, output?.…
Past ~90 KB the tail namespaces lose their schemas; call again narrowed to them.
draft_automation
Scope:automations:write · Kind: write · Annotations: readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false
Validate a FlowPlan you wrote and store it as a draft version. Nothing is scheduled until it is published.
Parameters
object
required
The FlowPlan (
planVersion: 1).string
required
The request this plan implements, in one sentence; shown on the automation.
'required' | 'automatic'
default:"required"
required: every write behind an approval node. automatic: no approval nodes; writes run unattended.string
Draft the next version of this automation instead of a new one. Needs the right to change it.
Returns
Either a draft:'plan'
…
What
edit_automation publish takes.…
Read these back to the person before publishing.
isError: true), with nothing stored:
'failed'
array
rule (shape, dag/cycle, capability/not-connected, capability/input, binding/not-upstream, …), path into your plan JSON (["nodes", 2, "inputs", "issues"]), node_id?, message. Fix exactly these and resubmit.edit_automation
Scope:automations:write · Kind: write · Annotations: readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false
One tool, three actions:publisha draft behind a trigger,runan automation now (ordry_runit),set_enabledto pause or resume. Pausing is the undo for everything; there is no delete. A paused automation refuses a realrunbut still acceptsdry_run: true, so it can be tested without starting its schedule.
Parameters
'publish' | 'run' | 'set_enabled'
required
string
Required for
run and set_enabled. On publish, makes the draft that automation’s next version; without it a new automation is created.string
publish: the draft from draft_automation (or the live version, to change only the trigger).…
publish. name is required for a new automation.'personal' | 'workspace'
publish. workspace needs an admin and cannot use personal connectors.'off' | 'problems' | 'everyRun'
publish: when the creator is notified.number
publish: minimum seconds between event-triggered runs.boolean
publish: false leaves it paused for review (default enabled). set_enabled: required.boolean
default:"false"
run: simulate writes.Returns
string
Echoed.
string
…
On
publish.…
On
run; run_id is set for a dry run and readable with read_automation(run_id). A normal run is queued and appears under include_runs moments later.…
On
set_enabled.