@awesomate/hosting-mcp 0.87.0 → 0.88.6

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 (42) hide show
  1. package/dist/index.js +51 -141
  2. package/package.json +2 -1
  3. package/skill/CHANGELOG.json +43 -0
  4. package/skill/awesomate-app-builder/SKILL.md +13 -8
  5. package/skill/awesomate-app-builder/references/node-recipes.md +3 -2
  6. package/skill/awesomate-app-builder/references/stack-decision.md +4 -3
  7. package/skill/awesomate-bookings/SKILL.md +9 -6
  8. package/skill/awesomate-database/SKILL.md +52 -62
  9. package/skill/awesomate-hosting/SKILL.md +1 -1
  10. package/skill/awesomate-n8n/SKILL.md +165 -108
  11. package/skill/awesomate-n8n/evals/n8n-agent-build/graders/grader.md +2 -1
  12. package/skill/awesomate-n8n/references/ai-agents.md +10 -8
  13. package/skill/awesomate-n8n/references/datatables.md +46 -66
  14. package/skill/awesomate-n8n/references/error-handling.md +5 -5
  15. package/skill/awesomate-n8n/references/n8n-agents.md +10 -9
  16. package/skill/awesomate-n8n/references/onebrain.md +4 -4
  17. package/skill/awesomate-n8n/references/platform-notes.md +13 -13
  18. package/skill/awesomate-n8n/references/possibilities.md +12 -11
  19. package/skill/awesomate-n8n/references/testing-policy.md +51 -47
  20. package/skill/awesomate-n8n/references/troubleshooting.md +15 -16
  21. package/skill/awesomate-n8n/references/webhook-pages.md +5 -5
  22. package/skill/awesomate-n8n/references/wp-form-handler.md +6 -4
  23. package/skill/awesomate-seo/SKILL.md +15 -8
  24. package/skill/awesomate-seo/references/ai-discoverability.md +40 -26
  25. package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +0 -31
  26. package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +0 -1
  27. package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +0 -30
  28. package/skill/awesomate-n8n/evals/build-form-email/prompt.md +0 -1
  29. package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +0 -32
  30. package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +0 -2
  31. package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +0 -27
  32. package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +0 -2
  33. package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +0 -35
  34. package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +0 -2
  35. package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +0 -27
  36. package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +0 -2
  37. package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +0 -26
  38. package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +0 -3
  39. package/skill/awesomate-n8n/evals/webhook-page-build/graders/grader.md +0 -36
  40. package/skill/awesomate-n8n/evals/webhook-page-build/prompt.md +0 -1
  41. package/skill/awesomate-n8n/references/rest-fallback.md +0 -77
  42. package/skill/awesomate-n8n/references/upgrade-loop.md +0 -98
@@ -127,14 +127,16 @@ n8n's chat widget can embed the agent on any site. chatTrigger config:
127
127
  - CORS `allowedOrigins`: no trailing slashes, no spaces after commas.
128
128
  - No structured output parser on the final agent (see above).
129
129
 
130
- ## Test and deploy
131
-
132
- - E2E = activate + production webhook + poll executions: `awesomate_n8n_test`
133
- verify end-to-end: `awesomate_n8n_executions {workflowId}` to find the run,
134
- then `awesomate_n8n_executions {executionId, debug: true}` for node-by-node
135
- detail.
136
- — `awesomate_n8n_deploy {action:"promote"}` preserves webhookIds.
137
- - `saveExecutionProgress` stays FALSE (hub enforces; quadratic-write
130
+ ## Test and publish
131
+
132
+ - E2E = publish + production webhook + poll executions. Publish through the
133
+ n8n MCP server, fire the production webhook (or the n8n server's execute
134
+ tool), then `awesomate_n8n_executions {workflowId}` to find the run and
135
+ `awesomate_n8n_executions {executionId, debug: true}` for node-by-node
136
+ detail.
137
+ - A change to a live agent workflow goes onto its own id (SKILL.md §4); a
138
+ copy mints new webhookIds.
139
+ - `saveExecutionProgress` stays FALSE (set it yourself; quadratic-write
138
140
  incident). Agent/tool loops around `splitInBatches` need an
139
141
  `executionTimeout`.
140
142
  - Agent + chat workflows also run their published version — republish after
@@ -1,8 +1,11 @@
1
- # Datatables — client-side playbook
1
+ # Datatables: client-side playbook
2
2
 
3
3
  n8n data tables: small operational stores a workflow reads/writes at runtime.
4
4
  Read with `awesomate_n8n_inspect {what: "datatables"}` (tables, columns, row
5
- counts). Write with `awesomate_n8n_datatable_write` (Support Plus+ plans only).
5
+ counts, rows). Tables are created and edited in n8n itself: the user opens
6
+ **Data tables** in their n8n's left menu, or Claude creates one through the
7
+ n8n MCP server when that server offers a data-table tool. No Awesomate tool
8
+ creates or writes a table.
6
9
 
7
10
  ## Right store or wrong store
8
11
 
@@ -12,94 +15,71 @@ counts). Write with `awesomate_n8n_datatable_write` (Support Plus+ plans only).
12
15
  | Task queue / retry list a workflow drains | Datatable |
13
16
  | Lookup map (SKU→label, email→owner) | Datatable |
