AI Agents (MCP)

Turn the workflows you built into tools an AI assistant can call. Each flow you expose becomes its own named tool — the assistant runs it and reads the result.

Your workflow

The flow you already built

Named MCP tool

One tool per exposed flow

AI assistant

Calls it, reads the result

What It Is

An AI assistant decides what to do; Watchflows decides what it's allowed to do. It can see, run, and read results from the flows you share, and nothing else. This works over the Model Context Protocol (MCP) — a small watchflows-mcp helper in the app bundle talks to a local-only server inside the app (it listens on 127.0.0.1 / loopback, so nothing off this Mac can reach it).

It is off by default: no server listens and no live token is in effect until you flip the master toggle. When on, it stays local to this Mac:

Property Detail
Binds127.0.0.1 only — no network exposure
AuthPrivate bearer token required on every call
Token32 random bytes (43 base64url chars), regenerated every time the server starts
Stored inA 0600 file only your account can read
Never inThe Keychain or your shell history

Setup at a Glance

Four steps, once. The next three sections walk through 1–3.

1 Enable

AI Agents master toggle

2 Connect

Wire in your assistant

3 Expose

Per-flow toggle

4 Call

Assistant runs the tool

1. Turn It On

Open Settings → AI Agents and flip Enable AI Agents. That starts the loopback server, generates a fresh access token, and writes the port to disk so your assistant's helper can find it. The token is regenerated every time the server starts — a restart or off/on cycle invalidates the old one. Turning the toggle off stops the server.

2. Connect Your Assistant

The AI Agents pane has a connector for each major client. You never paste the token — every snippet carries only the path to the bundled helper, and the helper reads the token off its 0600 file itself.

Client How to connect
Claude DesktopOne-click Connect: merges a watchflows entry into your config, leaves other servers untouched. You restart Claude. (If it isn't installed, you get a copyable config instead.)
Claude CodeCopy one command, paste into a terminal (below)
Cursor / Windsurf / VS CodeCopy the same mcpServers JSON; only the target file differs (~/.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, etc.)
CodexCopy a TOML table into ~/.codex/config.toml

The Claude Code command looks like this (the helper path comes from wherever the app is actually installed):

claude mcp add --transport stdio watchflows -- /Applications/Watchflows.app/Contents/MacOS/watchflows-mcp

An Advanced section shows the active port and a masked copy of the token, with Copy and Rotate. Rotating replaces the token file and restarts the server so the new token takes effect immediately — any client still using the old token will need to reconnect.

3. Expose a Flow

Enabling AI Agents does not hand over all your flows. Each workflow has its own Expose to AI agents toggle, off by default, in the “Exposed workflows” list or the flow's inspector. A flow is agent-runnable only when both are true:

Enabled

The flow is on

Exposed

Toggle flipped on

Agent-runnable

Becomes a named tool

  • Everything else stays visible, just not runnable. list_workflows reports all flows with an agentRunnable flag, so the assistant sees what exists — but a non-exposed flow has no run tool and the run gate refuses it.
  • Destructive flows use the same toggle. A flow that can delete files or run scripts is gated by the very same Expose to AI agents switch — there's no separate one. The only difference: the refusal message adds a heads-up that the flow contains such a node, so you opt in with eyes open.

How Input Works

Exposing a flow turns it into a tool the assistant can call — and the first node of your flow is the slot where its input goes in. Whatever the assistant passes replaces the placeholder you saved while building (it replaces, never blends). Your saved value is shown to the assistant only as an example of what belongs there — not a fallback it quietly runs.

You get a clean, labeled slot when your flow starts with an Input node: it shows the assistant exactly one box, named after the Input's type.

Entry trigger Argument key Type
Input · Text (default)textstring
Input · JSONdataobject
Input · FilefilePathstring
Any other triggerpayloadobject (free-form)

An Input node isn't strictly required — the assistant's data is fed into whichever trigger your flow starts with. But only Input flows get that tidy labeled box. Every other trigger — File Changed, Schedule, Device Event, and so on — hands the assistant a single blank payload box to fill in, with no labels to guide it.

Assistant calls
podcast_info_fetcher(text: "Acquired")
Typed expansion

Fills contentType + data for you

Flow runs → returns

Curated output + output_source inline

The two run entry points are not interchangeable. Only the flow's own named tool does the typed key→payload expansion shown above (your text argument, then contentType and data filled in). run_workflow passes its payload object straight through with no remapping, so there you supply the raw trigger keys yourself.

To see a flow's exact input contract, call describe_workflow — it returns a runPayload block: a note plus a keys list giving each key's type, description, and example.

Omit a key and the flow runs on its saved default — the same value you tested with in the canvas. A supplied value always wins.

What You Get Back

A completed run returns the answer inline — a top-level output plus an output_source telling you where it came from. The rest of the body is lean: per-node status, timings, and errors, but not full payloads. For every node's full payload, the assistant calls get_run.

Watchflows picks the output automatically, and output_source self-advertises the pick:

output_source Meaning
explicit:<node>You set “Return this to the agent” on that node, and it ran
auto:<node>Single end node — its result was returned
none:side-effectThe leaf ran but produced no result
none:dead-endThe run ended without reaching an end node
ambiguous:multi-leaf:<names>Two or more branches ended at once — pick unclear
  • “Return this to the agent” override. When the auto-pick is wrong, turn this on in any node's inspector — its output becomes the answer (explicit:<node>), as long as it ran and produced a value. If it was skipped or empty, projection quietly falls back to the auto-pick. Never a hard error.
  • Verbose agent-trace fields are stripped from the output.
  • The inline value is capped at ~16 KB (16,384 bytes); anything larger is truncated inline to a marker.
  • A value already spilled to disk surfaces as a …[spilled blob — use get_run] marker, never the full bytes.

Long Runs & Retries

A run that hasn't finished after about a minute doesn't fail — the flow keeps executing in the background and is saved under a run_id from the start. Two non-error statuses tell the assistant to wait, not re-call:

Status Means Do
runningStill executing past ~60sPoll get_run with the run_id
already_runningYou tried to start it while in flightPoll the in-flight run_id — don't start a duplicate

The rule: on running or already_running, poll the run_id — don't re-call.

The Tools

Alongside each exposed flow's own named tool, the assistant always has these five core tools. They are read/run only — no creating, editing, or enabling/disabling flows in this version (planned for a later phase).

Tool What it does
list_workflowsLists every workflow, each with an agentRunnable flag
describe_workflowA flow's node-by-node shape plus its runPayload input contract
run_workflowRuns a flow by id with an optional payload, returning curated output inline (a flow's named tool is the typed shortcut)
get_runThe full, verbose record of one run, including every node's payload
list_runsPages through a flow's run history

Read tools see every flow; only exposed-and-enabled flows can be run.