@awesomate/hosting-mcp 0.87.0 → 0.88.2
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/dist/index.js +6 -136
- package/package.json +2 -1
- package/skill/CHANGELOG.json +18 -0
- package/skill/awesomate-app-builder/SKILL.md +4 -3
- package/skill/awesomate-app-builder/references/node-recipes.md +3 -2
- package/skill/awesomate-app-builder/references/stack-decision.md +4 -3
- package/skill/awesomate-bookings/SKILL.md +9 -6
- package/skill/awesomate-database/SKILL.md +52 -62
- package/skill/awesomate-n8n/SKILL.md +165 -108
- package/skill/awesomate-n8n/evals/n8n-agent-build/graders/grader.md +2 -1
- package/skill/awesomate-n8n/references/ai-agents.md +10 -8
- package/skill/awesomate-n8n/references/datatables.md +46 -66
- package/skill/awesomate-n8n/references/error-handling.md +5 -5
- package/skill/awesomate-n8n/references/n8n-agents.md +10 -9
- package/skill/awesomate-n8n/references/onebrain.md +4 -4
- package/skill/awesomate-n8n/references/platform-notes.md +13 -13
- package/skill/awesomate-n8n/references/possibilities.md +12 -11
- package/skill/awesomate-n8n/references/testing-policy.md +51 -47
- package/skill/awesomate-n8n/references/troubleshooting.md +15 -16
- package/skill/awesomate-n8n/references/webhook-pages.md +5 -5
- package/skill/awesomate-n8n/references/wp-form-handler.md +6 -4
- package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +0 -31
- package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +0 -1
- package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +0 -30
- package/skill/awesomate-n8n/evals/build-form-email/prompt.md +0 -1
- package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +0 -32
- package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +0 -2
- package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +0 -27
- package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +0 -2
- package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +0 -35
- package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +0 -2
- package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +0 -27
- package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +0 -2
- package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +0 -26
- package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +0 -3
- package/skill/awesomate-n8n/evals/webhook-page-build/graders/grader.md +0 -36
- package/skill/awesomate-n8n/evals/webhook-page-build/prompt.md +0 -1
- package/skill/awesomate-n8n/references/rest-fallback.md +0 -77
- package/skill/awesomate-n8n/references/upgrade-loop.md +0 -98
package/dist/index.js
CHANGED
|
@@ -41766,14 +41766,10 @@ var TITLES = {
|
|
|
41766
41766
|
awesomate_n8n_findings: "Get n8n findings",
|
|
41767
41767
|
awesomate_n8n_kpis: "Get n8n KPIs",
|
|
41768
41768
|
awesomate_n8n_node_docs: "Get n8n node docs",
|
|
41769
|
-
awesomate_n8n_deploy: "Deploy n8n workflow",
|
|
41770
41769
|
awesomate_n8n_agents: "Build n8n Agents",
|
|
41771
41770
|
awesomate_n8n_library: "Install Awesomate templates",
|
|
41772
41771
|
awesomate_book_session: "Book a session with Awesomate",
|
|
41773
|
-
awesomate_n8n_test: "Test-fire n8n workflow",
|
|
41774
|
-
awesomate_n8n_datatable_write: "Write to n8n data table",
|
|
41775
41772
|
awesomate_n8n_attach_to_app: "Attach n8n to app",
|
|
41776
|
-
awesomate_n8n_provision_pg: "Provision Postgres for n8n",
|
|
41777
41773
|
awesomate_request_build: "Request a build from Awesomate",
|
|
41778
41774
|
awesomate_knowledge_status: "Get Knowledge Base status",
|
|
41779
41775
|
awesomate_knowledge_provision: "Enable Knowledge Base",
|
|
@@ -41866,65 +41862,9 @@ server.registerTool(
|
|
|
41866
41862
|
);
|
|
41867
41863
|
readTool(
|
|
41868
41864
|
"awesomate_n8n_context",
|
|
41869
|
-
"Call FIRST before any n8n work. Returns the client's n8n instance URL, plan, whether Claude Code n8n access is consented (if consented=false, send the user to settingsUrl and re-check after),
|
|
41865
|
+
"Call FIRST before any n8n work. Returns the client's n8n instance URL, plan, whether Claude Code n8n access is consented (if consented=false, send the user to settingsUrl and re-check after), template-install capability (Support Plus+) and instance variant. When consented it also returns an instance fingerprint (community packages, workflow/credential/datatable counts). Companion tools once consented: awesomate_n8n_workflows (world picture), awesomate_n8n_inspect (nodes/datatables/possibilities/credentials/variables), awesomate_n8n_executions, awesomate_n8n_node_docs (live node schemas + community templates \u2014 every plan).",
|
|
41870
41866
|
"/api/my-n8n/machine/context"
|
|
41871
41867
|
);
|
|
41872
|
-
server.registerTool(
|
|
41873
|
-
"awesomate_n8n_deploy",
|
|
41874
|
-
{
|
|
41875
|
-
annotations: annotate("awesomate_n8n_deploy", DESTRUCTIVE),
|
|
41876
|
-
description: "Workflow lifecycle writes on the client's n8n, all consent-gated and audited server-side. Actions: 'validate' (structural + n8n-mcp check of workflowJson; ALWAYS validate before create_draft), 'create_draft' (creates an INACTIVE '[CLI] ' workflow tagged awm:client-cli; returns its webhook URLs), 'activate'/'deactivate' (activation strips the [CLI] prefix; production webhooks respond only while active; one Awesomate built may be switched on or off, and the reply says built_by_us so you can tell the client what it does first, but every other write to it is refused with agency_managed; switching on a workflow installed from the library with an empty or missing credential answers 409 setup_incomplete with the list, so walk the client through filling it first), 'promote' (swaps a TESTED draft into the live workflow IN PLACE: live id + webhookIds preserved so external callers keep working; pass workflowId=the LIVE id and draftId=the tested draft; the draft is archived '[promoted <date>]'; response includes operationId for rollback), 'rollback' (restore a promote's pre-swap state; pass operationId), 'update_draft' (replace an INACTIVE self-built draft's full JSON in place; pass workflowId + workflowJson; live workflows are refused, use the promote path), 'delete_draft' (inactive self-built drafts only). Get explicit user approval before activate, promote, rollback, and delete_draft. 429 quota_exceeded = daily plan limit; 403 consent_required \u2192 send user to settingsUrl; 409 n8n_credential_invalid = the user's OWN n8n rejected the stored API key (NOT a hub outage: reads and validate keep working because they never touch their instance): tell them to create a new API key in their n8n under Settings \u2192 n8n API, paste it into their Awesomate account at hub.awesomate.ai/n8n/settings, then retry.",
|
|
41877
|
-
inputSchema: {
|
|
41878
|
-
action: external_exports.enum(["validate", "create_draft", "update_draft", "activate", "deactivate", "promote", "rollback", "delete_draft"]),
|
|
41879
|
-
workflowJson: external_exports.record(external_exports.unknown()).optional().describe("For validate: the full workflow JSON. For create_draft: must contain name, nodes, connections (settings optional)."),
|
|
41880
|
-
workflowId: external_exports.string().optional().describe("Required for activate/deactivate/delete_draft; for promote this is the LIVE workflow id"),
|
|
41881
|
-
draftId: external_exports.string().optional().describe("promote only: the tested draft to swap into the live workflow"),
|
|
41882
|
-
operationId: external_exports.string().optional().describe("rollback only: the operationId returned by promote")
|
|
41883
|
-
}
|
|
41884
|
-
},
|
|
41885
|
-
async ({ action, workflowJson, workflowId, draftId, operationId }) => {
|
|
41886
|
-
try {
|
|
41887
|
-
if (action === "validate") {
|
|
41888
|
-
return textResult(await hubPost(requireConfig(), "/api/my-n8n/machine/workflows/validate", { workflow: workflowJson }));
|
|
41889
|
-
}
|
|
41890
|
-
if (action === "create_draft") {
|
|
41891
|
-
return textResult(await hubPost(requireConfig(), "/api/my-n8n/machine/workflows/draft", workflowJson ?? {}));
|
|
41892
|
-
}
|
|
41893
|
-
if (action === "update_draft") {
|
|
41894
|
-
if (!workflowId) return errorResult(new Error("workflowId is required for update_draft"));
|
|
41895
|
-
if (!workflowJson) return errorResult(new Error("workflowJson (full: name, nodes, connections, settings?) is required for update_draft"));
|
|
41896
|
-
return textResult(
|
|
41897
|
-
await hubPatch(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}`, workflowJson)
|
|
41898
|
-
);
|
|
41899
|
-
}
|
|
41900
|
-
if (action === "rollback") {
|
|
41901
|
-
if (!operationId) return errorResult(new Error("operationId is required for rollback"));
|
|
41902
|
-
return textResult(
|
|
41903
|
-
await hubPost(requireConfig(), `/api/my-n8n/machine/operations/${encodeURIComponent(operationId)}/rollback`, {})
|
|
41904
|
-
);
|
|
41905
|
-
}
|
|
41906
|
-
if (!workflowId) return errorResult(new Error(`workflowId is required for ${action}`));
|
|
41907
|
-
if (action === "activate" || action === "deactivate") {
|
|
41908
|
-
return textResult(
|
|
41909
|
-
await hubPost(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}/activate`, {
|
|
41910
|
-
active: action === "activate"
|
|
41911
|
-
})
|
|
41912
|
-
);
|
|
41913
|
-
}
|
|
41914
|
-
if (action === "promote") {
|
|
41915
|
-
if (!draftId) return errorResult(new Error("draftId is required for promote"));
|
|
41916
|
-
return textResult(
|
|
41917
|
-
await hubPost(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}/promote`, { draftId })
|
|
41918
|
-
);
|
|
41919
|
-
}
|
|
41920
|
-
return textResult(
|
|
41921
|
-
await hubDelete(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}`)
|
|
41922
|
-
);
|
|
41923
|
-
} catch (err) {
|
|
41924
|
-
return errorResult(err);
|
|
41925
|
-
}
|
|
41926
|
-
}
|
|
41927
|
-
);
|
|
41928
41868
|
var N8N_AGENT_TOOLS = [
|
|
41929
41869
|
"get_agent_builder_reference",
|
|
41930
41870
|
"search_projects",
|
|
@@ -41967,7 +41907,7 @@ server.registerTool(
|
|
|
41967
41907
|
"awesomate_n8n_agents",
|
|
41968
41908
|
{
|
|
41969
41909
|
annotations: annotate("awesomate_n8n_agents", DESTRUCTIVE),
|
|
41970
|
-
description: "Build and manage n8n AGENTS (the Agents tab in n8n 2.41+; NOT the AI Agent node inside a workflow, and NOT the older Chat Hub agents) on the client's own n8n. Every action works on EVERY plan, Essentials included. The hub relays one call at a time to n8n's own instance MCP server, consent-gated, quota-limited and audited; the client's MCP key never reaches this machine. Actions: 'status' (is it set up? keyConfigured / reachable / ready / limits; call FIRST, and when not ready relay setup.steps to the user in plain words), 'describe' (n8n's own description + JSON input schema for every relayed tool, or just `tool`; read it before calling a tool whose arguments you have not seen this session, never guess argument shapes), 'call' (run one n8n agent tool: pass `tool` and its `arguments` exactly as its schema defines them), 'result' (call_id: collect a call that was still running). Before the first build in a session call tool 'get_agent_builder_reference' and follow its build sequence and JSON schema; it is n8n's own live guide and beats anything remembered. Flow: search_projects \u2192 discover_agent_assets (models, workflows, subagents) + list_credentials \u2192 create_agent {projectId, name, config} \u2192 mutate_agent {agentId, baseConfigHash, operation} (always the LATEST configHash; result.ok=false with code stale_config \u2192 get_agent and retry) \u2192 validate_agent \u2192 call_agent with one representative test message (real tools run, say so) \u2192 ask the user \u2192 publish_agent ONLY on their explicit yes. call_agent can take a couple of minutes: this tool waits for it. If it comes back pending with a call_id, or 409 agent_call_in_progress, NEVER resend the message; use 'result'. 504 mcp_timeout means it may have run anyway: check before retrying. Workflow tools must start with an Execute Workflow Trigger and be active (
|
|
41910
|
+
description: "Build and manage n8n AGENTS (the Agents tab in n8n 2.41+; NOT the AI Agent node inside a workflow, and NOT the older Chat Hub agents) on the client's own n8n. Every action works on EVERY plan, Essentials included. The hub relays one call at a time to n8n's own instance MCP server, consent-gated, quota-limited and audited; the client's MCP key never reaches this machine. Actions: 'status' (is it set up? keyConfigured / reachable / ready / limits; call FIRST, and when not ready relay setup.steps to the user in plain words), 'describe' (n8n's own description + JSON input schema for every relayed tool, or just `tool`; read it before calling a tool whose arguments you have not seen this session, never guess argument shapes), 'call' (run one n8n agent tool: pass `tool` and its `arguments` exactly as its schema defines them), 'result' (call_id: collect a call that was still running). Before the first build in a session call tool 'get_agent_builder_reference' and follow its build sequence and JSON schema; it is n8n's own live guide and beats anything remembered. Flow: search_projects \u2192 discover_agent_assets (models, workflows, subagents) + list_credentials \u2192 create_agent {projectId, name, config} \u2192 mutate_agent {agentId, baseConfigHash, operation} (always the LATEST configHash; result.ok=false with code stale_config \u2192 get_agent and retry) \u2192 validate_agent \u2192 call_agent with one representative test message (real tools run, say so) \u2192 ask the user \u2192 publish_agent ONLY on their explicit yes. call_agent can take a couple of minutes: this tool waits for it. If it comes back pending with a call_id, or 409 agent_call_in_progress, NEVER resend the message; use 'result'. 504 mcp_timeout means it may have run anyway: check before retrying. Workflow tools must start with an Execute Workflow Trigger and be active (the client switches it on in n8n, or through their own connection to the instance's MCP server). 403 agent_tool_blocked: the config tried to attach a workflow Awesomate manages, or the n8n node / an n8n API credential; use one of the client's own workflows instead. delete_agent only works on agents Claude created. 409 mcp_key_missing / mcp_disabled / mcp_key_rejected = setup problem on THEIR n8n, relay `hint` + `setup`. 429 quota_exceeded = daily plan limit. A response with ok:false is n8n's own answer: read error.code/message and fix the input, don't retry blindly.",
|
|
41971
41911
|
inputSchema: {
|
|
41972
41912
|
action: external_exports.enum(["status", "describe", "call", "result"]),
|
|
41973
41913
|
tool: external_exports.enum(N8N_AGENT_TOOLS).optional().describe("call: the n8n agent tool to run (required). describe: limit to this tool (optional)"),
|
|
@@ -42072,26 +42012,6 @@ server.registerTool(
|
|
|
42072
42012
|
}
|
|
42073
42013
|
}
|
|
42074
42014
|
);
|
|
42075
|
-
server.registerTool(
|
|
42076
|
-
"awesomate_n8n_test",
|
|
42077
|
-
{
|
|
42078
|
-
annotations: annotate("awesomate_n8n_test", MUTATING),
|
|
42079
|
-
description: "Fire a synthetic test payload at an ACTIVE self-built workflow's production webhook and get back the webhook response plus the executionId it caused (then poll GET /api/my-n8n/executions/:id for node-by-node results). Sends the X-Awesomate-Test header. Real side effects DO run (emails actually send) \u2014 warn the user, use their own address, prefix subjects with [TEST]. Only works on awm:client-cli-tagged workflows.",
|
|
42080
|
-
inputSchema: {
|
|
42081
|
-
workflowId: external_exports.string(),
|
|
42082
|
-
payload: external_exports.record(external_exports.unknown()).optional().describe("JSON body to POST to the webhook (format-valid, obviously-fake values)")
|
|
42083
|
-
}
|
|
42084
|
-
},
|
|
42085
|
-
async ({ workflowId, payload }) => {
|
|
42086
|
-
try {
|
|
42087
|
-
return textResult(
|
|
42088
|
-
await hubPost(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}/test-fire`, { payload })
|
|
42089
|
-
);
|
|
42090
|
-
} catch (err) {
|
|
42091
|
-
return errorResult(err);
|
|
42092
|
-
}
|
|
42093
|
-
}
|
|
42094
|
-
);
|
|
42095
42015
|
server.registerTool(
|
|
42096
42016
|
"awesomate_n8n_workflows",
|
|
42097
42017
|
{
|
|
@@ -42207,41 +42127,6 @@ server.registerTool(
|
|
|
42207
42127
|
}
|
|
42208
42128
|
}
|
|
42209
42129
|
);
|
|
42210
|
-
server.registerTool(
|
|
42211
|
-
"awesomate_n8n_datatable_write",
|
|
42212
|
-
{
|
|
42213
|
-
annotations: annotate("awesomate_n8n_datatable_write", DESTRUCTIVE),
|
|
42214
|
-
description: "Datatable writes (Support Plus+, consent-gated, audited). 'create' {name, columns:[{name,type?}], workflowId?} \u2014 ALWAYS pass workflowId when the table serves a specific workflow (datatables resolve PER PROJECT at runtime; workflowId threads that workflow's project; a projectWarning in the response means pass it). 'add_column' {tableId, name, type?} \u2014 needs the 'direct database writes' privacy toggle; names: letters/digits/underscores only. 'insert' {tableId, rows:[...]} (\u2264100), 'update' {tableId, filter, data}, 'delete_rows' {tableId, filter \u2014 REQUIRED, there is no delete-all}. Writes only work on tables created through Claude Code (403 not_self_created otherwise \u2014 agency tables are off limits). Get explicit user approval before delete_rows.",
|
|
42215
|
-
inputSchema: {
|
|
42216
|
-
action: external_exports.enum(["create", "add_column", "insert", "update", "delete_rows"]),
|
|
42217
|
-
tableId: external_exports.string().optional(),
|
|
42218
|
-
name: external_exports.string().optional().describe("create: table name; add_column: column name"),
|
|
42219
|
-
columns: external_exports.array(external_exports.object({ name: external_exports.string(), type: external_exports.enum(["string", "number", "boolean", "date"]).optional() })).optional(),
|
|
42220
|
-
workflowId: external_exports.string().optional().describe("create: co-locate the table with this workflow (recommended)"),
|
|
42221
|
-
type: external_exports.enum(["string", "number", "boolean", "date"]).optional().describe("add_column only"),
|
|
42222
|
-
rows: external_exports.array(external_exports.record(external_exports.unknown())).optional().describe("insert only"),
|
|
42223
|
-
filter: external_exports.record(external_exports.unknown()).optional().describe("update/delete_rows: {filters:[{columnName,condition,value}], type?}"),
|
|
42224
|
-
data: external_exports.record(external_exports.unknown()).optional().describe("update only: column \u2192 new value")
|
|
42225
|
-
}
|
|
42226
|
-
},
|
|
42227
|
-
async ({ action, tableId, name, columns, workflowId, type, rows, filter, data }) => {
|
|
42228
|
-
try {
|
|
42229
|
-
const cfg = requireConfig();
|
|
42230
|
-
if (action === "create") {
|
|
42231
|
-
return textResult(await hubPost(cfg, "/api/my-n8n/machine/datatables", { name, columns, workflowId }));
|
|
42232
|
-
}
|
|
42233
|
-
if (!tableId) return errorResult(new Error(`tableId is required for ${action}`));
|
|
42234
|
-
const base = `/api/my-n8n/machine/datatables/${encodeURIComponent(tableId)}`;
|
|
42235
|
-
if (action === "add_column") {
|
|
42236
|
-
return textResult(await hubPost(cfg, `${base}/columns`, { name, type }));
|
|
42237
|
-
}
|
|
42238
|
-
const mode = action === "delete_rows" ? "delete" : action;
|
|
42239
|
-
return textResult(await hubPost(cfg, `${base}/rows`, { mode, rows, filter, data }));
|
|
42240
|
-
} catch (err) {
|
|
42241
|
-
return errorResult(err);
|
|
42242
|
-
}
|
|
42243
|
-
}
|
|
42244
|
-
);
|
|
42245
42130
|
server.registerTool(
|
|
42246
42131
|
"awesomate_skill_update",
|
|
42247
42132
|
{
|
|
@@ -42501,7 +42386,7 @@ readTool(
|
|
|
42501
42386
|
);
|
|
42502
42387
|
readTool(
|
|
42503
42388
|
"awesomate_get_limits",
|
|
42504
|
-
"Usage vs plan limits across every dimension (sites, custom domains, apps,
|
|
42389
|
+
"Usage vs plan limits across every dimension (sites, custom domains, apps, workflow credits, AI-editor credits) plus a nudges[] array. Call BEFORE any create action; when a nudge has severity 'approaching' or 'exceeded', surface it to the user with the recommended plan \u2014 never execute an upgrade without preview + explicit confirmation (upgrade tools ship in a later release; for now deep-link to the hub billing page).",
|
|
42505
42390
|
"/api/client-hosting/limits"
|
|
42506
42391
|
);
|
|
42507
42392
|
var PLAN_LADDER_FALLBACK = {
|
|
@@ -42876,10 +42761,10 @@ server.registerTool(
|
|
|
42876
42761
|
"awesomate_n8n_attach_to_app",
|
|
42877
42762
|
{
|
|
42878
42763
|
annotations: annotate("awesomate_n8n_attach_to_app", MUTATING),
|
|
42879
|
-
description: "Wire an app to call the user's own n8n as a backend. Give it the app +
|
|
42764
|
+
description: "Wire an app to call the user's own n8n as a backend. Give it the app + the production webhook URL of a workflow on their n8n (read it with awesomate_n8n_workflows; a workflow Claude built through the instance's own MCP server works too). It stores N8N_WEBHOOK_URL + a generated N8N_WEBHOOK_SECRET on the app (encrypted + injected) and RETURNS the secret so you can add a matching `X-Awesomate-Webhook-Secret` header check to the n8n workflow (so the webhook isn't world-callable). The app then calls it via src/lib/n8n.ts callWorkflow(). Node apps only. Only reach for this when the job needs an external app/credential or AI the user already has in n8n \u2014 not for pure in-app logic.",
|
|
42880
42765
|
inputSchema: {
|
|
42881
42766
|
appId: external_exports.number().int().positive().describe("The app id"),
|
|
42882
|
-
webhookUrl: external_exports.string().url().describe("The n8n workflow's production webhook URL
|
|
42767
|
+
webhookUrl: external_exports.string().url().describe("The n8n workflow's production webhook URL"),
|
|
42883
42768
|
env: external_exports.enum(["dev", "staging", "prod"]).default("dev").describe("Which app environment to wire")
|
|
42884
42769
|
}
|
|
42885
42770
|
},
|
|
@@ -42927,21 +42812,6 @@ server.registerTool(
|
|
|
42927
42812
|
}
|
|
42928
42813
|
}
|
|
42929
42814
|
);
|
|
42930
|
-
server.registerTool(
|
|
42931
|
-
"awesomate_n8n_provision_pg",
|
|
42932
|
-
{
|
|
42933
|
-
annotations: annotate("awesomate_n8n_provision_pg", MUTATING),
|
|
42934
|
-
description: "Provision a NEW Postgres database on the user's own Awesomate cPanel hosting and wire it into their n8n as a ready-to-use `postgres` credential their workflows can select. This is a WRITE that creates real infrastructure \u2014 get explicit user approval first. Requires: their n8n builder access (Support Plus+, allow_client_cli_builds) AND the allow_pg_writes consent (403 consent_required \u2192 send them to settingsUrl); AND an Awesomate cPanel hosting account (409 hosting_required otherwise). Limited to 2/day. Returns the new credential id + name, the database/user, and the password ONCE (it lives in the n8n credential, never stored by Awesomate \u2014 tell the user to note or rotate it). After this, build the workflow selecting the returned Postgres credential.",
|
|
42935
|
-
inputSchema: {}
|
|
42936
|
-
},
|
|
42937
|
-
async () => {
|
|
42938
|
-
try {
|
|
42939
|
-
return textResult(await hubPost(requireConfig(), "/api/my-n8n/machine/pg-credentials", {}));
|
|
42940
|
-
} catch (err) {
|
|
42941
|
-
return errorResult(err);
|
|
42942
|
-
}
|
|
42943
|
-
}
|
|
42944
|
-
);
|
|
42945
42815
|
function knowledgeResult(data) {
|
|
42946
42816
|
return {
|
|
42947
42817
|
content: [
|
|
@@ -43731,7 +43601,7 @@ server.registerTool(
|
|
|
43731
43601
|
key: external_exports.string().max(41).optional().describe("save_calendar, save_service: lower case, digits and underscores"),
|
|
43732
43602
|
name: external_exports.string().max(80).optional(),
|
|
43733
43603
|
timezone: external_exports.string().max(60).optional().describe("IANA zone, like Australia/Sydney"),
|
|
43734
|
-
hours: external_exports.record(external_exports.string(), external_exports.array(external_exports.
|
|
43604
|
+
hours: external_exports.record(external_exports.string(), external_exports.array(external_exports.array(external_exports.string()).length(2))).optional().describe('save_calendar: {"mon": [["09:00","17:00"]], ...}'),
|
|
43735
43605
|
min_notice_minutes: external_exports.number().int().min(0).optional(),
|
|
43736
43606
|
buffer_minutes: external_exports.number().int().min(0).optional(),
|
|
43737
43607
|
max_per_day: external_exports.number().int().min(1).nullable().optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomate/hosting-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.88.2",
|
|
4
4
|
"description": "Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"zod": "^3.24.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
+
"@anthropic-ai/sdk": "^0.132.0",
|
|
31
32
|
"@types/node": "^25.9.3",
|
|
32
33
|
"esbuild": "^0.25.0",
|
|
33
34
|
"typescript": "^6.0.3"
|
package/skill/CHANGELOG.json
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"versions": [
|
|
3
|
+
{
|
|
4
|
+
"version": "0.88.2",
|
|
5
|
+
"highlights": [
|
|
6
|
+
"Fixed: the booking diary tool described its opening hours in an older JSON Schema form that strict clients refuse, which would stop every Awesomate tool loading there. Nothing changes in Claude Code"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.88.1",
|
|
11
|
+
"highlights": [
|
|
12
|
+
"Bookings can keep a calendar's busy times free from Outlook as well as Google Calendar, and write each booking into it; the owner connects it in the hub"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"version": "0.88.0",
|
|
17
|
+
"highlights": [
|
|
18
|
+
"Claude no longer builds workflows through Awesomate: it writes them straight on your own n8n through n8n's MCP server (switch on MCP access in your n8n and add its key to Claude Code), with no Awesomate limits on it. Reading your n8n, installing templates and n8n Agents work as before"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
3
21
|
{
|
|
4
22
|
"version": "0.87.0",
|
|
5
23
|
"highlights": [
|
|
@@ -70,9 +70,10 @@ decision brain. The short version, matched to what they say:
|
|
|
70
70
|
a static app — there is nowhere to put a secret. Anything the page must
|
|
71
71
|
keep private (an API key, a webhook URL you don't want public) rules
|
|
72
72
|
static out.
|
|
73
|
-
- **`awesomate_n8n_attach_to_app` is Node-only.**
|
|
74
|
-
their n8n
|
|
75
|
-
|
|
73
|
+
- **`awesomate_n8n_attach_to_app` is Node-only.** It takes any production
|
|
74
|
+
webhook URL on their n8n and stores it with a secret on the app, so the
|
|
75
|
+
"form posts to their n8n" pattern needs a Node app, unless the webhook
|
|
76
|
+
URL being public is genuinely acceptable.
|
|
76
77
|
- **No separate dev site.** All three environment URLs point at the same
|
|
77
78
|
single subdomain — there's no dev copy to review on, so every change is
|
|
78
79
|
live the moment it's published.
|
|
@@ -50,8 +50,9 @@ with a clear reason). Postgres code should prefer `DATABASE_URL`.
|
|
|
50
50
|
## Attach n8n as the backend
|
|
51
51
|
|
|
52
52
|
Job needs email / a lookup in their connected apps / AI → build the webhook
|
|
53
|
-
workflow with the awesomate-n8n skill
|
|
54
|
-
|
|
53
|
+
workflow with the awesomate-n8n skill (through the user's own n8n MCP
|
|
54
|
+
server), then `awesomate_n8n_attach_to_app` with its production webhook URL
|
|
55
|
+
(stores `N8N_WEBHOOK_URL` + secret; returns the secret ONCE: add the
|
|
55
56
|
matching `X-Awesomate-Webhook-Secret` header check to the workflow). The app
|
|
56
57
|
calls `callWorkflow(payload)` from `src/lib/n8n.ts`; it no-ops when unset and
|
|
57
58
|
never throws — check `result.ok` and degrade gracefully.
|
|
@@ -65,13 +65,14 @@ credentials are already connected there, so there's nothing new to set up.
|
|
|
65
65
|
- Check what's connected with `awesomate_n8n_inspect {what:'credentials'}`
|
|
66
66
|
(names/types only) and offer what they already have: *"You've got Gmail +
|
|
67
67
|
Google Sheets connected — want the form to email you and add the lead to a
|
|
68
|
-
sheet?"* That read needs the **"
|
|
68
|
+
sheet?"* That read needs the **"Let Claude Code work with your automations"**
|
|
69
69
|
privacy toggle, which is off by default — a 403 `consent_required` means
|
|
70
70
|
call `awesomate_privacy_settings`, name the toggle, and ask the user to flip
|
|
71
71
|
it at hub.awesomate.ai/settings?tab=privacy.
|
|
72
72
|
- Build the workflow with the **awesomate-n8n** skill (webhook trigger →
|
|
73
|
-
action
|
|
74
|
-
|
|
73
|
+
action, written through the user's own n8n MCP server), take its
|
|
74
|
+
**production webhook URL**, and wire it into the app.
|
|
75
|
+
- **Node app:** `awesomate_n8n_attach_to_app` with that URL. It stores
|
|
75
76
|
`N8N_WEBHOOK_URL` plus a generated `N8N_WEBHOOK_SECRET` (encrypted +
|
|
76
77
|
injected) and returns the secret so you can add the matching
|
|
77
78
|
`X-Awesomate-Webhook-Secret` check on the n8n side. `src/lib/n8n.ts`
|
|
@@ -82,9 +82,12 @@ themselves cannot be written through `awesomate_crm_write`; only these actions c
|
|
|
82
82
|
Essentials, the tool answers `upgrade_required`: say the owner can do the same in the hub under
|
|
83
83
|
Contacts, Bookings, and do not retry.
|
|
84
84
|
- Payments and deposits are not part of bookings yet. Do not promise them; the price is shown only.
|
|
85
|
-
- **Google Calendar** is connected per calendar in the hub (Contacts, Bookings, Set
|
|
86
|
-
Google Calendar), by the person whose calendar it is: Claude
|
|
87
|
-
there. Once connected, times they are busy
|
|
88
|
-
written to an "Awesomate bookings" calendar in their
|
|
89
|
-
`setup` lists the connected calendars under `links
|
|
90
|
-
|
|
85
|
+
- **Google Calendar or Outlook** is connected per calendar in the hub (Contacts, Bookings, Set
|
|
86
|
+
up, Connect Google Calendar or Connect Outlook), by the person whose calendar it is: Claude
|
|
87
|
+
cannot connect it, so send them there. Once connected, times they are busy there are never
|
|
88
|
+
offered, and every booking is written to an "Awesomate bookings" calendar in their account,
|
|
89
|
+
moved and removed with it. `setup` lists the connected calendars under `links` (each with its
|
|
90
|
+
`provider`), and says which providers this hub offers (`google.available`,
|
|
91
|
+
`microsoft.available`). Where neither is offered, the notice email's invite is how a booking
|
|
92
|
+
reaches their calendar. A work account whose organisation limits apps may need its Microsoft
|
|
93
|
+
365 admin to approve Awesomate once; the hub says so when that happens.
|
|
@@ -20,17 +20,18 @@ write, or for an app your customers log into?"
|
|
|
20
20
|
|
|
21
21
|
**(a) A list an AUTOMATION reads/writes** — a dedupe ledger, a task
|
|
22
22
|
queue, a lookup map, form submissions feeding a workflow. → n8n DATA
|
|
23
|
-
TABLE, via the awesomate-n8n skill.
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
TABLE, via the awesomate-n8n skill. The table lives in n8n: Claude designs
|
|
24
|
+
the columns, the user creates it in n8n (Data tables in the left menu,
|
|
25
|
+
inside the project that owns the workflow), or Claude creates it through
|
|
26
|
+
their n8n's own MCP server when that server offers a data-table tool. No
|
|
27
|
+
Awesomate tool creates or writes a table. No hosting slot consumed, and
|
|
26
28
|
workflows query it directly — this is the default answer for anything
|
|
27
29
|
automation-shaped. Inspect what exists with
|
|
28
30
|
`awesomate_n8n_inspect {what:'datatables'}`.
|
|
29
|
-
**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
both the read and the write come back 403 `consent_required`. Call
|
|
31
|
+
**That read is gated** by the privacy switch **"Let Claude Code work with
|
|
32
|
+
your automations"** in Settings, Privacy (hub.awesomate.ai/settings?tab=privacy,
|
|
33
|
+
which is what the 403's `settingsUrl` points at). It is **off by default**,
|
|
34
|
+
so on a fresh account the read comes back 403 `consent_required`. Call
|
|
34
35
|
`awesomate_privacy_settings` to name the exact toggle that's off, send the
|
|
35
36
|
user to flip it, then re-check. You cannot flip it for them.
|
|
36
37
|
|
|
@@ -43,25 +44,24 @@ app serves to people. → the app's own Postgres.
|
|
|
43
44
|
via the awesomate-app-builder skill, which wires it in from the start.
|
|
44
45
|
|
|
45
46
|
**(c) A WORKFLOW that needs raw SQL against its own Postgres** — real
|
|
46
|
-
joins, aggregates, or volumes a data table shouldn't carry. →
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
switch" or a "raise it with support" answer.
|
|
47
|
+
joins, aggregates, or volumes a data table shouldn't carry. → a Postgres
|
|
48
|
+
credential the user creates in their own n8n. No Awesomate tool provisions
|
|
49
|
+
this any more; it is two steps the user does, and you walk them through:
|
|
50
|
+
1. Get a database. If they have an Awesomate hosting account and cPanel
|
|
51
|
+
shows a **PostgreSQL Databases** page (not every package does; check
|
|
52
|
+
before promising it), it makes one (database + user + password) in a
|
|
53
|
+
minute; the awesomate-hosting skill opens cPanel for them. If their data
|
|
54
|
+
already lives in a Postgres somewhere else (their app's database, Supabase,
|
|
55
|
+
Neon), use that one: see (d).
|
|
56
|
+
2. Create the credential in n8n at `{instanceUrl}/home/credentials`
|
|
57
|
+
(type Postgres: host, port, database, user, password, SSL as cPanel shows
|
|
58
|
+
them). The password goes from cPanel into n8n and never through the chat.
|
|
59
|
+
Then confirm it exists with `awesomate_n8n_inspect {what:'credentials'}`
|
|
60
|
+
and build the workflow on it (awesomate-n8n skill).
|
|
61
|
+
An app database made by `awesomate_app_provision_db` belongs to the app: a
|
|
62
|
+
workflow reads it through the app's own API, or through a credential the
|
|
63
|
+
user makes on purpose from the app's connection details, never by Claude
|
|
64
|
+
copying `DATABASE_URL` into n8n.
|
|
65
65
|
|
|
66
66
|
**(d) Analytics/BI or data shared with other systems** — reporting
|
|
67
67
|
warehouses, a spreadsheet the whole team lives in, a CRM. → recommend
|
|
@@ -92,19 +92,15 @@ reach), ask "live or dev?" before provisioning against it.
|
|
|
92
92
|
|
|
93
93
|
## 2. Safety rules
|
|
94
94
|
|
|
95
|
-
- **Passwords land where they belong
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
should be rotated. Never put a `DATABASE_URL` in a message. Tell the user where
|
|
105
|
-
it lives instead: "the app already has its connection — nothing for you
|
|
106
|
-
to copy." (After an app database is provisioned, the app needs a restart
|
|
107
|
-
or redeploy to pick it up.)
|
|
95
|
+
- **Passwords land where they belong.** `awesomate_app_provision_db`
|
|
96
|
+
NEVER returns a password: it's set server-side, stored encrypted, and
|
|
97
|
+
injected as the app's `DATABASE_URL`. There is nothing to show, so don't
|
|
98
|
+
promise the user a password. A workflow Postgres password lives in the n8n
|
|
99
|
+
credential the user created; never ask for it and never put it, or a
|
|
100
|
+
`DATABASE_URL`, in a message. Tell the user where it lives instead: "the
|
|
101
|
+
app already has its connection, nothing for you to copy." (After an app
|
|
102
|
+
database is provisioned, the app needs a restart or redeploy to pick it
|
|
103
|
+
up.)
|
|
108
104
|
- Secrets the user's own app code needs (API keys, tokens) go through
|
|
109
105
|
the awesomate-credentials skill, never pasted into files or chat.
|
|
110
106
|
- **Deleting data requires an explicit filter and an explicit yes.**
|
|
@@ -114,28 +110,22 @@ reach), ask "live or dev?" before provisioning against it.
|
|
|
114
110
|
|
|
115
111
|
## 3. Limits, honestly
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
(`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
— "app databases are on Support Plus" — point them at
|
|
134
|
-
hub.awesomate.ai/billing to upgrade, then help fully within what their plan
|
|
135
|
-
allows. On Essentials that means none of (a), (b) or (c) is available —
|
|
136
|
-
don't dangle a data table as the consolation prize; say so once and look at
|
|
137
|
-
(d), keeping the data where it already lives and connecting to it. If a
|
|
138
|
-
daily quota is hit, say when it resets and what can proceed meanwhile.
|
|
113
|
+
App databases (`awesomate_app_provision_db`) need **Support Plus or
|
|
114
|
+
above**. There is **no daily cap**: it's one database per environment and
|
|
115
|
+
refuses (409 `already_has_db`) if the app has one, so there's nothing to
|
|
116
|
+
ration.
|
|
117
|
+
|
|
118
|
+
Data tables (a) and a workflow Postgres (c) are n8n's own features on every
|
|
119
|
+
plan, with no Awesomate gate, limit or count: the user creates them in n8n
|
|
120
|
+
and in cPanel. An instance tops out at 50 data tables (n8n's cap). Reading
|
|
121
|
+
tables or credentials from here needs the "Let Claude Code work with your
|
|
122
|
+
automations" toggle (§0(a)).
|
|
123
|
+
|
|
124
|
+
If the user's plan doesn't cover what branch (b) needs, say it once ("app
|
|
125
|
+
databases are on Support Plus"), point them at hub.awesomate.ai/billing to
|
|
126
|
+
upgrade, then help fully within what their plan allows: on Essentials (a)
|
|
127
|
+
and (c) still work, and so does (d), keeping the data where it already lives
|
|
128
|
+
and connecting to it.
|
|
139
129
|
|
|
140
130
|
Report every result as a business outcome: "your workflow now remembers
|
|
141
131
|
every invoice it's processed, so no customer gets emailed twice" — with
|