14
17
  | Cursor/state between runs (last-synced timestamp) | Datatable |
15
- | Real app data (users, orders, content) | The app's own database — never a datatable |
18
+ | Real app data (users, orders, content) | The app's own database, never a datatable |
16
19
  | Analytics, event history, anything unbounded | External store (app DB, sheet, warehouse) |
17
20
 
18
21
  Rule of thumb: bounded row count, flat rows, no joins, consumed by the
19
- automation itself. Instance cap is 50 tables (`datatable_cap_reached`), and
20
- creates have a daily plan quota (`quota_exceeded` — limits in
21
- `awesomate_n8n_context`).
22
+ automation itself. n8n caps an instance at 50 tables.
22
23
 
23
- ## Creating — pass workflowId
24
-
25
- ```
26
- awesomate_n8n_datatable_write {action: "create", name, columns: [{name, type?}], workflowId}
27
- ```
24
+ ## Creating: same project as the workflow
28
25
 
29
26
  - **Datatables resolve PER PROJECT at runtime.** A workflow in project A
30
27
  referencing a table in project B fails on every run with
31
- `Could not find the data table: '<id>'` — while the table, its columns, and
28
+ `Could not find the data table: '<id>'` while the table, its columns, and
32
29
  permissions are all perfectly intact. When the id matches and structure
33
30
  looks fine, the project link is what's broken.
34
- - **Pass `workflowId` whenever the table serves a specific workflow** (nearly
35
- always). The table is then moved into that workflow's owner project —
36
- co-location is verified, never assumed.
37
- - Without `workflowId` the server co-locates only when exactly one project
38
- owns your Claude Code drafts. Otherwise the response carries a
39
- `projectWarning` ("CLI drafts span N projects — pass workflowId…" or
40
- "workflowId … has no owner project — table left where n8n placed it").
41
- **Treat `projectWarning` as a failed co-location**: recreate with the right
42
- `workflowId` before inserting any rows.
43
- - Column `type`: `string` | `number` | `boolean` | `date` (default `string`).
44
- Column names: letters/digits/underscores, starting with a letter, no
45
- spaces — n8n's row API references columns bare, so a spaced name is
46
- unwritable even though PG would accept it.
47
- - Design the full column set up front — schema is effectively frozen (next
48
- section).
49
-
50
- ## Schema is immutable over REST
51
-
52
- n8n's REST API cannot alter a table. `action: "add_column"` exists but runs a
53
- direct database write, so it additionally requires the account's
54
- `allow_pg_writes` consent — ON by default, and NOT client-toggleable: a
55
- `consent_required` here means Awesomate disabled it for this account, so the
56
- remediation is recreating the table with the full column set, or asking
57
- Awesomate support to re-enable direct database writes.
58
- There is no rename, drop, or retype at all. Wrong schema and no PG consent →
59
- create a new table, migrate rows, repoint the workflow.
60
-
61
- ## Writes only touch self-created tables
62
-
63
- `insert` / `update` / `delete_rows` / `add_column` work only on tables created
64
- through Claude Code. Anything else → `403 not_self_created` — including tables
65
- provisioned by Awesomate template deploys. Those belong to managed
66
- automations; do not work around the refusal. Reads are unrestricted:
67
- `awesomate_n8n_inspect` lists every table.
68
-
69
- ## Row operations
70
-
71
- | action | Requires | Notes |
72
- |---|---|---|
73
- | `insert` | `rows`: 1–100 objects | Chunk larger batches |
74
- | `update` | non-empty `filter` + `data` object | `data` is one object, not an array |
75
- | `delete_rows` | non-empty `filter` — REQUIRED | There is deliberately no delete-all. To empty a table, delete by filter or recreate it |
31
+ - So the table is created **inside the project that owns the workflow**
32
+ (on a single-user instance that is the owner's personal project; check
33
+ `awesomate_n8n_workflows` for which project a workflow sits in). Tell the
34
+ user which project to be in when they create it, and read it back with
35
+ `awesomate_n8n_inspect` to confirm before the workflow references it.
36
+ - Design the full column set up front: n8n's REST API cannot alter a table,
37
+ so a column added later means the user does it in n8n's Data tables UI or
38
+ the table is recreated. Column `type`: `string` | `number` | `boolean` |
39
+ `date` (default `string`). Column names: letters/digits/underscores,
40
+ starting with a letter, no spaces (n8n's row API references columns bare,
41
+ so a spaced name is unwritable even though PG would accept it).
42
+ - Reference tables **by name** in the Data table node, never by id: a
43
+ rebuilt table keeps its name and gets a new id.
44
+ - Walk the user through it in their words: "open Data tables, click Add,
45
+ name it `sent_invoices`, add these three columns, done". Then confirm with
46
+ `awesomate_n8n_inspect {what: "datatables"}`.
47
+
48
+ ## Rows
49
+
50
+ Rows are written by the workflow itself (Data table node: insert, update,
51
+ delete with a filter) and read back with `awesomate_n8n_inspect`. To put
52
+ seed rows in by hand, the user pastes them in n8n's Data tables UI. There is
53
+ no delete-all; to empty a table, delete by filter or recreate it.
54
+
55
+ Tables that arrived with an Awesomate template belong to that managed
56
+ automation: read them freely, never change their schema or rows.
76
57
 
