@ericrisco/rsc 0.1.37 → 0.1.39
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.
- package/README.md +8 -2
- package/manifest.json +130 -4
- package/package.json +1 -1
- package/scripts/lib/domains.js +1 -0
- package/scripts/lib/recommend.js +5 -0
- package/skills/automation-flows/SKILL.md +1 -1
- package/skills/automation-strategy/SKILL.md +131 -0
- package/skills/automation-strategy/evals/README.md +16 -0
- package/skills/automation-strategy/evals/cases.yaml +48 -0
- package/skills/automation-strategy/references/automate-decision-and-roi.md +118 -0
- package/skills/automation-strategy/references/orchestration-and-antipatterns.md +107 -0
- package/skills/automation-strategy/references/platform-selection-matrix.md +86 -0
- package/skills/harness/references/providers.yaml +101 -0
- package/skills/make/SKILL.md +255 -0
- package/skills/make/evals/README.md +14 -0
- package/skills/make/evals/cases.yaml +45 -0
- package/skills/make/references/api-v2-cheatsheet.md +114 -0
- package/skills/make/references/blueprint-round-trip.md +128 -0
- package/skills/make/references/make-mcp-and-auth.md +101 -0
- package/skills/n8n/SKILL.md +205 -0
- package/skills/n8n/evals/README.md +14 -0
- package/skills/n8n/evals/cases.yaml +45 -0
- package/skills/n8n/references/auth-and-selfhost.md +62 -0
- package/skills/n8n/references/n8n-mcp-tools.md +84 -0
- package/skills/n8n/references/rest-api-cheatsheet.md +94 -0
- package/skills/power-automate/SKILL.md +169 -0
- package/skills/power-automate/evals/README.md +17 -0
- package/skills/power-automate/evals/cases.yaml +43 -0
- package/skills/power-automate/references/dataverse-web-api.md +187 -0
- package/skills/power-automate/references/entra-auth-setup.md +75 -0
- package/skills/power-automate/references/flowstudio-mcp-and-limits.md +62 -0
- package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
- package/skills/zapier/SKILL.md +145 -0
- package/skills/zapier/evals/README.md +5 -0
- package/skills/zapier/evals/cases.yaml +50 -0
- package/skills/zapier/references/programmatic-limits-and-partner-api.md +48 -0
- package/skills/zapier/references/when-to-use-vs-n8n-make.md +44 -0
- package/skills/zapier/references/zapier-mcp-tools.md +72 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Make API v2 — cheat-sheet
|
|
2
|
+
|
|
3
|
+
Current as of July 2026. Endpoints and query keys are **case-sensitive** and
|
|
4
|
+
every call is **zoned**. Verify anything you depend on at
|
|
5
|
+
[developers.make.com](https://developers.make.com/api-documentation) at author time.
|
|
6
|
+
|
|
7
|
+
## Base URL & auth
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
https://{zone}.make.com/api/v2
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `{zone}` ∈ `eu1 | eu2 | us1 | us2` (plus `celonis` for that deployment). The
|
|
14
|
+
wrong zone returns an **authentication error** even with a valid token — this
|
|
15
|
+
is the single most common Make API mistake.
|
|
16
|
+
- Header: `Authorization: Token {MAKE_API_TOKEN}` — literal `Token`, a space,
|
|
17
|
+
the token. OAuth2 exists for multi-user apps.
|
|
18
|
+
- Content type for writes: `Content-Type: application/json`.
|
|
19
|
+
|
|
20
|
+
## Token scopes (frozen at creation)
|
|
21
|
+
|
|
22
|
+
Mint the token in **Profile → API/SDK**. You pick scopes **once**; they cannot
|
|
23
|
+
be widened afterward — a too-narrow token means minting a new one. Grant only
|
|
24
|
+
what you use, e.g. `scenarios:read scenarios:write connections:read
|
|
25
|
+
connections:write hooks:read hooks:write datastores:read datastores:write
|
|
26
|
+
teams:read organizations:read`.
|
|
27
|
+
|
|
28
|
+
## Response envelope
|
|
29
|
+
|
|
30
|
+
Most responses wrap the payload under a root key named for the resource, e.g.
|
|
31
|
+
`{ "scenario": {...} }`, `{ "scenarios": [...] }`, `{ "response": { "blueprint": {...} } }`.
|
|
32
|
+
Extract with `jq '.scenario'` etc. **Confirm the exact wrapper per endpoint at
|
|
33
|
+
author time** — a few endpoints differ.
|
|
34
|
+
|
|
35
|
+
## Endpoint map
|
|
36
|
+
|
|
37
|
+
### Scenarios (the core)
|
|
38
|
+
|
|
39
|
+
| Method | Path | Notes |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| GET | `/scenarios?teamId={id}` | list; paginate with `pg[limit]` / `pg[offset]` |
|
|
42
|
+
| POST | `/scenarios` | body: `teamId` (int), `blueprint` (**string**), `scheduling` (**string**); optional `folderId`, `basedon` |
|
|
43
|
+
| GET | `/scenarios/{id}` | metadata (not the blueprint) |
|
|
44
|
+
| PATCH | `/scenarios/{id}` | update — send `blueprint`/`scheduling`/`name` as strings |
|
|
45
|
+
| DELETE | `/scenarios/{id}` | **permanent, no trash** — export blueprint first |
|
|
46
|
+
| GET | `/scenarios/{id}/blueprint` | the editable JSON (round-trip source) |
|
|
47
|
+
| POST | `/scenarios/{id}/start` | activate scheduled execution |
|
|
48
|
+
| POST | `/scenarios/{id}/stop` | deactivate |
|
|
49
|
+
| POST | `/scenarios/{id}/run` | one manual run; `{"responsive":true}` waits for result |
|
|
50
|
+
| POST | `/scenarios/{id}/clone` | body `{teamId, name}` — copy into a team |
|
|
51
|
+
|
|
52
|
+
### Connections
|
|
53
|
+
|
|
54
|
+
`GET/POST /connections`, `GET/DELETE /connections/{id}`,
|
|
55
|
+
`POST /connections/{id}/test`. Modules reference a connection **by id** for app
|
|
56
|
+
auth — the blueprint holds the id, never the secret.
|
|
57
|
+
|
|
58
|
+
### Hooks (Make's inbound webhooks/mailhooks)
|
|
59
|
+
|
|
60
|
+
`GET/POST /hooks`, `GET/DELETE /hooks/{id}`, `POST /hooks/{id}/ping`,
|
|
61
|
+
`POST /hooks/{id}/learn-start` / `learn-stop` (structure learning). This is
|
|
62
|
+
Make's *own* webhook receiver; building an inbound endpoint in **your** app is
|
|
63
|
+
the `webhooks` skill.
|
|
64
|
+
|
|
65
|
+
### Data stores
|
|
66
|
+
|
|
67
|
+
`GET/POST /data-stores`, `GET/DELETE /data-stores/{id}`,
|
|
68
|
+
`GET/POST/DELETE /data-stores/{id}/data`. The idiomatic place for dedup keys and
|
|
69
|
+
cross-run state (see `automation-flows` for the dedup pattern).
|
|
70
|
+
|
|
71
|
+
### Templates
|
|
72
|
+
|
|
73
|
+
`GET /templates`, `GET /templates/{id}/blueprint`. A published template's
|
|
74
|
+
blueprint is the cleanest round-trip starting point.
|
|
75
|
+
|
|
76
|
+
### Teams & organizations
|
|
77
|
+
|
|
78
|
+
`GET /teams?organizationId={id}`, `GET /organizations/{id}`. Read your real
|
|
79
|
+
rate ceiling: `GET /organizations/{id}` → `license.apiLimit`.
|
|
80
|
+
|
|
81
|
+
## Rate limits (req/min, per plan)
|
|
82
|
+
|
|
83
|
+
| Plan | Limit |
|
|
84
|
+
|---|---|
|
|
85
|
+
| Core | 60 |
|
|
86
|
+
| Pro | 120 |
|
|
87
|
+
| Teams | 240 |
|
|
88
|
+
| Enterprise | 1000 |
|
|
89
|
+
|
|
90
|
+
Don't hard-code it — read `license.apiLimit` from your own org. On `429`, back
|
|
91
|
+
off and retry (generic retry/backoff engineering: `api-connector-builder`).
|
|
92
|
+
|
|
93
|
+
## Scheduling string
|
|
94
|
+
|
|
95
|
+
`scheduling` is a JSON **string**. Common shapes (verify fields at author time):
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{"type":"on-demand"}
|
|
99
|
+
{"type":"indefinitely","interval":900} // interval in seconds
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`on-demand` scenarios run only via `/run` or a webhook trigger; `indefinitely`
|
|
103
|
+
runs on the interval once `/start`ed.
|
|
104
|
+
|
|
105
|
+
## Errors you will actually hit
|
|
106
|
+
|
|
107
|
+
| Symptom | Cause | Fix |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| Auth error with a valid token | wrong `{zone}` | match the org's zone |
|
|
110
|
+
| 400 on create | `blueprint`/`scheduling` sent as objects | stringify them |
|
|
111
|
+
| 400 naming a module/field | malformed blueprint | fix that node, re-POST |
|
|
112
|
+
| 403 on a valid endpoint | token missing that scope | re-mint with the scope |
|
|
113
|
+
| 404 on a path that should exist | wrong case in the path | fix casing |
|
|
114
|
+
| 429 | over plan rate limit | back off; read `apiLimit` |
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# The blueprint round-trip
|
|
2
|
+
|
|
3
|
+
You almost never author a Make blueprint by hand. You **export** one, **mutate**
|
|
4
|
+
the JSON, and **send it back as a string**. This file is that recipe in depth.
|
|
5
|
+
|
|
6
|
+
## Why round-trip
|
|
7
|
+
|
|
8
|
+
A blueprint is a large, only-partially-documented JSON structure. Writing one
|
|
9
|
+
from scratch means guessing internal module parameter keys and metadata that the
|
|
10
|
+
create endpoint will reject. Exporting a working scenario (or a published
|
|
11
|
+
template) gives you a guaranteed-valid skeleton to edit — the diff you make is
|
|
12
|
+
small and reviewable.
|
|
13
|
+
|
|
14
|
+
## Blueprint anatomy (top level)
|
|
15
|
+
|
|
16
|
+
```jsonc
|
|
17
|
+
{
|
|
18
|
+
"name": "My scenario",
|
|
19
|
+
"flow": [ // ordered modules — index 1, 2, 3…
|
|
20
|
+
{
|
|
21
|
+
"id": 1,
|
|
22
|
+
"module": "gateway:CustomWebHook", // module type
|
|
23
|
+
"version": 1,
|
|
24
|
+
"parameters": { "hook": 123456 }, // references a hook by id
|
|
25
|
+
"mapper": {}, // inbound mapping for this module
|
|
26
|
+
"metadata": { "designer": { "x": 0, "y": 0 } }
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 2,
|
|
30
|
+
"module": "notion:createDatabaseItem",
|
|
31
|
+
"version": 2,
|
|
32
|
+
"parameters": { "__IMTCONN__": 78910 }, // connection id — NOT a secret
|
|
33
|
+
"mapper": { "title": "{{1.body.name}}" } // maps module 1's output
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"metadata": {
|
|
37
|
+
"instant": true,
|
|
38
|
+
"scenario": { "roundtrips": 1, "maxErrors": 3, "autoCommit": true },
|
|
39
|
+
"designer": { "orphans": [] }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Key ideas:
|
|
45
|
+
|
|
46
|
+
- **`flow`** is the ordered module list. Each module has an integer `id`; a
|
|
47
|
+
trigger sits at index 1.
|
|
48
|
+
- **Mapping** is `{{sourceId.path}}` — `{{1.body.name}}` = module 1's
|
|
49
|
+
`body.name`. This is the same mapping `automation-flows` designs; here you are
|
|
50
|
+
only serializing it.
|
|
51
|
+
- **Connections and hooks are referenced by id** (`__IMTCONN__`, `parameters.hook`).
|
|
52
|
+
Create the connection/hook first (or reuse one), put its id here. Never inline
|
|
53
|
+
an API key or token.
|
|
54
|
+
- **Routers/branches** appear as nested `routes` arrays inside a router module.
|
|
55
|
+
- `metadata.scenario` carries run settings (max errors, sequential processing,
|
|
56
|
+
auto-commit) — design decisions from `automation-flows`, encoded here.
|
|
57
|
+
|
|
58
|
+
## Step 1 — export
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
curl -s -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
62
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$SRC_ID/blueprint" \
|
|
63
|
+
| jq '.response.blueprint' > bp.json # verify the .response.blueprint wrapper at author time
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or from a template: `GET /templates/{id}/blueprint`.
|
|
67
|
+
|
|
68
|
+
## Step 2 — mutate
|
|
69
|
+
|
|
70
|
+
Edit `bp.json`: rename it, repoint `parameters.__IMTCONN__` /
|
|
71
|
+
`parameters.hook` at *your* connection/hook ids, adjust `mapper` expressions,
|
|
72
|
+
add/remove modules in `flow`. If you add a module, give it a fresh integer `id`
|
|
73
|
+
and wire downstream mappers to it.
|
|
74
|
+
|
|
75
|
+
Validate it is still JSON before sending:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
jq empty bp.json && echo "valid json"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Step 3 — send back as a STRING
|
|
82
|
+
|
|
83
|
+
The create/update endpoints want `blueprint` (and `scheduling`) as JSON
|
|
84
|
+
**strings**, not objects. Build the body with `jq` so the stringify is correct:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# CREATE
|
|
88
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
89
|
+
-H "Content-Type: application/json" \
|
|
90
|
+
"https://$MAKE_ZONE/api/v2/scenarios" \
|
|
91
|
+
-d "$(jq -n \
|
|
92
|
+
--argjson team "$MAKE_TEAM_ID" \
|
|
93
|
+
--arg bp "$(jq -c . bp.json)" \
|
|
94
|
+
--arg sched '{"type":"on-demand"}' \
|
|
95
|
+
'{teamId:$team, blueprint:$bp, scheduling:$sched}')"
|
|
96
|
+
|
|
97
|
+
# UPDATE (same scenario)
|
|
98
|
+
curl -s -X PATCH -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$ID" \
|
|
101
|
+
-d "$(jq -n --arg bp "$(jq -c . bp.json)" '{blueprint:$bp}')"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`jq -c . bp.json` compacts the blueprint to one line; passing it via `--arg`
|
|
105
|
+
makes it a **string** field. `--argjson team` keeps `teamId` a number.
|
|
106
|
+
|
|
107
|
+
## The stringify gotcha
|
|
108
|
+
|
|
109
|
+
The most common failure is sending `blueprint` as a nested object:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
// WRONG — object, 400
|
|
113
|
+
{ "teamId": 123, "blueprint": { "flow": [ ... ] }, "scheduling": {"type":"on-demand"} }
|
|
114
|
+
|
|
115
|
+
// RIGHT — string
|
|
116
|
+
{ "teamId": 123, "blueprint": "{\"flow\":[...]}", "scheduling": "{\"type\":\"on-demand\"}" }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If you build the request in Python/JS, `json.dumps()` / `JSON.stringify()` the
|
|
120
|
+
blueprint value itself and assign the resulting string.
|
|
121
|
+
|
|
122
|
+
## Verify, then activate
|
|
123
|
+
|
|
124
|
+
The create/PATCH call is the validator — a bad blueprint returns a 400 naming
|
|
125
|
+
the offending module. On success, dry-run with `POST /scenarios/{id}/run`
|
|
126
|
+
(`{"responsive":true}` to get the output inline), inspect the bundle, then
|
|
127
|
+
`POST /scenarios/{id}/start`. Before any `DELETE`, re-export the blueprint to a
|
|
128
|
+
file — deletion is permanent.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Make MCP server & auth setup
|
|
2
|
+
|
|
3
|
+
The Make MCP server exposes your Make account to an MCP client (Claude, Cursor,
|
|
4
|
+
ChatGPT, or any MCP-capable agent) so it can run — and, on paid plans, manage —
|
|
5
|
+
scenarios as tools. It is **GA and free on every plan**; you pay only the normal
|
|
6
|
+
scenario **credits** each run consumes. Verify specifics at
|
|
7
|
+
[developers.make.com/mcp-server](https://developers.make.com/mcp-server) at
|
|
8
|
+
author time — tool names and transports move.
|
|
9
|
+
|
|
10
|
+
## Transports
|
|
11
|
+
|
|
12
|
+
Two ways to authenticate the connection:
|
|
13
|
+
|
|
14
|
+
### OAuth (remote, recommended for end users)
|
|
15
|
+
|
|
16
|
+
Point the client at the hosted endpoint:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
https://mcp.make.com # stateless (default)
|
|
20
|
+
https://mcp.make.com/stream # streamable HTTP
|
|
21
|
+
https://mcp.make.com/sse # server-sent events
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The client runs an OAuth consent flow; the **scopes you grant at consent decide
|
|
25
|
+
which tools appear**. No token to manage by hand.
|
|
26
|
+
|
|
27
|
+
### MCP token (per-zone URL)
|
|
28
|
+
|
|
29
|
+
Generate an **MCP token** in Make (Profile → API/SDK) and embed it in a zoned URL:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
https://{zone}.make.com/mcp/u/{MCP_TOKEN}/stateless
|
|
33
|
+
https://{zone}.make.com/mcp/u/{MCP_TOKEN}/stream
|
|
34
|
+
https://{zone}.make.com/mcp/u/{MCP_TOKEN}/sse
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- `{zone}` is your org's zone (`eu1|eu2|us1|us2`, + `celonis`) — same **zone
|
|
38
|
+
trap** as the REST API: wrong zone = auth failure.
|
|
39
|
+
- The MCP token is **separate** from the REST API token.
|
|
40
|
+
|
|
41
|
+
### Timeout — pick the transport by run length
|
|
42
|
+
|
|
43
|
+
| Transport | Timeout | Use for |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `/stateless` | ~60 s | quick scenarios, simple clients |
|
|
46
|
+
| `/stream` | ~5 min 20 s | long-running scenarios |
|
|
47
|
+
| `/sse` | ~5 min 20 s | streaming clients |
|
|
48
|
+
|
|
49
|
+
A scenario that takes longer than 60 s on `/stateless` will time out — use
|
|
50
|
+
`/stream` or `/sse`.
|
|
51
|
+
|
|
52
|
+
## Tool tiers
|
|
53
|
+
|
|
54
|
+
Exact tool names change; confirm in the client's tool list. The **tiers** are
|
|
55
|
+
stable:
|
|
56
|
+
|
|
57
|
+
- **Run tools — all plans.** List the account's on-demand scenarios and execute
|
|
58
|
+
a chosen one with inputs, returning its output bundle. This is what lets an
|
|
59
|
+
agent *use* an automation you built.
|
|
60
|
+
- **Management tools — paid plans only.** View and modify scenarios,
|
|
61
|
+
connections, hooks, data stores, teams, and organizations — effectively the
|
|
62
|
+
REST CRUD surfaced as MCP tools. On a free plan these do not appear.
|
|
63
|
+
|
|
64
|
+
On the OAuth transport, missing scopes (not just plan tier) can also hide tools.
|
|
65
|
+
|
|
66
|
+
## Client config sketches
|
|
67
|
+
|
|
68
|
+
Token transport (generic `mcpServers` block; adapt to your client):
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"make": {
|
|
74
|
+
"url": "https://eu2.make.com/mcp/u/${MAKE_MCP_TOKEN}/stream"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For stdio-only clients, bridge a streamable-HTTP URL to stdio with a proxy such
|
|
81
|
+
as `mcp-proxy`.
|
|
82
|
+
|
|
83
|
+
## Legacy local server
|
|
84
|
+
|
|
85
|
+
`integromat/make-mcp-server` is the **older local stdio** server. It runs as a
|
|
86
|
+
local process and exposes your on-demand scenarios as tools over stdio. It
|
|
87
|
+
predates the cloud server; prefer the cloud MCP unless you specifically need a
|
|
88
|
+
local, offline-ish process (e.g. an air-gapped client that cannot reach
|
|
89
|
+
`mcp.make.com`).
|
|
90
|
+
|
|
91
|
+
## Credits, not a free lunch
|
|
92
|
+
|
|
93
|
+
The MCP *server* is free, but every scenario an MCP call runs burns the same
|
|
94
|
+
**credits** as any other run. An agent that loops over a run tool can quietly
|
|
95
|
+
drain credits — cap it the way you would any autonomous consumer.
|
|
96
|
+
|
|
97
|
+
## When NOT to use MCP
|
|
98
|
+
|
|
99
|
+
If the operator is your own deterministic script/CI, the REST API v2 is simpler
|
|
100
|
+
and fully controllable — MCP earns its keep only when an **agent** is the one
|
|
101
|
+
driving Make.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: n8n
|
|
3
|
+
description: "Use when operating a live n8n instance programmatically — driving its public REST API (`{host}/api/v1`, `X-N8N-API-KEY`) or the n8n-mcp server to create, validate, test, activate/deactivate, list, update, or delete workflows and read executions, on self-host or `*.app.n8n.cloud`. Triggers: 'deploy this workflow to my n8n over the API', 'push my workflow JSON to n8n with curl', 'I set active:true in the create call but it stays inactive', 'connect n8n-mcp / n8n_create_workflow to Claude', 'validate and autofix my n8n workflow', 'run an n8n workflow by id from a script', 'delete a workflow via the API', 'automatiza n8n por API', 'desplega el workflow a n8n.cloud'. NOT designing the flow's trigger-step-error logic or hand-building the importable workflow JSON (that is automation-flows), NOT operating Make / Zapier / Power Automate (their own skills), NOT a typed API client with auth+pagination+retry (api-connector-builder), NOT the inbound webhook receiver in your own app (webhooks)."
|
|
4
|
+
tags: [n8n, automation, workflows, mcp, rest-api, no-code, integrations]
|
|
5
|
+
recommends: [automation-flows, automation-strategy, api-connector-builder, webhooks]
|
|
6
|
+
profiles: [full]
|
|
7
|
+
origin: risco
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# n8n — operate a live instance over its REST API and MCP
|
|
11
|
+
|
|
12
|
+
You already have a workflow *design* (the trigger→steps→error shape and the importable JSON).
|
|
13
|
+
This skill is the **operate** half: push that JSON into a running n8n, validate it, test it, flip it
|
|
14
|
+
live, watch its executions, and tear it down safely — all without touching the UI. n8n has the
|
|
15
|
+
richest programmatic story of the no-code platforms: a first-party REST API **plus** a mature MCP
|
|
16
|
+
server, both hitting the same instance.
|
|
17
|
+
|
|
18
|
+
Designing the flow itself (what fires it, how errors are handled, dedup) is **automation-flows** —
|
|
19
|
+
this skill *consumes* that skill's `references/n8n-workflow-json.md` payload; it does not re-teach
|
|
20
|
+
design.
|
|
21
|
+
|
|
22
|
+
## Connect first — REST API vs MCP
|
|
23
|
+
|
|
24
|
+
Two ways to drive the same instance. Pick by who is at the wheel.
|
|
25
|
+
|
|
26
|
+
| | **Public REST API** | **n8n-mcp** (czlonkowski, de-facto standard) |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| What it is | n8n's own HTTP API at `{host}/api/v1` | MCP server wrapping that API **+** offline node/expression knowledge |
|
|
29
|
+
| Best for | scripts, CI/CD, deterministic deploys, no extra dependency | an agent (Claude) building/fixing workflows in the loop — it can look up node schemas, then validate/autofix before it writes |
|
|
30
|
+
| Auth | API key in header `X-N8N-API-KEY` | management tools need `N8N_API_URL` + `N8N_API_KEY`; **node-knowledge tools need no auth** |
|
|
31
|
+
| Surface | identical on self-host **and** `*.app.n8n.cloud` | same underlying API; hosted trial at `dashboard.n8n-mcp.com` |
|
|
32
|
+
|
|
33
|
+
**Version reality (verify at author time — n8n moves fast):**
|
|
34
|
+
- API base is `{host}/api/v1`. Self-host ships interactive Swagger at `/api/v1/docs`; **cloud does not**.
|
|
35
|
+
- `POST /workflows/{id}/execute` (run-by-id) is **recent** (n8n PR #20234). Older instances lack it —
|
|
36
|
+
there, the only programmatic run is POSTing to a Webhook node's URL. It also takes **no custom input**.
|
|
37
|
+
- The API surface is the SAME whether you self-host or run on `*.app.n8n.cloud`; only the host differs.
|
|
38
|
+
|
|
39
|
+
### `.env`
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# host root only — you append /api/v1 for REST; n8n-mcp reads it whole
|
|
43
|
+
N8N_API_URL=https://your-instance.app.n8n.cloud # or N8N_HOST for self-host, e.g. http://localhost:5678
|
|
44
|
+
N8N_API_KEY=n8n_api_... # Settings → n8n API → Create an API key
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Never inline the key in a command that gets logged, and never put a *node* credential (Slack token,
|
|
48
|
+
etc.) in the workflow payload — reference it by the n8n **credential store** id/name (see
|
|
49
|
+
automation-flows' JSON schema). Full key-creation + self-host vs cloud + MCP install:
|
|
50
|
+
`references/auth-and-selfhost.md`.
|
|
51
|
+
|
|
52
|
+
## The payload you POST
|
|
53
|
+
|
|
54
|
+
The create/update body is exactly the automation-flows workflow JSON. Required top-level keys on
|
|
55
|
+
**create**: `name`, `nodes`, `connections`, `settings`. Build it per
|
|
56
|
+
`../automation-flows/references/n8n-workflow-json.md` — non-empty `nodes` with one trigger, a wired
|
|
57
|
+
`connections` map, `settings.errorWorkflow`, credentials referenced by store (never inlined).
|
|
58
|
+
|
|
59
|
+
**Node/expression essentials** (pointer, not a tutorial): node `type` is namespaced
|
|
60
|
+
(`n8n-nodes-base.webhook`), `typeVersion` must match a node version installed on the target instance
|
|
61
|
+
or activation/execution fails; field values use expressions like `={{ $json.email }}` or
|
|
62
|
+
`={{ $node["Webhook"].json.body.id }}`. If you are hand-authoring nodes, let n8n-mcp's node-knowledge
|
|
63
|
+
tools (`search_nodes`, `get_node_essentials`, `validate_node_operation`) fill in the exact property
|
|
64
|
+
shapes rather than guessing — that is the single biggest reason to drive via MCP.
|
|
65
|
+
|
|
66
|
+
## Dynamic lifecycle
|
|
67
|
+
|
|
68
|
+
create → **validate** → test → **activate** → manage → delete. A concrete sketch per step, curl and
|
|
69
|
+
n8n-mcp side by side.
|
|
70
|
+
|
|
71
|
+
### 1. Validate (do this BEFORE create)
|
|
72
|
+
|
|
73
|
+
REST has no validation endpoint — n8n only tells you at create/activate time. MCP does, so validate
|
|
74
|
+
first when it is available:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
n8n_validate_workflow { "workflow": { …the full JSON… } }
|
|
78
|
+
n8n_autofix_workflow { "workflow": { … } } # repairs common structural errors, returns fixed JSON
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 2. Create
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl -sS -X POST "$N8N_API_URL/api/v1/workflows" \
|
|
85
|
+
-H "X-N8N-API-KEY: $N8N_API_KEY" -H "Content-Type: application/json" \
|
|
86
|
+
-d @workflow.json # body = { name, nodes, connections, settings }
|
|
87
|
+
# → returns the created workflow WITH its "id" — capture it for every step below
|
|
88
|
+
```
|
|
89
|
+
```
|
|
90
|
+
n8n_create_workflow { "name": "...", "nodes": [ … ], "connections": { … }, "settings": { … } }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Test / dry-run
|
|
94
|
+
|
|
95
|
+
- **No input needed** → run by id (recent instances only): `POST /workflows/{id}/execute`.
|
|
96
|
+
- **Needs input** → the execute endpoint accepts none. Make the trigger a **Webhook node** and POST to
|
|
97
|
+
its URL (test URL `/webhook-test/<path>` while "Listen for test event" is armed; production
|
|
98
|
+
`/webhook/<path>` once active).
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
curl -sS -X POST "$N8N_API_URL/api/v1/workflows/$ID/execute" -H "X-N8N-API-KEY: $N8N_API_KEY"
|
|
102
|
+
curl -sS -X POST "$N8N_API_URL/webhook-test/my-path" -H "Content-Type: application/json" -d '{"foo":"bar"}'
|
|
103
|
+
```
|
|
104
|
+
```
|
|
105
|
+
n8n_test_workflow { "id": "$ID" }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 4. Activate — the step people miss
|
|
109
|
+
|
|
110
|
+
`active` in the create/update body is **read-only and silently ignored**. Setting `"active": true`
|
|
111
|
+
does nothing. You MUST call the separate endpoint:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
curl -sS -X POST "$N8N_API_URL/api/v1/workflows/$ID/activate" -H "X-N8N-API-KEY: $N8N_API_KEY"
|
|
115
|
+
curl -sS -X POST "$N8N_API_URL/api/v1/workflows/$ID/deactivate" -H "X-N8N-API-KEY: $N8N_API_KEY"
|
|
116
|
+
```
|
|
117
|
+
n8n-mcp deliberately does not expose activate/deactivate as tools (activation has live side effects).
|
|
118
|
+
Check the current tool list; if absent, call the REST `/activate` endpoint as above.
|
|
119
|
+
|
|
120
|
+
### 5. Manage
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
curl -sS "$N8N_API_URL/api/v1/workflows?limit=50" -H "X-N8N-API-KEY: $N8N_API_KEY" # list (paginate via nextCursor)
|
|
124
|
+
curl -sS "$N8N_API_URL/api/v1/workflows/$ID" -H "X-N8N-API-KEY: $N8N_API_KEY" # get
|
|
125
|
+
curl -sS -X PUT "$N8N_API_URL/api/v1/workflows/$ID" -H "X-N8N-API-KEY: $N8N_API_KEY" \
|
|
126
|
+
-H "Content-Type: application/json" -d @workflow.json # FULL replace
|
|
127
|
+
curl -sS "$N8N_API_URL/api/v1/executions?workflowId=$ID&limit=20" -H "X-N8N-API-KEY: $N8N_API_KEY"
|
|
128
|
+
```
|
|
129
|
+
```
|
|
130
|
+
n8n_list_workflows {} n8n_get_workflow { "id": "$ID" } n8n_executions { "workflowId": "$ID" }
|
|
131
|
+
n8n_update_full_workflow { "id": "$ID", "nodes": [ … ], "connections": { … } } # replace everything
|
|
132
|
+
n8n_update_partial_workflow { "id": "$ID", "operations": [ … ] } # atomic diff — preferred
|
|
133
|
+
n8n_health_check {} # confirm API reachable + which features the instance supports
|
|
134
|
+
```
|
|
135
|
+
`PUT` is a **full replace** — GET, mutate the whole object, PUT it back, or you drop the nodes you
|
|
136
|
+
omitted. n8n-mcp's `n8n_update_partial_workflow` applies a targeted, atomic batch instead (safer).
|
|
137
|
+
|
|
138
|
+
### 6. Delete — irreversible
|
|
139
|
+
|
|
140
|
+
`DELETE` is a **hard delete: no trash, no undo.** Export the current JSON first, every time.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
curl -sS "$N8N_API_URL/api/v1/workflows/$ID" -H "X-N8N-API-KEY: $N8N_API_KEY" > backup-$ID.json # export FIRST
|
|
144
|
+
curl -sS -X DELETE "$N8N_API_URL/api/v1/workflows/$ID" -H "X-N8N-API-KEY: $N8N_API_KEY"
|
|
145
|
+
```
|
|
146
|
+
```
|
|
147
|
+
n8n_get_workflow { "id": "$ID" } → save output → n8n_delete_workflow { "id": "$ID" }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Irreversibility rule:** never DELETE (or full-replace) a live workflow without exporting it first.
|
|
151
|
+
|
|
152
|
+
## Governance
|
|
153
|
+
|
|
154
|
+
If you expose n8n-mcp to an agent, lock down destructive tools with the `DISABLED_TOOLS` env var
|
|
155
|
+
(comma-separated), e.g. `DISABLED_TOOLS=n8n_delete_workflow,n8n_update_full_workflow`. Scope the API
|
|
156
|
+
key itself too — n8n supports scoped keys (e.g. grant `workflow:read` without `workflow:execute`).
|
|
157
|
+
Details in `references/n8n-mcp-tools.md`.
|
|
158
|
+
|
|
159
|
+
## Honesty / gotchas
|
|
160
|
+
|
|
161
|
+
- **`active` and `tags` are read-only on create/update** — ignored in the body; activate/tag via the
|
|
162
|
+
dedicated endpoints. This is the #1 "why is my workflow inactive" bug.
|
|
163
|
+
- **`/workflows/{id}/execute` takes no custom input** — for runtime params, trigger a Webhook workflow
|
|
164
|
+
by POSTing to its URL. Also, it is a newer endpoint; older instances 404 it.
|
|
165
|
+
- **`DELETE` and `PUT` are destructive** — hard delete (no trash) and full replace. Export first; prefer
|
|
166
|
+
`n8n_update_partial_workflow` for edits.
|
|
167
|
+
- **`typeVersion` must exist on the target** — a node version the instance doesn't have fails only at
|
|
168
|
+
activate/execute time, not at create. Validate (MCP) or test before activating.
|
|
169
|
+
- **Credential secrets are not fully manageable over the public API** — you can reference existing
|
|
170
|
+
credentials by id/name and create some, but you cannot read secrets back; provision credentials in
|
|
171
|
+
the UI / n8n-mcp `n8n_manage_credentials` and reference them.
|
|
172
|
+
- **Cloud has no Swagger** — `/api/v1/docs` is self-host only; on cloud, work from the docs.
|
|
173
|
+
- **Activation can succeed via API where the UI would block it** — the public API historically skips a
|
|
174
|
+
few UI-side activation validations, so a workflow can be "active" yet non-functional. Test it live.
|
|
175
|
+
|
|
176
|
+
## Related skills
|
|
177
|
+
|
|
178
|
+
- **automation-flows** — *design* the flow and produce the importable JSON this skill deploys. Design
|
|
179
|
+
vs operate boundary: they decide the trigger/steps/error path; you push it live. Start there if the
|
|
180
|
+
flow's logic isn't settled yet.
|
|
181
|
+
- **automation-strategy** — whether n8n is even the right platform (cost model, self-host vs cloud) vs
|
|
182
|
+
Make/Zapier/Power Automate.
|
|
183
|
+
- **make / zapier / power-automate** — the other platforms' operate stories (Zapier and Power Automate
|
|
184
|
+
can't create flows via API — n8n's edge).
|
|
185
|
+
- **api-connector-builder** — a generic typed HTTP client with auth/pagination/backoff, when the answer
|
|
186
|
+
is real code, not a workflow.
|
|
187
|
+
- **webhooks** — building the inbound receiver *in your own app*; here webhooks are just n8n triggers.
|
|
188
|
+
|
|
189
|
+
## Checklist
|
|
190
|
+
|
|
191
|
+
- [ ] `.env` has `N8N_API_URL`/`N8N_HOST` + `N8N_API_KEY` (key from Settings → n8n API); key not logged.
|
|
192
|
+
- [ ] Payload has `name`, `nodes` (one trigger), `connections`, `settings` per automation-flows' schema;
|
|
193
|
+
node credentials referenced by store, never inlined.
|
|
194
|
+
- [ ] Validated (`n8n_validate_workflow` / `n8n_autofix_workflow`) before create when MCP is available.
|
|
195
|
+
- [ ] Created via `POST /workflows` or `n8n_create_workflow`; captured the returned `id`.
|
|
196
|
+
- [ ] Tested — `execute`-by-id (no input) or POST to the webhook URL (with input) — and the run succeeded.
|
|
197
|
+
- [ ] Activated via `POST /workflows/{id}/activate` (NOT `active:true` in the body).
|
|
198
|
+
- [ ] Before any DELETE or full-replace: exported the current JSON (hard delete, no trash).
|
|
199
|
+
- [ ] If MCP is exposed to an agent: `DISABLED_TOOLS` set and/or the API key scoped.
|
|
200
|
+
|
|
201
|
+
## References
|
|
202
|
+
|
|
203
|
+
- `references/rest-api-cheatsheet.md` — every workflow/execution endpoint with curl, pagination, scopes.
|
|
204
|
+
- `references/n8n-mcp-tools.md` — the management + node-knowledge tool list, the auth split, `DISABLED_TOOLS`.
|
|
205
|
+
- `references/auth-and-selfhost.md` — API-key creation, self-host vs cloud, Swagger, installing/pointing n8n-mcp.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Evals — n8n
|
|
2
|
+
|
|
3
|
+
`cases.yaml` has three groups. `should_trigger` covers the operate tasks this skill owns: deploying a
|
|
4
|
+
workflow JSON over the REST API, the read-only-`active` gotcha, wiring n8n-mcp management tools,
|
|
5
|
+
running a workflow by id, hard-delete safety, and validate/autofix — with a Spanish phrasing. Each
|
|
6
|
+
`should_not_trigger` names a real sibling: flow design + importable JSON → automation-flows,
|
|
7
|
+
platform/cost choice → automation-strategy, another platform → make, a typed code client →
|
|
8
|
+
api-connector-builder, an in-app inbound receiver → webhooks. `capability` is one end-to-end deploy
|
|
9
|
+
scenario whose `must_include` rubric pins the current API/MCP calls, the honesty limits (read-only
|
|
10
|
+
`active`, no-input `execute`), and the irreversibility rule (export before hard delete).
|
|
11
|
+
|
|
12
|
+
No automated runner. Score by judgement: feed each `should_trigger`/`should_not_trigger` prompt to the
|
|
13
|
+
routing layer and confirm it activates or routes to the listed sibling; for `capability`, have the
|
|
14
|
+
skill produce the deploy plan/commands and check every `must_include` bullet by hand.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
skill: n8n
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Push my workflow JSON to n8n over the API with curl and turn it on."
|
|
5
|
+
why: Canonical operate task — POST /workflows then the separate /activate endpoint. Core deliverable.
|
|
6
|
+
- prompt: "I set active:true in my POST to /api/v1/workflows but the workflow stays inactive. Why?"
|
|
7
|
+
why: The read-only-active gotcha — active/tags are ignored on create; must call /workflows/{id}/activate.
|
|
8
|
+
- prompt: "Wire n8n-mcp into Claude Code so it can call n8n_create_workflow and n8n_update_partial_workflow against my instance."
|
|
9
|
+
why: MCP operate path — configuring the management tier with N8N_API_URL + N8N_API_KEY.
|
|
10
|
+
- prompt: "How do I run an n8n workflow by its id from a shell script, and can I pass it input data?"
|
|
11
|
+
why: POST /workflows/{id}/execute (recent) plus the no-custom-input limit → webhook trigger for params.
|
|
12
|
+
- prompt: "Delete this workflow from my n8n via the API — is there an undo?"
|
|
13
|
+
why: Hard-delete irreversibility; must export (GET) first, no trash.
|
|
14
|
+
- prompt: "desplega este workflow a mi n8n.cloud por la API y valídalo antes de activarlo"
|
|
15
|
+
why: Spanish; programmatic deploy + validate + activate against cloud — same REST surface.
|
|
16
|
+
- prompt: "Validate and autofix my n8n workflow before I create it, then list its executions."
|
|
17
|
+
why: n8n_validate_workflow / n8n_autofix_workflow then n8n_executions — MCP management lifecycle.
|
|
18
|
+
|
|
19
|
+
should_not_trigger:
|
|
20
|
+
- prompt: "Design an n8n flow: Stripe payment → Notion row → Slack, with an error path and dedup. Give me the importable JSON."
|
|
21
|
+
route_to: automation-flows
|
|
22
|
+
why: Designing the trigger/steps/error shape and producing the JSON is automation-flows; this skill only deploys/operates that JSON.
|
|
23
|
+
- prompt: "Should I use n8n, Make, or Zapier for 50k runs a month, and self-host or cloud?"
|
|
24
|
+
route_to: automation-strategy
|
|
25
|
+
why: Platform/cost-model selection, not operating a specific live n8n instance.
|
|
26
|
+
- prompt: "Create this scenario in my Make account programmatically."
|
|
27
|
+
route_to: make
|
|
28
|
+
why: Operating a different platform (Make) — its own skill; Make also has no create-via-API story like n8n's.
|
|
29
|
+
- prompt: "Write a TypeScript client for the Acme REST API with API-key auth, cursor pagination, and exponential backoff."
|
|
30
|
+
route_to: api-connector-builder
|
|
31
|
+
why: A typed HTTP client in code, not driving n8n's API or MCP.
|
|
32
|
+
- prompt: "Build the endpoint in my Express app that receives and verifies inbound webhook signatures."
|
|
33
|
+
route_to: webhooks
|
|
34
|
+
why: An inbound receiver in the user's own app; here webhooks are only n8n triggers, not something this skill builds.
|
|
35
|
+
|
|
36
|
+
capability:
|
|
37
|
+
- scenario: "User has an importable n8n workflow JSON (webhook trigger → HTTP node → Slack) and wants it deployed to their n8n.cloud instance: created, tested, activated, and later safely removed — via the REST API and/or n8n-mcp."
|
|
38
|
+
must_include:
|
|
39
|
+
- "Reads N8N_API_URL/N8N_HOST + N8N_API_KEY from env; key from Settings → n8n API; sends it as the X-N8N-API-KEY header (not a bearer token)."
|
|
40
|
+
- "Builds the create body per automation-flows' n8n-workflow-json schema (name, nodes, connections, settings); node credentials referenced by the credential store, never inlined."
|
|
41
|
+
- "Creates with POST /workflows (or n8n_create_workflow) and captures the returned id for subsequent calls."
|
|
42
|
+
- "States that active (and tags) are read-only on create/update and activates with a separate POST /workflows/{id}/activate."
|
|
43
|
+
- "Notes POST /workflows/{id}/execute takes no custom input (and is a recent endpoint), so runtime params require POSTing to a Webhook node URL."
|
|
44
|
+
- "Exports the workflow (GET /workflows/{id}) before any DELETE, and states DELETE is a hard delete with no trash."
|
|
45
|
+
- "When driving via MCP, validates/autofixes (n8n_validate_workflow / n8n_autofix_workflow) before create; notes management tools need the two env vars while node-knowledge tools do not."
|