@awesomate/hosting-mcp 0.12.0 → 0.13.0
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 +204 -8
- package/package.json +2 -2
- package/skill/awesomate-app-builder/SKILL.md +5 -1
- package/skill/awesomate-credentials/SKILL.md +1 -1
- package/skill/awesomate-hosting/SKILL.md +50 -159
- package/skill/awesomate-hosting/references/connect-troubleshooting.md +77 -0
- package/skill/awesomate-hosting/references/multi-account.md +33 -0
- package/skill/awesomate-hosting/references/rest-fallback.md +30 -0
- package/skill/awesomate-hosting/scripts/bootstrap.mjs +27 -7
- package/skill/awesomate-n8n/SKILL.md +153 -147
- package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +31 -0
- package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +30 -0
- package/skill/awesomate-n8n/evals/build-form-email/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +32 -0
- package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/diagnose-failure/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/diagnose-failure/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +35 -0
- package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/possibilities-grounded/graders/grader.md +28 -0
- package/skill/awesomate-n8n/evals/possibilities-grounded/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/vars-not-env/graders/grader.md +26 -0
- package/skill/awesomate-n8n/evals/vars-not-env/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +26 -0
- package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +3 -0
- package/skill/awesomate-n8n/references/ai-agents.md +135 -0
- package/skill/awesomate-n8n/references/datatables.md +105 -0
- package/skill/awesomate-n8n/references/{node-recipes.md → platform-notes.md} +56 -7
- package/skill/awesomate-n8n/references/possibilities.md +83 -0
- package/skill/awesomate-n8n/references/testing-policy.md +115 -0
- package/skill/awesomate-n8n/references/troubleshooting.md +69 -0
- package/skill/awesomate-n8n/references/upgrade-loop.md +98 -0
- package/skill/awesomate-n8n/references/vendor/MANIFEST.json +26 -0
- package/skill/awesomate-n8n/references/vendor/code-node/BUILTIN_FUNCTIONS.md +779 -0
- package/skill/awesomate-n8n/references/vendor/code-node/COMMON_PATTERNS.md +1123 -0
- package/skill/awesomate-n8n/references/vendor/code-node/DATA_ACCESS.md +797 -0
- package/skill/awesomate-n8n/references/vendor/code-node/ERROR_PATTERNS.md +776 -0
- package/skill/awesomate-n8n/references/vendor/code-node/SKILL.md +703 -0
- package/skill/awesomate-n8n/references/vendor/expressions/COMMON_MISTAKES.md +406 -0
- package/skill/awesomate-n8n/references/vendor/expressions/EXAMPLES.md +496 -0
- package/skill/awesomate-n8n/references/vendor/expressions/SKILL.md +525 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/DEPENDENCIES.md +743 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/OPERATION_PATTERNS.md +926 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/SKILL.md +583 -0
- package/skill/awesomate-n8n/references/vendor/validation/ERROR_CATALOG.md +781 -0
- package/skill/awesomate-n8n/references/vendor/validation/FALSE_POSITIVES.md +695 -0
- package/skill/awesomate-n8n/references/vendor/validation/SKILL.md +414 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/SKILL.md +413 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/ai_agent_workflow.md +797 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/database_operations.md +798 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/http_api_integration.md +747 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/scheduled_tasks.md +786 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/webhook_processing.md +558 -0
package/dist/index.js
CHANGED
|
@@ -39676,9 +39676,9 @@ var StdioServerTransport = class {
|
|
|
39676
39676
|
|
|
39677
39677
|
// src/index.ts
|
|
39678
39678
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
39679
|
-
import { homedir as
|
|
39680
|
-
import { join as
|
|
39681
|
-
import { fileURLToPath } from "node:url";
|
|
39679
|
+
import { homedir as homedir3 } from "node:os";
|
|
39680
|
+
import { join as join3, dirname as dirname3 } from "node:path";
|
|
39681
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
39682
39682
|
|
|
39683
39683
|
// src/config.ts
|
|
39684
39684
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -39910,10 +39910,39 @@ function hubGet(config3, path) {
|
|
|
39910
39910
|
function hubPost(config3, path, jsonBody = {}) {
|
|
39911
39911
|
return hubRequest(config3, "POST", path, jsonBody);
|
|
39912
39912
|
}
|
|
39913
|
+
function hubPatch(config3, path, jsonBody = {}) {
|
|
39914
|
+
return hubRequest(config3, "PATCH", path, jsonBody);
|
|
39915
|
+
}
|
|
39913
39916
|
function hubDelete(config3, path) {
|
|
39914
39917
|
return hubRequest(config3, "DELETE", path);
|
|
39915
39918
|
}
|
|
39916
39919
|
|
|
39920
|
+
// src/skills.ts
|
|
39921
|
+
import { cpSync, existsSync as existsSync2, readdirSync, writeFileSync } from "node:fs";
|
|
39922
|
+
import { homedir as homedir2 } from "node:os";
|
|
39923
|
+
import { join as join2, dirname as dirname2 } from "node:path";
|
|
39924
|
+
import { fileURLToPath } from "node:url";
|
|
39925
|
+
var PACKAGE_ROOT = join2(dirname2(fileURLToPath(import.meta.url)), "..");
|
|
39926
|
+
function installSkills(version2) {
|
|
39927
|
+
const sourceRoot = join2(PACKAGE_ROOT, "skill");
|
|
39928
|
+
const destRoot = join2(homedir2(), ".claude", "skills");
|
|
39929
|
+
const installed = [];
|
|
39930
|
+
for (const entry of readdirSync(sourceRoot, { withFileTypes: true })) {
|
|
39931
|
+
if (!entry.isDirectory()) continue;
|
|
39932
|
+
const src = join2(sourceRoot, entry.name);
|
|
39933
|
+
if (!existsSync2(join2(src, "SKILL.md"))) continue;
|
|
39934
|
+
const dest = join2(destRoot, entry.name);
|
|
39935
|
+
cpSync(src, dest, { recursive: true });
|
|
39936
|
+
try {
|
|
39937
|
+
writeFileSync(join2(dest, ".installed-version"), `${version2}
|
|
39938
|
+
`);
|
|
39939
|
+
} catch {
|
|
39940
|
+
}
|
|
39941
|
+
installed.push(entry.name);
|
|
39942
|
+
}
|
|
39943
|
+
return { installed, version: version2, skillsDir: destRoot };
|
|
39944
|
+
}
|
|
39945
|
+
|
|
39917
39946
|
// src/index.ts
|
|
39918
39947
|
var config2 = null;
|
|
39919
39948
|
var configError = null;
|
|
@@ -39930,7 +39959,7 @@ function accountStamp() {
|
|
|
39930
39959
|
var SERVER_VERSION = (() => {
|
|
39931
39960
|
try {
|
|
39932
39961
|
const pkg = JSON.parse(
|
|
39933
|
-
readFileSync2(
|
|
39962
|
+
readFileSync2(join3(dirname3(fileURLToPath2(import.meta.url)), "..", "package.json"), "utf8")
|
|
39934
39963
|
);
|
|
39935
39964
|
return pkg.version ?? "0.0.0";
|
|
39936
39965
|
} catch {
|
|
@@ -39941,7 +39970,7 @@ function skillUpdateInfo() {
|
|
|
39941
39970
|
let installedSkillVersion = null;
|
|
39942
39971
|
try {
|
|
39943
39972
|
installedSkillVersion = readFileSync2(
|
|
39944
|
-
|
|
39973
|
+
join3(homedir3(), ".claude", "skills", "awesomate-hosting", ".installed-version"),
|
|
39945
39974
|
"utf8"
|
|
39946
39975
|
).trim() || null;
|
|
39947
39976
|
} catch {
|
|
@@ -40016,15 +40045,15 @@ server.registerTool(
|
|
|
40016
40045
|
);
|
|
40017
40046
|
readTool(
|
|
40018
40047
|
"awesomate_n8n_context",
|
|
40019
|
-
"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), builder capability (Support Plus+), instance variant, and build/test quota limits.
|
|
40048
|
+
"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), builder capability (Support Plus+), instance variant, and build/test quota limits. 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).",
|
|
40020
40049
|
"/api/my-n8n/machine/context"
|
|
40021
40050
|
);
|
|
40022
40051
|
server.registerTool(
|
|
40023
40052
|
"awesomate_n8n_deploy",
|
|
40024
40053
|
{
|
|
40025
|
-
description: "Workflow lifecycle writes on the client's n8n, all consent-gated and audited server-side. Actions: 'validate' (structural + n8n-mcp check of workflowJson \u2014 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; agency-managed workflows are refused), 'promote' (swaps a TESTED draft into the live workflow IN PLACE \u2014 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 \u2014 pass operationId), '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.",
|
|
40054
|
+
description: "Workflow lifecycle writes on the client's n8n, all consent-gated and audited server-side. Actions: 'validate' (structural + n8n-mcp check of workflowJson \u2014 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; agency-managed workflows are refused), 'promote' (swaps a TESTED draft into the live workflow IN PLACE \u2014 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 \u2014 pass operationId), 'update_draft' (replace an INACTIVE self-built draft's full JSON in place \u2014 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.",
|
|
40026
40055
|
inputSchema: {
|
|
40027
|
-
action: external_exports.enum(["validate", "create_draft", "activate", "deactivate", "promote", "rollback", "delete_draft"]),
|
|
40056
|
+
action: external_exports.enum(["validate", "create_draft", "update_draft", "activate", "deactivate", "promote", "rollback", "delete_draft"]),
|
|
40028
40057
|
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)."),
|
|
40029
40058
|
workflowId: external_exports.string().optional().describe("Required for activate/deactivate/delete_draft; for promote this is the LIVE workflow id"),
|
|
40030
40059
|
draftId: external_exports.string().optional().describe("promote only: the tested draft to swap into the live workflow"),
|
|
@@ -40039,6 +40068,13 @@ server.registerTool(
|
|
|
40039
40068
|
if (action === "create_draft") {
|
|
40040
40069
|
return textResult(await hubPost(requireConfig(), "/api/my-n8n/machine/workflows/draft", workflowJson ?? {}));
|
|
40041
40070
|
}
|
|
40071
|
+
if (action === "update_draft") {
|
|
40072
|
+
if (!workflowId) return errorResult(new Error("workflowId is required for update_draft"));
|
|
40073
|
+
if (!workflowJson) return errorResult(new Error("workflowJson (full: name, nodes, connections, settings?) is required for update_draft"));
|
|
40074
|
+
return textResult(
|
|
40075
|
+
await hubPatch(requireConfig(), `/api/my-n8n/machine/workflows/${encodeURIComponent(workflowId)}`, workflowJson)
|
|
40076
|
+
);
|
|
40077
|
+
}
|
|
40042
40078
|
if (action === "rollback") {
|
|
40043
40079
|
if (!operationId) return errorResult(new Error("operationId is required for rollback"));
|
|
40044
40080
|
return textResult(
|
|
@@ -40086,6 +40122,166 @@ server.registerTool(
|
|
|
40086
40122
|
}
|
|
40087
40123
|
}
|
|
40088
40124
|
);
|
|
40125
|
+
server.registerTool(
|
|
40126
|
+
"awesomate_n8n_workflows",
|
|
40127
|
+
{
|
|
40128
|
+
description: "The client's workflows. No id \u2192 EVERY workflow as a node-level summary in one call (nodeCount, nodeTypes, triggers, usesAi, communityNodes, dates; ?active filter + pagination) \u2014 use this for the session's world picture instead of fetching workflows one by one. With id \u2192 that workflow's JSON: detail 'full' (default \u2014 nodes with parameters, connections, settings) or 'structure' (nodes WITHOUT parameters + connections \u2014 cheap shape check for big workflows). 403 consent_required \u2192 send the user to settingsUrl and re-check.",
|
|
40129
|
+
inputSchema: {
|
|
40130
|
+
id: external_exports.string().optional().describe("Workflow id for a single-workflow read; omit for the all-workflows summary"),
|
|
40131
|
+
detail: external_exports.enum(["full", "structure"]).optional().describe("Single-workflow only. 'structure' strips node parameters"),
|
|
40132
|
+
active: external_exports.enum(["1", "0"]).optional().describe("Summary only: filter by active state"),
|
|
40133
|
+
limit: external_exports.number().optional(),
|
|
40134
|
+
offset: external_exports.number().optional()
|
|
40135
|
+
}
|
|
40136
|
+
},
|
|
40137
|
+
async ({ id, detail, active, limit, offset }) => {
|
|
40138
|
+
try {
|
|
40139
|
+
if (!id) {
|
|
40140
|
+
const qs = new URLSearchParams();
|
|
40141
|
+
if (active) qs.set("active", active);
|
|
40142
|
+
if (limit) qs.set("limit", String(limit));
|
|
40143
|
+
if (offset) qs.set("offset", String(offset));
|
|
40144
|
+
const q = qs.toString();
|
|
40145
|
+
return textResult(await hubGet(requireConfig(), `/api/my-n8n/machine/workflows${q ? `?${q}` : ""}`));
|
|
40146
|
+
}
|
|
40147
|
+
const full = await hubGet(requireConfig(), `/api/my-n8n/workflows/${encodeURIComponent(id)}`);
|
|
40148
|
+
if (detail === "structure" && full?.workflow?.nodes) {
|
|
40149
|
+
full.workflow.nodes = full.workflow.nodes.map((n) => {
|
|
40150
|
+
const { parameters: _p, ...rest } = n;
|
|
40151
|
+
return rest;
|
|
40152
|
+
});
|
|
40153
|
+
}
|
|
40154
|
+
return textResult(full);
|
|
40155
|
+
} catch (err) {
|
|
40156
|
+
return errorResult(err);
|
|
40157
|
+
}
|
|
40158
|
+
}
|
|
40159
|
+
);
|
|
40160
|
+
server.registerTool(
|
|
40161
|
+
"awesomate_n8n_inspect",
|
|
40162
|
+
{
|
|
40163
|
+
description: `Instance inventory reads, one tool: 'nodes' (distinct node types in use, counts, versions, community/AI flags), 'datatables' (tables + columns + row counts), 'datatable_rows' (pass datatableId; limit \u2264 100), 'possibilities' (facts for "what could I automate": connected services with live-usage cross-check, unused connections, top nodes, AI tools [null = unknown, not none], community packages, counts \u2014 YOU turn these into suggestions, grounded only in what's actually there), 'credentials' (names/types/inferred service \u2014 never secrets), 'variables' ($vars keys). All consent-gated server-side; 403 consent_required \u2192 settingsUrl.`,
|
|
40164
|
+
inputSchema: {
|
|
40165
|
+
what: external_exports.enum(["nodes", "datatables", "datatable_rows", "possibilities", "credentials", "variables"]),
|
|
40166
|
+
datatableId: external_exports.string().optional().describe("datatable_rows only"),
|
|
40167
|
+
limit: external_exports.number().optional().describe("datatable_rows only (max 100)")
|
|
40168
|
+
}
|
|
40169
|
+
},
|
|
40170
|
+
async ({ what, datatableId, limit }) => {
|
|
40171
|
+
try {
|
|
40172
|
+
const cfg = requireConfig();
|
|
40173
|
+
if (what === "datatable_rows") {
|
|
40174
|
+
if (!datatableId) return errorResult(new Error("datatableId is required for datatable_rows"));
|
|
40175
|
+
const q = limit ? `?limit=${limit}` : "";
|
|
40176
|
+
return textResult(await hubGet(cfg, `/api/my-n8n/machine/datatables/${encodeURIComponent(datatableId)}/rows${q}`));
|
|
40177
|
+
}
|
|
40178
|
+
const path = {
|
|
40179
|
+
nodes: "/api/my-n8n/machine/nodes",
|
|
40180
|
+
datatables: "/api/my-n8n/machine/datatables",
|
|
40181
|
+
possibilities: "/api/my-n8n/machine/possibilities",
|
|
40182
|
+
credentials: "/api/my-n8n/machine/credentials",
|
|
40183
|
+
variables: "/api/my-n8n/machine/variables"
|
|
40184
|
+
}[what];
|
|
40185
|
+
return textResult(await hubGet(cfg, path));
|
|
40186
|
+
} catch (err) {
|
|
40187
|
+
return errorResult(err);
|
|
40188
|
+
}
|
|
40189
|
+
}
|
|
40190
|
+
);
|
|
40191
|
+
server.registerTool(
|
|
40192
|
+
"awesomate_n8n_executions",
|
|
40193
|
+
{
|
|
40194
|
+
description: "Execution reads. workflowId \u2192 recent executions of that workflow. executionId \u2192 full detail with error summary. executionId + debug:true \u2192 node-by-node decode (statuses, timings, errors, 2 example items per node) \u2014 the best failure-diagnosis view; needs the 'error content analysis' privacy toggle (403 consent_required \u2192 settingsUrl), and responses with tooLarge:true mean the payload exceeded 15MB \u2014 fall back to the non-debug detail.",
|
|
40195
|
+
inputSchema: {
|
|
40196
|
+
workflowId: external_exports.string().optional(),
|
|
40197
|
+
executionId: external_exports.string().optional(),
|
|
40198
|
+
debug: external_exports.boolean().optional()
|
|
40199
|
+
}
|
|
40200
|
+
},
|
|
40201
|
+
async ({ workflowId, executionId, debug }) => {
|
|
40202
|
+
try {
|
|
40203
|
+
const cfg = requireConfig();
|
|
40204
|
+
if (executionId && debug) {
|
|
40205
|
+
return textResult(await hubGet(cfg, `/api/my-n8n/machine/executions/${encodeURIComponent(executionId)}/debug`));
|
|
40206
|
+
}
|
|
40207
|
+
if (executionId) {
|
|
40208
|
+
return textResult(await hubGet(cfg, `/api/my-n8n/executions/${encodeURIComponent(executionId)}`));
|
|
40209
|
+
}
|
|
40210
|
+
if (workflowId) {
|
|
40211
|
+
return textResult(await hubGet(cfg, `/api/my-n8n/workflows/${encodeURIComponent(workflowId)}/executions`));
|
|
40212
|
+
}
|
|
40213
|
+
return errorResult(new Error("Pass workflowId (list) or executionId (detail; add debug:true for node-by-node)"));
|
|
40214
|
+
} catch (err) {
|
|
40215
|
+
return errorResult(err);
|
|
40216
|
+
}
|
|
40217
|
+
}
|
|
40218
|
+
);
|
|
40219
|
+
server.registerTool(
|
|
40220
|
+
"awesomate_n8n_node_docs",
|
|
40221
|
+
{
|
|
40222
|
+
description: "Live n8n documentation, 500+ nodes + 2,500+ community templates \u2014 ALWAYS prefer this over memory for node schemas and typeVersions. tools: search_nodes {query}, get_node {nodeType \u2014 full form like 'n8n-nodes-base.gmail' works, add detail:'full' for everything}, search_templates {query} / get_template {templateId} (real importable community workflows \u2014 great starting points), validate_node {nodeType, config}, tools_documentation {}. Works on every plan, no consent needed. 503 node_catalog_unavailable \u2192 use the skill's references/vendor/ files instead; 422 catalog_tool_error \u2192 YOUR args were wrong (message says why), the catalog is fine.",
|
|
40223
|
+
inputSchema: {
|
|
40224
|
+
tool: external_exports.enum(["search_nodes", "get_node", "search_templates", "get_template", "validate_node", "tools_documentation"]),
|
|
40225
|
+
args: external_exports.record(external_exports.unknown()).optional().describe("Arguments passed to the catalog tool verbatim")
|
|
40226
|
+
}
|
|
40227
|
+
},
|
|
40228
|
+
async ({ tool, args }) => {
|
|
40229
|
+
try {
|
|
40230
|
+
return textResult(await hubPost(requireConfig(), `/api/my-n8n/machine/node-catalog/${tool}`, args ?? {}));
|
|
40231
|
+
} catch (err) {
|
|
40232
|
+
return errorResult(err);
|
|
40233
|
+
}
|
|
40234
|
+
}
|
|
40235
|
+
);
|
|
40236
|
+
server.registerTool(
|
|
40237
|
+
"awesomate_n8n_datatable_write",
|
|
40238
|
+
{
|
|
40239
|
+
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.",
|
|
40240
|
+
inputSchema: {
|
|
40241
|
+
action: external_exports.enum(["create", "add_column", "insert", "update", "delete_rows"]),
|
|
40242
|
+
tableId: external_exports.string().optional(),
|
|
40243
|
+
name: external_exports.string().optional().describe("create: table name; add_column: column name"),
|
|
40244
|
+
columns: external_exports.array(external_exports.object({ name: external_exports.string(), type: external_exports.enum(["string", "number", "boolean", "date"]).optional() })).optional(),
|
|
40245
|
+
workflowId: external_exports.string().optional().describe("create: co-locate the table with this workflow (recommended)"),
|
|
40246
|
+
type: external_exports.enum(["string", "number", "boolean", "date"]).optional().describe("add_column only"),
|
|
40247
|
+
rows: external_exports.array(external_exports.record(external_exports.unknown())).optional().describe("insert only"),
|
|
40248
|
+
filter: external_exports.record(external_exports.unknown()).optional().describe("update/delete_rows: {filters:[{columnName,condition,value}], type?}"),
|
|
40249
|
+
data: external_exports.record(external_exports.unknown()).optional().describe("update only: column \u2192 new value")
|
|
40250
|
+
}
|
|
40251
|
+
},
|
|
40252
|
+
async ({ action, tableId, name, columns, workflowId, type, rows, filter, data }) => {
|
|
40253
|
+
try {
|
|
40254
|
+
const cfg = requireConfig();
|
|
40255
|
+
if (action === "create") {
|
|
40256
|
+
return textResult(await hubPost(cfg, "/api/my-n8n/machine/datatables", { name, columns, workflowId }));
|
|
40257
|
+
}
|
|
40258
|
+
if (!tableId) return errorResult(new Error(`tableId is required for ${action}`));
|
|
40259
|
+
const base = `/api/my-n8n/machine/datatables/${encodeURIComponent(tableId)}`;
|
|
40260
|
+
if (action === "add_column") {
|
|
40261
|
+
return textResult(await hubPost(cfg, `${base}/columns`, { name, type }));
|
|
40262
|
+
}
|
|
40263
|
+
const mode = action === "delete_rows" ? "delete" : action;
|
|
40264
|
+
return textResult(await hubPost(cfg, `${base}/rows`, { mode, rows, filter, data }));
|
|
40265
|
+
} catch (err) {
|
|
40266
|
+
return errorResult(err);
|
|
40267
|
+
}
|
|
40268
|
+
}
|
|
40269
|
+
);
|
|
40270
|
+
server.registerTool(
|
|
40271
|
+
"awesomate_skill_update",
|
|
40272
|
+
{
|
|
40273
|
+
description: "Refresh the locally installed Awesomate skills from this (always-latest) server package \u2014 run when awesomate_get_context reports skill.updateAvailable. Copies every bundled skill into ~/.claude/skills and re-stamps versions. New skill content applies from the NEXT Claude Code session; finish the current task first, then suggest a restart.",
|
|
40274
|
+
inputSchema: {}
|
|
40275
|
+
},
|
|
40276
|
+
async () => {
|
|
40277
|
+
try {
|
|
40278
|
+
const result = installSkills(SERVER_VERSION);
|
|
40279
|
+
return textResult({ ...result, note: "Updated skill files load in the next Claude Code session." });
|
|
40280
|
+
} catch (err) {
|
|
40281
|
+
return errorResult(err);
|
|
40282
|
+
}
|
|
40283
|
+
}
|
|
40284
|
+
);
|
|
40089
40285
|
readTool(
|
|
40090
40286
|
"awesomate_get_hosting_status",
|
|
40091
40287
|
"The hosting account's provisioning state: eligible/provisioned flags, in-progress provisioning step, primary domain, cPanel server, DNS targets. Use before suggesting any site action.",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomate/hosting-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Awesomate MCP server
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Awesomate MCP server \u2014 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",
|
|
7
7
|
"publishConfig": {
|
|
@@ -52,7 +52,7 @@ machinery that does it.
|
|
|
52
52
|
If the app needs to **send an email, look something up in their apps (Sheets,
|
|
53
53
|
CRM, a database), or use AI** — their **own n8n** is often the fastest path,
|
|
54
54
|
because their credentials are already connected there. Check the credential
|
|
55
|
-
inventory (`
|
|
55
|
+
inventory (`awesomate_n8n_inspect {what:'credentials'}`) and say e.g. *"you already
|
|
56
56
|
have Gmail connected in n8n — want the form to email you through that?"* Use
|
|
57
57
|
the **awesomate-n8n** skill to build the workflow, then store its webhook URL
|
|
58
58
|
in the app (see the awesomate-credentials skill) and call it from the app.
|
|
@@ -118,6 +118,10 @@ commit + push (redeploys the previous good state), or redeploy an earlier good
|
|
|
118
118
|
SHA. Always `awesomate_app_health` after a promote. Static sites ship their
|
|
119
119
|
files directly (no build step).
|
|
120
120
|
|
|
121
|
+
When the need is "remember/track a list an automation uses" rather than an
|
|
122
|
+
app with a UI, an n8n data table (awesomate-n8n skill) beats building an app
|
|
123
|
+
— no hosting slot, no deploy, queryable from workflows directly.
|
|
124
|
+
|
|
121
125
|
## 3. Hard rules
|
|
122
126
|
|
|
123
127
|
- Non-technical user: explain in plain words, one or two short questions at a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: awesomate-credentials
|
|
3
|
-
description: Safely capture and store API keys, tokens, database URLs and other secrets for the user's Awesomate apps — encrypted in the hub and injected into the app's .env, never committed to git, never echoed back. Use whenever the user pastes something that looks like a secret, says "here's my API key", "add this key", "store this secret / token / password", "save my credentials", or drops a key into a file. Companion to awesomate-app-builder.
|
|
3
|
+
description: Safely capture and store API keys, tokens, database URLs and other secrets for the user's Awesomate apps — encrypted in the hub and injected into the app's .env, never committed to git, never echoed back. Use whenever the user pastes something that looks like a secret, says "here's my API key", "add this key", "store this secret / token / password", "save my credentials", or drops a key into a file. Companion to awesomate-app-builder. If the secret is for an n8n workflow or automation, route to the awesomate-n8n skill instead — n8n credentials are created on the n8n instance, never in .env.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Awesomate Credentials — handle secrets safely
|
|
@@ -26,127 +26,28 @@ generation, defer to WordPress Studio and any installed WordPress skills
|
|
|
26
26
|
|
|
27
27
|
## 0. First run — orient before acting
|
|
28
28
|
|
|
29
|
-
On the first hosting request in a session, call **`awesomate_whoami`** —
|
|
30
|
-
zero-network
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- **`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
refresh the token. If any tool returns a 401, do the same.
|
|
43
|
-
- **`skill.updateAvailable`** — if true, this skill's local files are older than
|
|
44
|
-
the MCP server. Mention it once (don't nag): re-running Connect Claude Code
|
|
45
|
-
from **hub.awesomate.ai/sites** refreshes the skill and renews the token in
|
|
46
|
-
one go. Not urgent — finish the user's actual request first.
|
|
29
|
+
On the first hosting request in a session, call **`awesomate_whoami`** —
|
|
30
|
+
zero-network; it reports WHICH account this folder is connected to and why.
|
|
31
|
+
**If the slug isn't the account the user means, stop and fix the connection
|
|
32
|
+
before any work** — every tool response is stamped `account: <slug> (source:
|
|
33
|
+
…)`; treat a mismatch there the same way. Then call **`awesomate_get_context`**
|
|
34
|
+
once (plus `awesomate_get_limits` before any create/change) and cache:
|
|
35
|
+
|
|
36
|
+
- **`plan`** and **`capabilities.shell`** — decides which branch below you're on.
|
|
37
|
+
- **`patExpiresAt`** — within ~7 days, or any 401: re-run the setup prompt at
|
|
38
|
+
**hub.awesomate.ai/sites → Connect Claude Code** to refresh the token.
|
|
39
|
+
- **`skill.updateAvailable`** — this skill's local files are older than the MCP
|
|
40
|
+
server. Mention once (don't nag); the same Connect re-run refreshes the skill
|
|
41
|
+
and renews the token in one go. Not urgent — finish the user's request first.
|
|
47
42
|
- **`cpanel`** routing (host/user), present once hosting is provisioned.
|
|
48
43
|
|
|
49
44
|
If `awesomate_get_context` fails with a connectivity error, it's the user's
|
|
50
45
|
network or the API base — not an auth problem; say so.
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`.awesomate.json` pin (`{"account": "<slug>"}`) written by the bootstrap in the
|
|
57
|
-
folder it ran in. Resolution order: `AWESOMATE_PAT` env → `AWESOMATE_ACCOUNT`
|
|
58
|
-
env → nearest folder pin (walking up, stopping at `$HOME`) → sole profile →
|
|
59
|
-
`defaultProfile`. A pin naming a missing profile is a **hard error, never a
|
|
60
|
-
fallback** — that's deliberate.
|
|
61
|
-
|
|
62
|
-
- **Wrong account connected?** Compare `awesomate_whoami` against the folder's
|
|
63
|
-
`.awesomate.json`. Fix by editing the pin (if the profile exists) or by
|
|
64
|
-
running Connect Claude Code from the hub **while logged into the right hub
|
|
65
|
-
account, from the right folder** — the connect command carries
|
|
66
|
-
`--account <slug>` and the bootstrap aborts on a mismatch instead of storing
|
|
67
|
-
anything.
|
|
68
|
-
- **"Multiple accounts … folder isn't pinned" error?** Create the pin file or
|
|
69
|
-
set `AWESOMATE_ACCOUNT`. Don't guess an account for the user.
|
|
70
|
-
- Connecting a second account never disconnects the first; re-pairing an
|
|
71
|
-
account just refreshes its profile.
|
|
72
|
-
- The bootstrap prints a final `AWESOMATE CONNECT: SUCCESS account=<slug>` (or
|
|
73
|
-
`PARTIAL … issues=…` / `FAILED reason=…`) sentinel — when a connect ran as a
|
|
74
|
-
`!` bang command, check for that line instead of assuming success from
|
|
75
|
-
silence. `PARTIAL` means the token/pin are stored but a step (listed in
|
|
76
|
-
`issues=`) needs the printed manual fix.
|
|
77
|
-
|
|
78
|
-
### Sandboxed / ephemeral environments (cloud agent containers)
|
|
79
|
-
|
|
80
|
-
- **Egress proxy**: if `HTTPS_PROXY`/`HTTP_PROXY` is set, the environment
|
|
81
|
-
forces traffic through a proxy that Node's built-in fetch ignores — requests
|
|
82
|
-
bypass it and the gateway answers 403, which looks like a bad code/token but
|
|
83
|
-
is a transport failure. The bootstrap and MCP server handle this themselves
|
|
84
|
-
(undici env-proxy agent); if an older version is in play, prefix commands
|
|
85
|
-
with `NODE_USE_ENV_PROXY=1`. Diagnostic: `curl` works but `node -e "fetch(…)"`
|
|
86
|
-
403s → proxy bypass, not credentials.
|
|
87
|
-
- **Interrupted connect?** Setup codes are re-runnable for their whole
|
|
88
|
-
10-minute life (each run mints a fresh token), and `--pat amt_pat_…` resumes
|
|
89
|
-
with an already-redeemed token — never tell the user their code is spent
|
|
90
|
-
unless the API literally said so.
|
|
91
|
-
- **Nothing persists**: `~/.awesomate`, the skill copy, and the MCP
|
|
92
|
-
registration all vanish with the container. Treat a container connect as a
|
|
93
|
-
diagnosis/test, and tell the user a real workstation is needed for a lasting
|
|
94
|
-
install.
|
|
95
|
-
- **No ssh client**: containers usually lack `ssh-keygen`/`ssh`, so deploy and
|
|
96
|
-
shell are unavailable — reads and management calls still work. The bootstrap
|
|
97
|
-
skips SSH with a note rather than failing.
|
|
98
|
-
- Never probe connectivity with a POST to `/redeem` — it's state-changing. Use
|
|
99
|
-
`GET {apiBase}/api/hosting-access/context` (401 without a token still proves
|
|
100
|
-
reachability).
|
|
101
|
-
|
|
102
|
-
### When you're stuck: generate a support report
|
|
103
|
-
|
|
104
|
-
If a connect or tool failure survives the documented fixes above (wrong
|
|
105
|
-
account, proxy, resume, restart, legacy registrations), don't keep guessing —
|
|
106
|
-
hand Awesomate a diagnostic they can act on:
|
|
107
|
-
|
|
108
|
-
1. Run `node ~/.claude/skills/awesomate-hosting/scripts/support-report.mjs
|
|
109
|
-
--note "<one line: what the user was doing and what happened>"`.
|
|
110
|
-
It writes a **fully redacted** report to
|
|
111
|
-
`~/.awesomate/support-report-<timestamp>.md` — tokens reduced to
|
|
112
|
-
prefix+last4, no key material, proxy credentials stripped. It includes
|
|
113
|
-
versions, profiles/pin/registration state, live connectivity probes, and
|
|
114
|
-
the last bootstrap log automatically.
|
|
115
|
-
2. Show the user the file path and the headline findings (the ACTIVE line,
|
|
116
|
-
any ⚠ LEGACY registration flags, and the probe results).
|
|
117
|
-
3. **Ask the user before submitting.** With their OK, re-run with `--submit`
|
|
118
|
-
— it POSTs the report to Awesomate and returns a reference like
|
|
119
|
-
`ASR-XXXXXXXX`. Tell the user to quote that reference to
|
|
120
|
-
support@awesomate.ai or their Awesomate contact; the report is already
|
|
121
|
-
attached to it server-side. Submission works even when the token is
|
|
122
|
-
broken (that's usually why you're here).
|
|
123
|
-
4. If `--submit` fails too (fully offline), the user emails the file itself —
|
|
124
|
-
it's safe to send as-is.
|
|
125
|
-
|
|
126
|
-
Never edit the report to add raw tokens, codes, or keys, and never submit
|
|
127
|
-
without the user's explicit go-ahead.
|
|
128
|
-
|
|
129
|
-
If this skill is loaded but **no `awesomate_*` tools exist in the session at
|
|
130
|
-
all**, the MCP server was registered after Claude Code started (the bootstrap
|
|
131
|
-
just ran). Don't investigate settings files or reinstall anything — and don't
|
|
132
|
-
make a restart the precondition for showing the user their own data. The
|
|
133
|
-
skill works right now over REST — resolve the ACTIVE profile first (run
|
|
134
|
-
`node ~/.claude/skills/awesomate-hosting/scripts/resolve-account.mjs --api` to
|
|
135
|
-
get `API`/`PAT`/`ACCT`; never read top-level `pat` directly when a `profiles`
|
|
136
|
-
map exists, and never echo the pat into the conversation) and GET with
|
|
137
|
-
`Authorization: Bearer <pat>`:
|
|
138
|
-
|
|
139
|
-
| MCP tool | REST equivalent |
|
|
140
|
-
|---|---|
|
|
141
|
-
| `awesomate_get_context` | `GET {apiBase}/api/hosting-access/context` |
|
|
142
|
-
| `awesomate_get_hosting_status` | `GET {apiBase}/api/client-hosting/status` |
|
|
143
|
-
| `awesomate_get_hosting_account` | `GET {apiBase}/api/client-hosting/account` |
|
|
144
|
-
| `awesomate_list_sites` | `GET {apiBase}/api/client-hosting/sites` |
|
|
145
|
-
| `awesomate_list_domains` | `GET {apiBase}/api/client-hosting/domains` |
|
|
146
|
-
| `awesomate_get_limits` | `GET {apiBase}/api/client-hosting/limits` |
|
|
147
|
-
|
|
148
|
-
Serve the request with these now, then suggest restarting Claude Code at a
|
|
149
|
-
natural break so the richer MCP integration loads.
|
|
47
|
+
References: `references/multi-account.md` (profiles, pins, resolution order,
|
|
48
|
+
wrong account) · `references/connect-troubleshooting.md` (bootstrap, sandbox/
|
|
49
|
+
proxy failures, resuming a connect, support report) ·
|
|
50
|
+
`references/rest-fallback.md` (no `awesomate_*` tools — serve over REST).
|
|
150
51
|
|
|
151
52
|
## 1. The plan model (so your nudges are accurate)
|
|
152
53
|
|
|
@@ -157,36 +58,35 @@ natural break so the richer MCP integration loads.
|
|
|
157
58
|
| **Pro** | 10 | 20 | 10 | **Yes** | + higher limits |
|
|
158
59
|
| **Embedded** | 100 | 100 | 100 | **Yes** | agency tier, not generally available |
|
|
159
60
|
|
|
160
|
-
Authoritative limits are
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
61
|
+
Authoritative limits are what `awesomate_get_limits` returns for THIS account
|
|
62
|
+
(`awesomate_get_plan_features` fetches the live ladder from the hub) — never
|
|
63
|
+
quote the table above as fact; use it only to explain upgrades. App creation
|
|
64
|
+
past the cap returns a 409 with code `app_limit` — don't retry; surface the
|
|
65
|
+
recommended plan instead.
|
|
165
66
|
|
|
166
67
|
## 2. Branch by capability
|
|
167
68
|
|
|
168
69
|
### Essentials (no shell) — read, report, nudge
|
|
169
70
|
|
|
170
|
-
Allowed: `awesomate_get_context`, `_get_hosting_status
|
|
171
|
-
`_list_sites`, `_list_domains`, `_get_limits
|
|
172
|
-
|
|
173
|
-
|
|
71
|
+
Allowed: `awesomate_get_context`, `_get_hosting_status` (hosting stats),
|
|
72
|
+
`_get_hosting_account`, `_list_sites`, `_list_domains`, `_get_limits` (plan
|
|
73
|
+
limits AND workflow/AI-editor credit balances), `_get_plan_features` (live plan
|
|
74
|
+
ladder), and 1-click WP-admin / cPanel SSO links. Billing/plan changes: §4.
|
|
174
75
|
|
|
175
76
|
Never attempt SSH, WP-CLI, snapshot/rollback, staging, deploy, multi-site —
|
|
176
77
|
those tools will 403. Instead, surface the specific limit and what
|
|
177
|
-
Support Plus/Pro unlocks (
|
|
78
|
+
Support Plus/Pro unlocks (§4), and link the hub billing page.
|
|
178
79
|
|
|
179
80
|
### Support Plus and above (shell) — full workflow
|
|
180
81
|
|
|
181
82
|
You additionally have: jailed SSH to the client's own cPanel account, WP-CLI
|
|
182
|
-
|
|
83
|
+
via `scripts/wp.sh` over that SSH (or raw SSH via `scripts/ssh-connect.sh`),
|
|
183
84
|
snapshot/rollback, **WP staging on awesomate.dev** (§5a), and the local-first
|
|
184
85
|
deploy flow (§5). Golden rule, always:
|
|
185
86
|
|
|
186
87
|
> **Local first, live never — and snapshot before you touch live.**
|
|
187
88
|
|
|
188
|
-
**Ask "live or dev?" before posting anything user-facing
|
|
189
|
-
you to change/publish something on their WordPress site, ask: *"Want me to put
|
|
89
|
+
**Ask "live or dev?" before posting anything user-facing** — *"Want me to put
|
|
190
90
|
this on your live site, or on your private dev copy (awesomate.dev) so you can
|
|
191
91
|
review it first?"* Default suggestion: dev first, publish after they've looked
|
|
192
92
|
at it. Their dev copy is invisible to Google and AI crawlers by policy.
|
|
@@ -196,27 +96,26 @@ at it. Their dev copy is invisible to Google and AI crawlers by policy.
|
|
|
196
96
|
- **Before ANY change to a live site** — plugin/theme/core update, `search-replace`,
|
|
197
97
|
bulk edit, deploy — call **`awesomate_snapshot_site`** first and tell the user the
|
|
198
98
|
`snapshotId`. If it goes wrong, `awesomate_rollback_site` restores files + DB.
|
|
199
|
-
- **Confirm before destructive actions
|
|
200
|
-
`
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
99
|
+
- **Confirm before destructive actions** — `awesomate_rollback_site`,
|
|
100
|
+
`awesomate_site_staging_promote` (replaces live), `_site_staging_discard`
|
|
101
|
+
(loses unpublished staging work), dropping tables, `wp db reset`, deleting
|
|
102
|
+
content. State exactly what will be lost and wait for an explicit "yes".
|
|
103
|
+
- **Site deletion has no MCP tool.** The user deletes sites themselves at
|
|
104
|
+
**hub.awesomate.ai** — deep-link them there; never script around it.
|
|
204
105
|
- Prefer building/testing in **WordPress Studio locally**, then deploy (§5).
|
|
205
106
|
- Dry-run risky WP-CLI where the command supports it before the real run.
|
|
206
107
|
|
|
207
108
|
## 4. Limits & upgrade etiquette
|
|
208
109
|
|
|
209
110
|
Before any create action (install a site, add a domain, a heavy build) call
|
|
210
|
-
`awesomate_get_limits`.
|
|
211
|
-
returns 403 for a plan reason:
|
|
111
|
+
`awesomate_get_limits`. On `approaching`/`exceeded`, or a plan-reason 403:
|
|
212
112
|
|
|
213
|
-
1. Explain plainly what they've hit and what the next plan unlocks (
|
|
214
|
-
nudge's `recommendedPlan`).
|
|
215
|
-
2.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
downgrades/cancels always go to the hub billing page via the deep-link tool.
|
|
113
|
+
1. Explain plainly what they've hit and what the next plan unlocks (the
|
|
114
|
+
nudge's `recommendedPlan`; `awesomate_get_plan_features` has the live ladder).
|
|
115
|
+
2. To change plan, deep-link `https://hub.awesomate.ai/billing`
|
|
116
|
+
(`?upgrade=<plan>` preselects). No billing tool exists in this MCP —
|
|
117
|
+
**never** trigger a charge, downgrade, or cancellation yourself; upgrades,
|
|
118
|
+
downgrades, and cancels all happen on the hub billing page.
|
|
220
119
|
|
|
221
120
|
## 5. Local-first deploy (Support Plus+)
|
|
222
121
|
|
|
@@ -270,25 +169,17 @@ Git skills drive the Git workflow; this skill just deploys the result.
|
|
|
270
169
|
|
|
271
170
|
## 7. Bundled scripts (`scripts/`)
|
|
272
171
|
|
|
273
|
-
- `bootstrap.mjs` — one-time setup: redeems the hub setup code for a scoped
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
step fails (e.g. hosting not fully provisioned), the token + skill + MCP are
|
|
278
|
-
still set up. The Connect-Claude-Code prompt from the hub runs this via
|
|
279
|
-
`npx -y --package=@awesomate/hosting-mcp awesomate-hosting-bootstrap`.
|
|
280
|
-
(Always the `--package=` form — a bare `-p` breaks the claude CLI's argv
|
|
281
|
-
pre-scan if the command is ever wrapped in `claude mcp add`.)
|
|
172
|
+
- `bootstrap.mjs` — one-time setup: redeems the hub setup code for a scoped Run it with `--update` to refresh the installed skills from the current package without redeeming a new setup code.
|
|
173
|
+
token (chmod 600), **installs this skill into `~/.claude/skills`**, registers
|
|
174
|
+
the MCP server, best-effort SSH setup (Support Plus+). Invocation + failure
|
|
175
|
+
modes: `references/connect-troubleshooting.md`.
|
|
282
176
|
- `ssh-connect.sh` — open a jailed SSH session (or run one remote command).
|
|
283
177
|
- `wp.sh` — run a WP-CLI command against a live site over that SSH.
|
|
284
178
|
- `deploy.sh` — snapshot-first Studio→live deploy (files, optional DB).
|
|
285
179
|
- `pull-live.sh` — clone a live site down to a local folder (read-only on live).
|
|
286
|
-
- `resolve-account.mjs` —
|
|
287
|
-
|
|
288
|
-
`--ssh` emits the ssh block.
|
|
180
|
+
- `resolve-account.mjs` — account resolver (pin/env/profile precedence) for
|
|
181
|
+
shell scripts + REST fallback; `--api` emits API/PAT/ACCT, `--ssh` ssh block.
|
|
289
182
|
- `support-report.mjs` — redacted diagnostic bundle for Awesomate support
|
|
290
|
-
(
|
|
291
|
-
reference ID.
|
|
183
|
+
(`references/connect-troubleshooting.md`); `--submit` returns a reference ID.
|
|
292
184
|
|
|
293
|
-
All scripts read `~/.awesomate/credentials.json`; none take secrets on the
|
|
294
|
-
command line.
|
|
185
|
+
All scripts read `~/.awesomate/credentials.json`; none take secrets on the CLI.
|