77
58
  ## The dedupe gate pattern (rowNotExists)
78
59
 
79
- Insert-if-absent as a barrier before side effects — the main reason a
80
- datatable exists in a client workflow:
60
+ Insert-if-absent as a barrier before side effects: the main reason a
61
+ datatable exists in a client workflow.
81
62
 
82
63
  1. Table with one key column (e.g. `event_id` string) plus any audit columns.
83
64
  2. In the workflow, BEFORE the side effect (email, API call, charge): Data
84
- table node with the **row-does-not-exist** operation matching the key —
85
- only unseen items pass.
65
+ table node with the **row-does-not-exist** operation matching the key.
66
+ Only unseen items pass.
86
67
  3. Insert the key immediately after the gate, BEFORE the side effect.
87
68
  Insert-first gives at-most-once (right for emails and charges);
88
69
  insert-after gives at-least-once (duplicates on crash/retry).
89
- 4. The gate and insert are separate node steps, not a transaction — a webhook
70
+ 4. The gate and insert are separate node steps, not a transaction: a webhook
90
71
  delivered twice in the same instant can pass both. Acceptable for dedupe;
91
72
  not a locking primitive.
92
73
 
93
74
  Queue-drain workflows (`splitInBatches` over a table) need `executionTimeout`
94
- set, and `saveExecutionProgress` stays FALSE — both fleet invariants.
75
+ set, and `saveExecutionProgress` stays FALSE. Both are platform invariants
76
+ you keep yourself.
95
77
 
96
78
  ## Failure decode
97
79
 
98
80
  | Symptom | Meaning | Fix |
99
81
  |---|---|---|
100
- | `Could not find the data table: '<id>'` at runtime | Project scope, not existence | Recreate/move the table with `workflowId`; check `awesomate_n8n_inspect {what: "datatables"}` vs the workflow's project |
101
- | `403 not_self_created` | Table wasn't created through Claude Code | Create your own table; never write agency tables |
102
- | `consent_required` on add_column | `allow_pg_writes` disabled for this account (not client-toggleable) | Recreate with the full schema, or ask Awesomate support |
103
- | `409 column_exists` | Column name collision | Pick another name; check current columns via inspect |
104
- | `429 datatable_cap_reached` / `quota_exceeded` | 50-table cap or daily create quota | Stop; reuse or delete tables, or wait for the daily reset |
105
- | `501 datatables_unsupported` | Instance's n8n version predates data tables | No datatable path — use an external store |
82
+ | `Could not find the data table: '<id>'` at runtime | Project scope, not existence | Recreate the table inside the workflow's project; check `awesomate_n8n_inspect {what: "datatables"}` vs the workflow's project |
83
+ | Data table node cannot see a column | Column name has a space or starts with a digit | Rename it in n8n's Data tables UI |
84
+ | Table count stuck at 50 | n8n's per-instance cap | Reuse or delete tables |
85
+ | Data tables missing from n8n's menu | Instance's n8n version predates data tables | No datatable path; use an external store |
@@ -61,12 +61,12 @@ Two nodes:
61
61
  `[Automation failed] {{ $json.workflow.name }}`, body with the error
62
62
  message, the node that failed, and the execution URL so they can open it.
63
63
 
64
- Build it through the normal loop (validate → create_draft → approval →
65
- activate), then set `settings.errorWorkflow` on each production workflow via
66
- `update_draft`/promote. One error workflow can serve every workflow on the
67
- instance — build it once, point everything at it.
64
+ Build it through the normal loop (SKILL.md §3, through the n8n MCP server),
65
+ then set `settings.errorWorkflow` on each production workflow with the n8n
66
+ server's update tool and republish each one. One error workflow can serve
67
+ every workflow on the instance: build it once, point everything at it.
68
68
 
69
- Test it honestly: you can't fake a failure through `awesomate_n8n_test`
69
+ Test it honestly: you can't fake a failure with a test fire
70
70
  without breaking something, so tell the user what will happen ("if any of
71
71
  these fail, you'll get an email like this") and verify the error workflow
72
72
  itself runs by executing it against a sample payload where possible.
@@ -10,7 +10,7 @@ Four different things get called an agent. Pick before building:
10
10
  | The user wants… | Build | Tool |
11
11
  |---|---|---|
12
12
  | An assistant they set up once and talk to **in Slack, Telegram, Linear, Discord, Teams or n8n chat**, run **on a schedule**, or call from several workflows; it decides its own steps | **n8n Agent** (this file) | `awesomate_n8n_agents` |
13
- | A fixed trigger → steps → result, with an LLM as one step | Workflow with an AI Agent node | `awesomate_n8n_deploy` + [ai-agents.md](ai-agents.md) |
13
+ | A fixed trigger → steps → result, with an LLM as one step | Workflow with an AI Agent node | The n8n MCP server (SKILL.md §3) + [ai-agents.md](ai-agents.md) |
14
14
  | A website chat that answers ONLY from their content, with citations | Knowledge agent | awesomate-knowledge skill |
15
15
  | One of Awesomate's ready-made chat agents | Template bundle | `awesomate_n8n_library` |
16
16
 
@@ -95,10 +95,10 @@ build → test → wrap-up.
95
95
  - Channels (Slack and so on) are NOT config. Use `update_agent_integration`.
96
96
  5. **Validate.** `validate_agent {agentId}` → fix every error.
97
97
  `incompatible_reference` with `no_supported_trigger` means that workflow
98
- can't be a tool. `not_published` means it must be active first. On Support
99
- Plus and above, activate it with `awesomate_n8n_deploy {action:"activate"}`
100
- after the user's yes (the hub's agency-workflow guards apply there). On
101
- Essentials the client switches it on in n8n themselves.
98
+ can't be a tool. `not_published` means it must be active first: publish it
99
+ through the n8n MCP server's publish tool after the user's yes (never a
100
+ workflow Awesomate manages for them), or the client switches it on in n8n
101
+ themselves.
102
102
  6. **Test.** `call_agent {agentId, request:{type:"message", message}}` with
103
103
  one representative message. To continue the same conversation, pass the
104
104
  `sessionId` it returned. Approval-gated tools come back as a pending
@@ -134,7 +134,7 @@ and the agent never holds any keys.
134
134
  description is the only thing the agent uses to choose the tool, so write
135
135
  it like an instruction.
136
136
  - Need a new tool workflow? Build it with the normal workflow loop
137
- (`awesomate_n8n_deploy`) first, test it, then attach it.
137
+ (SKILL.md §3, through the n8n MCP server) first, test it, then attach it.
138
138
  - A data table is not usable just because it exists. Attach it as a node
139
139
  tool (`n8n-nodes-base.dataTable`, found via `search_nodes`).
140
140
 
@@ -158,9 +158,10 @@ It targets the **published** agent and returns `text`,
158
158
 
159
159
  ## Guard rails (enforced by the hub)
160
160
 
161
- - Only the agent tools and the read-only discovery tools are relayed. n8n's
162
- workflow-writing MCP tools are NOT. Workflows still go through
163
- `awesomate_n8n_deploy`, with its drafts, promote and rollback.
161
+ - Only the agent tools and the read-only discovery tools are relayed through
162
+ `awesomate_n8n_agents`; n8n's workflow-writing MCP tools are NOT. Workflows
163
+ are written over the user's OWN connection to the same n8n MCP server
164
+ (SKILL.md §3), never through the hub.
164
165
  - An agent's config cannot attach a workflow Awesomate manages for the client,
165
166
  the n8n node, or any node using an n8n API credential (`403
166
167
  agent_tool_blocked`): calling the agent would run them. Use one of the
@@ -28,8 +28,8 @@ answer), load the **awesomate-onebrain** skill too.
28
28
  (hub Settings, Integrations, 1Brain). For an agent, use the credential of
29
29
  the person the agent answers to (its supervisor): the agent can never see
30
30
  more than that person.
31
- 4. **Validation false positive:** `awesomate_n8n_deploy {action:'validate'}`
32
- and `awesomate_n8n_node_docs` do not know CUSTOM nodes and report the 1Brain
31
+ 4. **Validation false positive:** `awesomate_n8n_node_docs validate_node`
32
+ does not know CUSTOM nodes and reports the 1Brain
33
33
  node as unknown. Expected; do not "fix" it. The node catalog has no schema
34
34
  for it either: this page is the reference.
35
35
 
@@ -205,8 +205,8 @@ before. To bring one back to life:
205
205
  4. Any other old operation says "This 1Brain operation was retired": pick a new
206
206
  one in the node.
207
207
 
208
- Change a live workflow through the upgrade loop
209
- ([upgrade-loop.md](upgrade-loop.md)), never in place.
208
+ Change a live workflow on its own id through the n8n MCP server (SKILL.md
209
+ §4), tested on a copy first, never by activating a copy in its place.
210
210
 
211
211
  ## 6. The no-code route: MCP Client Tool
212
212
 
@@ -99,23 +99,23 @@ trust this file.
99
99
  and its permissions are all perfectly intact. Every structural check
100
100
  passes; only the project link is wrong. **When the ID matches and
101
101
  permissions are fine, check scope, not existence.**
102
- 21. **Create tables through the hub, threaded to the workflow.**
103
- `awesomate_n8n_datatable_write {action: "create"}` co-locates the table
104
- with the project that owns the client's drafts, and accepts `workflowId`
105
- to target a specific workflow's owner project instead. Pass it whenever
106
- the consuming workflow is known. Datatable writes are Support Plus+.
102
+ 21. **Create tables inside the workflow's project.** Tables are made in
103
+ n8n itself (Data tables in the left menu, while in the project that owns
104
+ the workflow), or through the n8n MCP server when it offers a data-table
105
+ tool. No Awesomate tool creates one. Read the result back with
106
+ `awesomate_n8n_inspect {what: "datatables"}` and reference it by name.
107
107
  22. List existing tables (ids, columns, rows) with
108
108
  `awesomate_n8n_inspect {what: "datatables"}` before creating duplicates.
109
109
 
110
- ## Deploy & validation
110
+ ## Publishing & validation
111
111
 
112
- 23. **Never activate a copy to replace a live workflow.**
113
- `awesomate_n8n_deploy {action: "promote"}` preserves webhookIds;
114
- activating a duplicate mints new ones and silently breaks every external
115
- caller. E2E verification = activate, hit the production webhook, poll
116
- `awesomate_n8n_executions`.
117
- 24. **Known validation false positives** (via `awesomate_n8n_deploy
118
- {action: "validate"}` or `awesomate_n8n_node_docs validate_node`):
112
+ 23. **Never activate a copy to replace a live workflow.** Change the live
113
+ one on its own id through the n8n MCP server and republish it (SKILL.md
114
+ §4); activating a duplicate mints new webhookIds and silently breaks
115
+ every external caller. E2E verification = publish, hit the production
116
+ webhook, poll `awesomate_n8n_executions`.
117
+ 24. **Known validation false positives** (via `awesomate_n8n_node_docs
118
+ validate_node`):
119
119
  community/CUSTOM nodes report "unknown" (expected — see variant gating,
120
120
  rule 3); graph cycles flag `valid: false`, but cycle-based polling loops
121
121
  are legitimate. Filter known false positives — don't "fix" a working
@@ -89,8 +89,8 @@ and ground them in their numbers, never invent precision.
89
89
  nodes return `[{json:{...}}]`, `saveExecutionProgress` stays false,
90
90
  webhook trigger (explicit path) instead of formTrigger. Details:
91
91
  [platform-notes.md](platform-notes.md).
92
- - Datatable-backed ideas: only when `counts.datatables` is non-null;
93
- writes need Support Plus+ (`awesomate_n8n_datatable_write`); tables
92
+ - Datatable-backed ideas: only when `counts.datatables` is non-null; the
93
+ user creates tables in n8n's Data tables (no Awesomate tool does); tables
94
94
  resolve per project at runtime.
95
95
 
96
96
  ## Community templates — importable starting points
@@ -99,17 +99,18 @@ Search by the user's actually-connected services, not by the idea's topic:
99
99
 
100
100
  - `awesomate_n8n_node_docs {tool:'search_templates', args:{query: '<service>'}}`
101
101
  then `{tool:'get_template', args:{templateId}}` for the JSON.
102
- - A template is a starting point, not a deploy: strip nodes needing
103
- credentials the user lacks, then run the full build loop (validate →
104
- create_draft → test) from SKILL.md §2.
102
+ - A template is a starting point, not a finished workflow: strip nodes
103
+ needing credentials the user lacks, then run the full build loop
104
+ (SKILL.md §3) through the n8n MCP server.
105
105
  - 503 `node_catalog_unavailable` → skip templates this session and fall
106
106
  back to the vendored references in `references/vendor/`.
107
107
 
108
108
  ## Essentials plan
109
109
 
110
- `capabilities.builder: false` → reads work, builds need Support Plus+.
111
- Say so ONCE, honestly — "I can explain, diagnose, and design these, but
112
- building on your instance needs Support Plus+ (upgrade at
113
- hub.awesomate.ai/billing)" — then keep helping within reads: present the
114
- tiers as a roadmap, sketch designs, diagnose existing workflows. Do not
115
- repeat the upsell on every idea.
110
+ Reads, n8n Agents and building through the user's own n8n MCP server all
111
+ work on Essentials. What it lacks is Awesomate's template library:
112
+ `capabilities.templateInstall: false`. When an idea is best served by a
113
+ curated bundle, say so ONCE, honestly ("that one is a ready-made template,
114
+ which needs Support Plus+ (upgrade at hub.awesomate.ai/billing); I can build
115
+ you a version of it on your n8n instead"), then keep going. Do not repeat
116
+ the upsell on every idea.
@@ -1,54 +1,58 @@
1
1
  # Testing Policy (mandatory)
2
2
 
3
3
  A build or change is NOT done until the workflow has been EXECUTED on the
4
- user's instance and the execution INSPECTED node by node.
5
- `awesomate_n8n_deploy {action:'validate'}` checks structure, not behaviour —
6
- a passing validate plus a green final status is never "tested".
4
+ user's instance and the execution INSPECTED node by node. Node validation
5
+ (`awesomate_n8n_node_docs validate_node`) checks structure, not behaviour:
6
+ a passing validation plus a green final status is never "tested".
7
7
 
8
- Applies to: new builds (SKILL.md Phase 5), the upgrade loop (test the draft
9
- AND re-verify after promote), and any fix to a failing workflow. Only
10
- exception: the user explicitly waives testing for that specific task.
8
+ Applies to: new builds (SKILL.md Phase 5), changes to a live workflow (test
9
+ the change AND re-verify the live one after it is applied), and any fix to a
10
+ failing workflow. Only exception: the user explicitly waives testing for that
11
+ specific task.
11
12
 
12
13
  ## How a test runs
13
14
 
14
- There is no manual or pin-data execution on this platform. E2E = activate +
15
+ There is no manual or pin-data execution on this platform. E2E = publish +
15
16
  production webhook + poll executions:
16
17
 
17
- 1. Get approval to go live, then
18
- `awesomate_n8n_deploy {action:'activate', workflowId}` — production
19
- webhooks only respond while the workflow is active.
20
- 2. `awesomate_n8n_test {workflowId, payload}` — fires the PRODUCTION webhook
21
- with the `X-Awesomate-Test` header; returns the webhook response plus the
22
- `executionId` it caused. Real side effects DO run: emails actually send.
23
- Address them to the user's own email, prefix subjects `[TEST]`, use
24
- obviously fake data (`test+<runId>@…`, "TEST SUBMISSION"), and tell the
25
- user before firing. Non-email side effects (CRM writes, payments, SMS):
26
- STOP and ask first.
27
- 3. Inspect: `awesomate_n8n_executions {executionId, debug: true}` — read the
18
+ 1. Get approval to go live, then publish the workflow through the n8n MCP
19
+ server's publish tool (or the user switches it on in n8n). Production
20
+ webhooks only respond while the workflow is published.
21
+ 2. Run it. Three ways, pick the one that fits: the n8n MCP server's execute
22
+ tool; a POST to the PRODUCTION webhook URL (`{instanceUrl}/webhook/<path>`)
23
+ with the fixture as the body; or ask the user to trigger it themselves
24
+ (submit the form, send the email). Real side effects DO run: emails
25
+ actually send. Address them to the user's own email, prefix subjects
26
+ `[TEST]`, use obviously fake data (`test+<runId>@…`, "TEST SUBMISSION"),
27
+ and tell the user before firing. Non-email side effects (CRM writes,
28
+ payments, SMS): STOP and ask first.
29
+ 3. Find the run: `awesomate_n8n_executions {workflowId}` lists the newest
30
+ executions; the one you just caused is at the top.
31
+ 4. Inspect: `awesomate_n8n_executions {executionId, debug: true}`. Read the
28
32
  node list, per-node output, and which branches ran. When consent is off,
29
33
  debug data is unavailable and the call falls back to the non-debug
30
- detail (final status + failing node only) — state that in the report;
31
- you inspected less than usual.
34
+ detail (final status + failing node only). State that in the report; you
35
+ inspected less than usual.
32
36
 
33
37
  A green final status is not inspection. Do not enable
34
- `saveExecutionProgress` to get richer data — the hub enforces it FALSE
35
- (write-amplification incident); `debug: true` is the inspection path.
38
+ `saveExecutionProgress` to get richer data. Keep it FALSE on every workflow
39
+ you write (write-amplification incident); `debug: true` is the inspection
40
+ path.
36
41
 
37
42
  ## Fixtures (payload classes)
38
43
 
39
- The payload passed to `awesomate_n8n_test` is the POST body — the workflow
40
- sees it at `$json.body`. Run at minimum one of each class:
44
+ The body you POST is what the workflow sees at `$json.body`. Run at minimum
45
+ one of each class:
41
46
 
42
47
  | Class | Payload |
43
48
  |---|---|
44
49
  | happy-path | Realistic valid input, obviously fake values |
45
50
  | empty | `{}` / missing fields entirely |
46
51
  | malformed | Wrong types, missing required fields, junk strings |
47
- | error-`<api>` | Input that drives a named upstream API to a realistic error (nonexistent id → 404, bad enum → 400) — one per external dependency |
52
+ | error-`<api>` | Input that drives a named upstream API to a realistic error (nonexistent id → 404, bad enum → 400): one per external dependency |
48
53
 
49
- Quota: `limits` from `awesomate_n8n_context` caps daily test fires. Plan
50
- the fixture set before burning tests; a 429 `quota_exceeded` means the
51
- day's cap — tell the user, never retry-loop.
54
+ Awesomate sets no cap on test runs; the only cost is the side effects, so
55
+ plan the fixture set before firing rather than spraying the user's inbox.
52
56
 
53
57
  ## Error-path testing (required, minimum 3)
54
58
 
@@ -58,20 +62,20 @@ day's cap — tell the user, never retry-loop.
58
62
 
59
63
  Verify `onError` branches ACTUALLY ROUTE: in the execution's node list,
60
64
  confirm the error path's nodes ran and the post-failure happy-path nodes
61
- did not. Final status alone proves nothing — an execution whose error
65
+ did not. Final status alone proves nothing: an execution whose error
62
66
  branch routed can still finish green.
63
67
 
64
68
  ## Multi-trigger gotcha
65
69
 
66
- `awesomate_n8n_test` reaches the webhook trigger only. A schedule (or any
67
- non-webhook) branch NEVER runs from a test fire — it is untested unless
68
- exercised deliberately:
70
+ A webhook fire reaches the webhook trigger only. A schedule (or any
71
+ non-webhook) branch NEVER runs from it. It is untested unless exercised
72
+ deliberately:
69
73
 
70
- - Draft phase: temporarily wire the branch behind a webhook trigger via
71
- `awesomate_n8n_deploy {action:'update_draft'}`, test-fire it, then
72
- REMOVE the temporary trigger before promote.
73
- - Never promote or leave live a workflow carrying a temporary test
74
- trigger — it is a world-callable production URL.
74
+ - Temporarily wire the branch behind a webhook trigger (update the workflow
75
+ through the n8n MCP server), fire it, then REMOVE the temporary trigger
76
+ before the workflow stays live.
77
+ - Never leave live a workflow carrying a temporary test trigger: it is a
78
+ world-callable production URL.
75
79
  - If the branch cannot be exercised this way, list it under "needs human"
76
80
  in the report. Do not report it as tested.
77
81
 
@@ -91,7 +95,7 @@ their answer in the report.
91
95
  ## Test Report (required in every handoff)
92
96
 
93
97
  ```
94
- ## Test Report — <workflow> @ <instance>
98
+ ## Test Report: <workflow> @ <instance>
95
99
  Executed: <executionIds + payload class for each>
96
100
  Inspection: debug / non-debug fallback (consent off)
97
101
  Passed: <node paths verified, outputs checked>
@@ -102,14 +106,14 @@ Post-test state: restored ✔ (checklist below)
102
106
 
103
107
  ## Post-test state restore
104
108
 
105
- - [ ] Temporary test triggers/nodes removed from drafts
106
- - [ ] Test drafts deactivated; deleted via
107
- `awesomate_n8n_deploy {action:'delete_draft'}` unless the user wants
108
- them kept
109
- - [ ] `[TEST]` rows written to datatables during tests cleaned up
110
- (`awesomate_n8n_datatable_write {action:'delete_rows'}`)
111
- - [ ] Live workflow's activation state matches what the user expects
112
- - [ ] After a promote: the ORIGINAL production URL re-verified with a test
113
- fire (promote preserves webhookIds — the old URL must still respond)
109
+ - [ ] Temporary test triggers/nodes removed
110
+ - [ ] Throwaway test workflows unpublished, then deleted through the n8n
111
+ MCP server (with the user's OK) unless they want them kept
112
+ - [ ] `[TEST]` rows written to data tables during tests cleaned up (in
113
+ n8n's Data tables, or by the workflow's own delete step)
114
+ - [ ] Live workflow's published state matches what the user expects
115
+ - [ ] After a change to a live workflow: the ORIGINAL production URL
116
+ re-verified with a fire (the path is unchanged, so the old URL must
117
+ still respond)
114
118
  - [ ] User told which `[TEST]` artifacts (emails, records) to expect and
115
119
  discard
@@ -4,13 +4,14 @@ Diagnosis playbook. Work the flow top-to-bottom; do not jump to fixes before
4
4
  you have the failing execution's detail.
5
5
 
6
6
 
7
- ## "Could not create the draft" / writes fail while reads work
7
+ ## Template installs or activation fail while reads work
8
8
 
9
- If reads, `awesomate_n8n_context` and `validate` all succeed but every WRITE
10
- (create draft, activate, promote, test-fire) fails, the cause is almost always
11
- the account's stored n8n API key — not the hub, not Cloudflare, not the
12
- workflow JSON. Validation runs on Awesomate's side and never touches the
13
- instance, which is exactly why it keeps passing.
9
+ If reads and `awesomate_n8n_context` succeed but every hub WRITE (a template
10
+ `install`, `activate` or `test` through `awesomate_n8n_library`) fails, the
11
+ cause is almost always the account's stored n8n API key: not the hub, not
12
+ Cloudflare, not the template. Workflows you write through the n8n MCP server
13
+ use its own MCP key, not this one, so a refusal there is the n8n server's own
14
+ answer; read it as such.
14
15
 
15
16
  The server says so explicitly: HTTP **409** with `code: n8n_credential_invalid`.
16
17
  Older builds reported this as a 502, which reads like an outage — if you see a
@@ -65,22 +66,21 @@ rebuilt (a rebuilt instance shows 0 workflows and invalidates every old key).
65
66
  | Downstream fields empty/undefined on a webhook workflow | Webhook data lives at `$json.body`, not `$json` | Use `{{ $json.body.field }}`. #1 cause of "undefined" in webhook flows |
66
67
  | "access to environment variables is denied" | `$env` is blocked fleet-wide — in Code nodes AND regular field expressions | Use `{{ $vars.key \|\| 'fallback' }}` or a Config Set-node literal; never `$env` |
67
68
  | "$helpers is not defined" (works in editor preview, fails at run time) | Task runners strip `$helpers` from Code nodes | Move HTTP calls to HTTP Request nodes; process results in a downstream Code node |
68
- | "Could not find the data table: '<id>'" | PROJECT scope, not existence — datatables resolve within the workflow's own project at runtime | Check which project owns the table (`awesomate_n8n_inspect {what: "datatables"}`) vs the workflow. Recreate/move the table into the workflow's project (`awesomate_n8n_datatable_write`, Support Plus+). Reference tables by name, never by id |
69
+ | "Could not find the data table: '<id>'" | PROJECT scope, not existence: datatables resolve within the workflow's own project at runtime | Check which project owns the table (`awesomate_n8n_inspect {what: "datatables"}`) vs the workflow. The user recreates the table inside the workflow's project (n8n's Data tables). Reference tables by name, never by id |
69
70
  | Credential "could not be found" | Sharing/RBAC — the credential exists but is not shared with the workflow's project/owner. Almost never deletion | Verify it exists via `awesomate_n8n_inspect {what: "credentials"}`; user shares it to the project in the n8n editor |
70
- | Webhook URL returns 404 | Workflow not active — production webhook paths register only while active. Test URLs work only while the editor is listening | Activate via `awesomate_n8n_deploy`. Never activate a copy — `promote` preserves webhookIds |
71
+ | Webhook URL returns 404 | Workflow not active: production webhook paths register only while active. Test URLs work only while the editor is listening | Publish it through the n8n MCP server (or the user switches it on in n8n). Never activate a copy: change the live one on its own id (SKILL.md §4) |
71
72
  | Form URL 404s at its custom path | formTrigger ignores the custom `path`; forms serve only at `/form/<webhookId>` | Use a webhook trigger when a stable path matters |
72
73
  | "Unrecognized node type" / unknown node at activation | Community media node on an instance without the FFMPEG variant (Support Plus+ gate) | Check `awesomate_n8n_context` capabilities; upgrade variant or rebuild on core nodes. Note: static validation flagging `CUSTOM.*` nodes "unknown" is a false positive — trust activation, not the validator |
73
74
  | Output shows literal "[object Object]" | Expression resolves to an object where a string is expected | Drill to the scalar (`{{ $json.body.user.email }}`) or wrap in `JSON.stringify()` |
74
- | Workflow saved but never executes | Draft was never activated/published; saving is not publishing | `awesomate_n8n_deploy {action: "activate"}` (new) or `promote` (replacing a live one). E2E-verify: activate + hit the production webhook + poll executions |
75
+ | Workflow saved but never executes | Draft was never activated/published; saving is not publishing | Publish it through the n8n MCP server (a new workflow), or republish the live one after updating it. E2E-verify: publish + hit the production webhook + poll executions |
75
76
  | Code node output vanishes or breaks downstream | Not returning `[{ json: {...} }]`, or leftover template boilerplate | Return an array of `{json}` objects; check whether the node is unedited boilerplate |
76
77
  | Node config valid yesterday, "Invalid value for 'operation'" today | Partial update stripped the `operation` discriminator | Set `resource` + `operation` together in the same update; re-validate |
77
- | `crashed` status, hours-long runtime, loop workflow | `saveExecutionProgress: true` (quadratic writes — 2TB WAL incident) and/or no `executionTimeout` on a `splitInBatches` loop | Keep `saveExecutionProgress` FALSE (the hub enforces it); add `executionTimeout` to every loop workflow; bound rows per run |
78
- | `429 quota_exceeded` | Plan daily cap reached | STOP immediately. Do not retry-loop — tell the user the cap is hit; it resets daily or they upgrade. Limits are in `awesomate_n8n_context` |
78
+ | `crashed` status, hours-long runtime, loop workflow | `saveExecutionProgress: true` (quadratic writes, 2TB WAL incident) and/or no `executionTimeout` on a `splitInBatches` loop | Keep `saveExecutionProgress` FALSE (set it yourself; nothing enforces it for you); add `executionTimeout` to every loop workflow; bound rows per run |
79
79
 
80
80
  ## Verification after a fix
81
81
 
82
- - Re-run realistically: `awesomate_n8n_test {workflowId, payload}` for manual
83
- runs; for live paths, activate + POST the production webhook + poll
82
+ - Re-run realistically: the n8n MCP server's execute tool, a POST to the
83
+ production webhook, or the user's own trigger; then poll
84
84
  `awesomate_n8n_executions` until the new run appears.
85
85
  - Inspect the fixed run's data, not just its status — an `onError: continue`
86
86
  branch can turn a failure into a "successful" run carrying an `error` key.
@@ -91,11 +91,10 @@ rebuilt (a rebuilt instance shows 0 workflows and invalidates every old key).
91
91
  are fine: list it, read executions, run `debug`, and explain the failure to
92
92
  the user freely. Switching it off or on is allowed when the user asks (the
93
93
  reply carries `built_by_us`; tell them what stops while it's off). Do NOT
94
- attempt any other change (`update_draft`, `promote`, `rollback`, `test`,
95
- datatable writes): those go through Awesomate support.
94
+ attempt any other change (editing it through the n8n MCP server, test
95
+ fires, data table changes): those go through Awesomate support.
96
96
  Summarize your diagnosis so the user can paste it into their ticket.
97
97
  - `403 consent_required` the user declines to enable — diagnose from the
98
98
  execution summary only; say plainly what deeper access would show.
99
- - `429 quota_exceeded` — never burn remaining quota on retries.
100
99
  - Fix requires the FFMPEG variant or a higher plan — explain the gate; the
101
100
  upgrade happens in the hub, not here.
@@ -5,11 +5,11 @@ mini-app the user saves to their home screen, an approval page that resumes a pa
5
5
  workflow, a live status page. No hosting, no CORS, no deploy pipeline: the page exists
6
6
  while the workflow is active.
7
7
 
8
- **Never hand-build the page's URL.** `awesomate_n8n_deploy` returns a `webhooks` array —
9
- `{ node, url, method }` per trigger — and that `url` is the live address. Most instances
10
- are `https://<slug>.awesomate.io`, but not all of them are, so a constructed hostname is
11
- a guess that fails silently for the clients on a different domain. `awesomate_n8n_context`
12
- carries the same truth as `instanceUrl`. Give the user the URL you were handed.
8
+ **Never guess the page's hostname.** The live address is `{instanceUrl}/webhook/<path>`,
9
+ with the path from the webhook trigger you wrote and `instanceUrl` from
10
+ `awesomate_n8n_context`. Most instances are `https://<slug>.awesomate.io`, but not all of
11
+ them are, so a hostname built from the slug is a guess that fails silently for the clients
12
+ on a different domain. Give the user the URL built from `instanceUrl`.
13
13
 
14
14
  **The contract: GET renders, POST acts.** Two webhook trigger nodes on the SAME path —
15
15
  one `httpMethod: GET`, one `POST`, both `responseMode: "responseNode"`. Never let a GET