@awesomate/hosting-mcp 0.19.1 → 0.20.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 +234 -24
- package/package.json +2 -2
- package/skill/CHANGELOG.json +16 -2
- package/skill/awesomate-app-builder/SKILL.md +53 -3
- package/skill/awesomate-app-builder/references/stack-decision.md +36 -9
- package/skill/awesomate-app-builder/references/wp-migrate.md +4 -2
- package/skill/awesomate-credentials/SKILL.md +41 -4
- package/skill/awesomate-database/SKILL.md +60 -15
- package/skill/awesomate-github/SKILL.md +49 -8
- package/skill/awesomate-github/scripts/github-setup.mjs +4 -1
- package/skill/awesomate-hosting/SKILL.md +131 -20
- package/skill/awesomate-hosting/references/voice.md +1 -1
- package/skill/awesomate-knowledge/SKILL.md +37 -4
- package/skill/awesomate-knowledge/references/from-your-files.md +121 -0
- package/skill/awesomate-knowledge/references/showing-media.md +59 -0
- package/skill/awesomate-n8n/SKILL.md +37 -11
- package/skill/awesomate-n8n/references/error-handling.md +3 -1
- package/skill/awesomate-n8n/references/platform-notes.md +3 -1
- package/skill/awesomate-n8n/references/recurring-reports.md +13 -6
- package/skill/awesomate-n8n/references/rest-fallback.md +7 -2
- package/skill/awesomate-n8n/references/troubleshooting.md +3 -1
- package/skill/awesomate-seo/SKILL.md +109 -20
- package/skill/awesomate-support/SKILL.md +59 -12
|
@@ -47,8 +47,13 @@ value goes browser → destination directly; you only ever see the key NAMES.
|
|
|
47
47
|
node ~/.claude/skills/awesomate-credentials/scripts/secret-drop.mjs \
|
|
48
48
|
--hub-app <appId> --env dev --keys STRIPE_SECRET_KEY --port <port> --token <hex>
|
|
49
49
|
```
|
|
50
|
-
Get `<appId>` from `awesomate_app_list`. Keys
|
|
51
|
-
|
|
50
|
+
Get `<appId>` from `awesomate_app_list`. Keys must be UPPER_SNAKE: the
|
|
51
|
+
drop script uppercases what you pass it in hub mode, but the
|
|
52
|
+
`awesomate_app_set_env` TOOL does not — it hard-rejects anything that
|
|
53
|
+
isn't `^[A-Z][A-Z0-9_]{0,63}$`, so a lowercase name or a leading
|
|
54
|
+
underscore is a validation error there, not a tidy-up. Pick the final
|
|
55
|
+
uppercase name once and use it in both places. Node apps only — static
|
|
56
|
+
sites have no server env (`set_env` returns 400 for them). The
|
|
52
57
|
script posts each value to the hub with the user's own PAT
|
|
53
58
|
(`~/.awesomate/credentials.json`) — the same route `awesomate_app_set_env`
|
|
54
59
|
uses, so encryption, `.env` injection and restart all behave identically.
|
|
@@ -71,6 +76,26 @@ value goes browser → destination directly; you only ever see the key NAMES.
|
|
|
71
76
|
6. Confirm with key names only. No rotation warning needed — the value never
|
|
72
77
|
entered the conversation.
|
|
73
78
|
|
|
79
|
+
### What the drop link can't do
|
|
80
|
+
|
|
81
|
+
- **The link is short-lived and single-use.** It expires after 15 minutes
|
|
82
|
+
(`--ttl <minutes>` to change it) and the server exits after the FIRST
|
|
83
|
+
successful save unless you passed `--stay`. If the user comes back later
|
|
84
|
+
and the page is dead, that's expected — start a fresh one on a new port
|
|
85
|
+
with a new token rather than telling them to retry the old link.
|
|
86
|
+
- **It cannot carry a MULTI-LINE value.** The bulk box is parsed line by
|
|
87
|
+
line, splitting on the first `=`, so a PEM private key or a Google
|
|
88
|
+
service-account JSON loses everything after line 1 — silently, and those
|
|
89
|
+
are two of the commonest secrets people have. The named field is a
|
|
90
|
+
single-line input, so it can't hold one either. For a multi-line secret,
|
|
91
|
+
either:
|
|
92
|
+
- **base64 it into one line** — `base64 -i key.pem | tr -d '\n'` — drop
|
|
93
|
+
that through the link as e.g. `GOOGLE_SA_JSON_B64`, and decode it in the
|
|
94
|
+
app at startup; or
|
|
95
|
+
- have the user **save it to a file** on their machine and tell you the
|
|
96
|
+
path, then read and store it — being honest that reading it puts the
|
|
97
|
+
value in the conversation record, so the rotation nudge applies.
|
|
98
|
+
|
|
74
99
|
## Detect and offer
|
|
75
100
|
|
|
76
101
|
If the user's message contains something shaped like a secret — `sk-…`,
|
|
@@ -94,14 +119,26 @@ full map. Short version:
|
|
|
94
119
|
the file-mode link; add a rotation note if it came through the chat.
|
|
95
120
|
- **Never** a tracked file, a commit, or the chat.
|
|
96
121
|
|
|
122
|
+
A secret for an n8n workflow belongs on the n8n instance (awesomate-n8n
|
|
123
|
+
skill), never in an app `.env`. Those tools are consent-gated: if one comes
|
|
124
|
+
back 403 `consent_required`, call `awesomate_privacy_settings` — it names
|
|
125
|
+
the exact toggle that's off, so you can send the user to the right switch at
|
|
126
|
+
hub.awesomate.ai/n8n/settings instead of guessing. You can't flip it
|
|
127
|
+
for them.
|
|
128
|
+
|
|
97
129
|
## Fallback: the file-drop flow
|
|
98
130
|
|
|
99
131
|
Only when the link flow can't work (e.g. Claude is running on a remote machine
|
|
100
132
|
the user's browser can't reach as 127.0.0.1):
|
|
101
133
|
|
|
102
134
|
1. Tell them: *"Create a file `.awesomate/secret-inbox.txt` in your project and
|
|
103
|
-
paste the value there — I'll grab it and wipe the file."*
|
|
104
|
-
|
|
135
|
+
paste the value there — I'll grab it and wipe the file."*
|
|
136
|
+
**Verify `.gitignore` yourself before any commit.** Don't assume the
|
|
137
|
+
folder is ignored: the github skill's setup script adds `.awesomate/` only
|
|
138
|
+
when it has actually been run in this project, and older installed copies
|
|
139
|
+
of that script didn't list it at all. `grep -q '^\.awesomate/' .gitignore`
|
|
140
|
+
— add the line if it's missing, before the file exists, and never commit
|
|
141
|
+
while it does.
|
|
105
142
|
2. Read the file, store via `awesomate_app_set_env`, then **scrub the file**:
|
|
106
143
|
`node ~/.claude/skills/awesomate-credentials/scripts/capture-secret.mjs .awesomate/secret-inbox.txt`
|
|
107
144
|
3. Be honest with the user: reading the file put the value in the conversation
|
|
@@ -26,6 +26,14 @@ co-located with the workflow that uses it. No hosting slot consumed, and
|
|
|
26
26
|
workflows query it directly — this is the default answer for anything
|
|
27
27
|
automation-shaped. Inspect what exists with
|
|
28
28
|
`awesomate_n8n_inspect {what:'datatables'}`.
|
|
29
|
+
**Both the write AND that read are gated:** Support Plus or above, plus the
|
|
30
|
+
privacy toggle **"Allow Claude Code to Build n8n Workflows"** — n8n →
|
|
31
|
+
Settings → Privacy (hub.awesomate.ai/n8n/settings, or the same toggles at
|
|
32
|
+
hub.awesomate.ai/n8n/settings, which is what the 403's
|
|
33
|
+
`settingsUrl` points at). It is **off by default**, so on a fresh account
|
|
34
|
+
both the read and the write come back 403 `consent_required`. Call
|
|
35
|
+
`awesomate_privacy_settings` to name the exact toggle that's off, send the
|
|
36
|
+
user to flip it, then re-check. You cannot flip it for them.
|
|
29
37
|
|
|
30
38
|
**(b) Real APP data** — logins, dashboards, anything relational that an
|
|
31
39
|
app serves to people. → the app's own Postgres.
|
|
@@ -38,7 +46,23 @@ app serves to people. → the app's own Postgres.
|
|
|
38
46
|
**(c) A WORKFLOW that needs raw SQL against its own Postgres** — real
|
|
39
47
|
joins, aggregates, or volumes a data table shouldn't carry. →
|
|
40
48
|
`awesomate_n8n_provision_pg`. One step creates the database AND the n8n
|
|
41
|
-
credential, so the workflow can query it immediately.
|
|
49
|
+
credential, so the workflow can query it immediately. It has the most gates
|
|
50
|
+
of anything here — check them BEFORE offering it, so the user doesn't hit a
|
|
51
|
+
wall halfway:
|
|
52
|
+
- Support Plus or above.
|
|
53
|
+
- The **"Allow Claude Code to Build n8n Workflows"** toggle (off by
|
|
54
|
+
default) — same one as branch (a).
|
|
55
|
+
- The **direct database writes** consent (`allow_pg_writes`). It's on by
|
|
56
|
+
default, so this is rare — but it has **no client-facing toggle in the
|
|
57
|
+
hub**, so if it's off, don't send the user hunting for a switch that
|
|
58
|
+
doesn't exist: route it to support via the awesomate-support skill.
|
|
59
|
+
- An Awesomate cPanel hosting account. Without one it returns 409
|
|
60
|
+
`hosting_required`; hosting comes first (awesomate-hosting skill).
|
|
61
|
+
- Capped at **2 a day**.
|
|
62
|
+
|
|
63
|
+
On any 403 here, call `awesomate_privacy_settings` first — it names the
|
|
64
|
+
exact toggle that's blocking, which decides whether this is a "flip this
|
|
65
|
+
switch" or a "raise it with support" answer.
|
|
42
66
|
|
|
43
67
|
**(d) Analytics/BI or data shared with other systems** — reporting
|
|
44
68
|
warehouses, a spreadsheet the whole team lives in, a CRM. → recommend
|
|
@@ -69,12 +93,19 @@ reach), ask "live or dev?" before provisioning against it.
|
|
|
69
93
|
|
|
70
94
|
## 2. Safety rules
|
|
71
95
|
|
|
72
|
-
- **Passwords
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
96
|
+
- **Passwords land where they belong, and the two branches differ.**
|
|
97
|
+
`awesomate_app_provision_db` NEVER returns a password: it's set
|
|
98
|
+
server-side, stored encrypted, and injected as the app's `DATABASE_URL`
|
|
99
|
+
— there is nothing to show, so don't promise the user a password.
|
|
100
|
+
`awesomate_n8n_provision_pg` is the one that DOES return a password, once,
|
|
101
|
+
because it lives in the n8n credential and Awesomate never stores it. The
|
|
102
|
+
workflow doesn't need you to repeat it — the credential already holds it —
|
|
103
|
+
so say that, and only offer the value if the user actually needs it
|
|
104
|
+
elsewhere, warning that it has now passed through the transcript and
|
|
105
|
+
should be rotated. Never put a `DATABASE_URL` in a message. Tell the user where
|
|
106
|
+
it lives instead: "the app already has its connection — nothing for you
|
|
107
|
+
to copy." (After an app database is provisioned, the app needs a restart
|
|
108
|
+
or redeploy to pick it up.)
|
|
78
109
|
- Secrets the user's own app code needs (API keys, tokens) go through
|
|
79
110
|
the awesomate-credentials skill, never pasted into files or chat.
|
|
80
111
|
- **Deleting data requires an explicit filter and an explicit yes.**
|
|
@@ -84,14 +115,28 @@ reach), ask "live or dev?" before provisioning against it.
|
|
|
84
115
|
|
|
85
116
|
## 3. Limits, honestly
|
|
86
117
|
|
|
87
|
-
|
|
88
|
-
(`awesomate_app_provision_db`)
|
|
89
|
-
(`awesomate_n8n_provision_pg`)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
118
|
+
Everything that provisions here needs **Support Plus or above** — app
|
|
119
|
+
databases (`awesomate_app_provision_db`), workflow Postgres
|
|
120
|
+
(`awesomate_n8n_provision_pg`) and data tables alike. Data tables are NOT
|
|
121
|
+
"any plan with n8n access": Essentials gets 0 creations a day, and both the
|
|
122
|
+
table read and the write also need the "Allow Claude Code to Build n8n
|
|
123
|
+
Workflows" toggle (§0(a)).
|
|
124
|
+
|
|
125
|
+
Only some of it is capped per day:
|
|
126
|
+
- `awesomate_n8n_provision_pg` — **2 a day**, flat; no plan raises it, so
|
|
127
|
+
don't pitch an upgrade for it.
|
|
128
|
+
- Data table creations — **10 a day** on Support Plus and Pro (20 on
|
|
129
|
+
Embedded), 0 on Essentials. An instance also tops out at 50 data tables.
|
|
130
|
+
- `awesomate_app_provision_db` — **no daily cap**. It's one database per
|
|
131
|
+
environment and refuses (409 `already_has_db`) if the app has one, so
|
|
132
|
+
there's nothing to ration.
|
|
133
|
+
|
|
134
|
+
If the user's plan doesn't cover what branch (b) or (c) needs, say it once
|
|
135
|
+
— "app databases are on Support Plus" — point them at
|
|
136
|
+
hub.awesomate.ai/billing to upgrade, then help fully within what their plan
|
|
137
|
+
allows. On Essentials that means none of (a), (b) or (c) is available —
|
|
138
|
+
don't dangle a data table as the consolation prize; say so once and look at
|
|
139
|
+
(d), keeping the data where it already lives and connecting to it. If a
|
|
95
140
|
daily quota is hit, say when it resets and what can proceed meanwhile.
|
|
96
141
|
|
|
97
142
|
Report every result as a business outcome: "your workflow now remembers
|
|
@@ -47,19 +47,48 @@ Ask only: **"What should we call this project?"** (repo name) and, if relevant,
|
|
|
47
47
|
**"Keep it private?"** (default yes). Derive a sensible kebab-case repo name
|
|
48
48
|
from what they tell you.
|
|
49
49
|
|
|
50
|
+
**The script's first push goes to `main`.** It runs `git init -b main` and
|
|
51
|
+
pushes the current branch, so on a fresh repo `main` — the PRODUCTION branch
|
|
52
|
+
for Node apps — is what gets created. That's fine for a repo that's just a
|
|
53
|
+
backup, but if the code isn't ready to be live, say so before running it, or
|
|
54
|
+
create and check out `dev` first. There is **no `dev` branch until you make
|
|
55
|
+
one**: `git push origin dev` on a fresh repo fails. Create it, then push:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
git checkout -b dev
|
|
59
|
+
git push -u origin dev
|
|
60
|
+
```
|
|
61
|
+
|
|
50
62
|
## 2. Push-to-deploy (for apps built with awesomate-app-builder)
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
Node apps from the app builder ship with a GitHub Actions workflow that
|
|
65
|
+
deploys on a push to `dev` / `staging` / `main` (dev → dev, main → prod).
|
|
66
|
+
Once the branches exist, explain it as *"save your work = it goes live"* —
|
|
67
|
+
don't lecture on branches.
|
|
68
|
+
|
|
69
|
+
**But you cannot finish the wiring yourself, and you should say so.** That
|
|
70
|
+
workflow needs `SSH_HOST`, `SSH_USER` and `SSH_PRIVATE_KEY` as repo secrets,
|
|
71
|
+
and **no client-reachable tool or route returns those values** — they're
|
|
72
|
+
admin-only. `github-setup.mjs --deploy-secrets` only copies them from your
|
|
73
|
+
environment, so with nothing there it prints `skip deploy secret …` and the
|
|
74
|
+
first deploy run goes red. So:
|
|
75
|
+
|
|
76
|
+
1. Set up the repo, the branches and the commits (§1) — all of that works.
|
|
77
|
+
2. Tell the user plainly: *"your code is backed up on GitHub; the automatic
|
|
78
|
+
deploy still needs Awesomate to connect it — I'll raise that for you."*
|
|
79
|
+
Raise it via the **awesomate-support** skill.
|
|
80
|
+
3. **Do not loop on the failing pipeline.** Re-running it, rewriting the
|
|
81
|
+
workflow, or pushing again won't produce the missing secrets.
|
|
82
|
+
|
|
83
|
+
Static sites have no deploy workflow at all — the template is just the page
|
|
84
|
+
files — so pushing does not publish them either; same handoff.
|
|
58
85
|
|
|
59
86
|
## 3. Everyday use (plain language)
|
|
60
87
|
|
|
61
88
|
- "Save my work" → stage, commit with a short message you write for them, push.
|
|
62
|
-
- "Put it live" → push to the right branch (dev/staging/main) and tell them the
|
|
89
|
+
- "Put it live" → push to the right branch (dev/staging/main) and tell them the
|
|
90
|
+
URL. If the branch doesn't exist yet, create it (`git checkout -b <name>`)
|
|
91
|
+
before pushing — only `main` exists after first-time setup.
|
|
63
92
|
- Always write clear commit messages **for** them; don't ask them to.
|
|
64
93
|
|
|
65
94
|
## 4. Be the version-control guardian (proactive, not reactive)
|
|
@@ -78,6 +107,13 @@ control — they should never have to think about it:
|
|
|
78
107
|
aren't backed up anywhere — want me to set that up? Takes a minute."*
|
|
79
108
|
`env_file_tracked` is urgent: untrack it, .gitignore it, and route the
|
|
80
109
|
secrets through awesomate-credentials.
|
|
110
|
+
**`last_deploy_failed` that never clears is usually the unwired deploy
|
|
111
|
+
secrets (§2), not a bug you can fix.** Check whether `SSH_HOST` /
|
|
112
|
+
`SSH_USER` / `SSH_PRIVATE_KEY` are set on the repo (`gh secret list`)
|
|
113
|
+
before touching anything: if they're missing, stop, tell the user the
|
|
114
|
+
deploy connection is pending with Awesomate, and raise it via the
|
|
115
|
+
awesomate-support skill. Don't retry the run, and don't start editing the
|
|
116
|
+
workflow file.
|
|
81
117
|
- **Auto-checkpoint.** After every meaningful working change (feature works,
|
|
82
118
|
bug fixed, content updated), commit with a plain-English message — don't
|
|
83
119
|
wait for "save my work", and never ask them to write a message. Push at
|
|
@@ -90,7 +126,12 @@ control — they should never have to think about it:
|
|
|
90
126
|
|
|
91
127
|
## Hard rules
|
|
92
128
|
- Never commit a secret or a `.env`. The script's secret guard is a backstop,
|
|
93
|
-
not a licence to skip checking.
|
|
129
|
+
not a licence to skip checking. The script's `.gitignore` list — `.env`,
|
|
130
|
+
`.env.local`, `.awesomate/`, `*.log`, `.DS_Store`, `node_modules/` — is only
|
|
131
|
+
applied when the script has been run in that project, so on a repo somebody
|
|
132
|
+
else set up, read `.gitignore` before committing rather than assuming.
|
|
133
|
+
`.awesomate/` matters especially: the credentials skill's file-drop fallback
|
|
134
|
+
puts a live secret there. If you spot a secret, route it through the
|
|
94
135
|
awesomate-credentials skill instead.
|
|
95
136
|
- Never ask the user for a GitHub token or password; the device-flow is the
|
|
96
137
|
only auth path.
|
|
@@ -50,7 +50,10 @@ if (run('gh', ['auth', 'status']).status !== 0) {
|
|
|
50
50
|
|
|
51
51
|
// --- 1. .gitignore excludes .env ------------------------------------------
|
|
52
52
|
const giPath = join(cwd, '.gitignore');
|
|
53
|
-
|
|
53
|
+
// .awesomate/ is the secret-drop inbox — the credentials skill tells users it is
|
|
54
|
+
// ignored, and the SECRET_RE guard only catches known key SHAPES, so a database
|
|
55
|
+
// URL or bare token in there would otherwise be committable.
|
|
56
|
+
const needed = ['.env', '.env.local', '.awesomate/', '*.log', '.DS_Store', 'node_modules/'];
|
|
54
57
|
let gi = existsSync(giPath) ? readFileSync(giPath, 'utf8') : '';
|
|
55
58
|
const have = new Set(gi.split(/\r?\n/).map((l) => l.trim()));
|
|
56
59
|
const toAdd = needed.filter((n) => !have.has(n));
|
|
@@ -20,11 +20,15 @@ description: >
|
|
|
20
20
|
|
|
21
21
|
You are helping the user run their **Awesomate-hosted WordPress** through the
|
|
22
22
|
**Awesomate Hosting MCP** (tools prefixed `awesomate_`). For WordPress work,
|
|
23
|
-
use the tools you have: `awesomate_run_wp_cli` for
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
use the tools you have: `awesomate_run_wp_cli` for the allowlisted verbs
|
|
24
|
+
(plugin/theme list, activate, install-by-slug, update, cache flush, `option
|
|
25
|
+
get`, the `list` reads — §0a has the full gate and its gaps);
|
|
26
|
+
`awesomate_wp_settings` for title/tagline/timezone and other core settings;
|
|
27
|
+
`awesomate_wp_post` for creating/updating posts and pages (drafts by
|
|
28
|
+
default); `awesomate_wp_media_import` for pulling media in by URL. For
|
|
29
|
+
anything beyond those — visual page-builder edits, theme design work, core
|
|
30
|
+
updates, user management — point the user at their WP admin (1-click SSO
|
|
31
|
+
link) rather than improvising.
|
|
28
32
|
|
|
29
33
|
## 0. First run — orient before acting
|
|
30
34
|
|
|
@@ -45,21 +49,45 @@ once (plus `awesomate_get_limits` before any create/change) and cache:
|
|
|
45
49
|
**hub.awesomate.ai/sites → Connect Claude Code** to refresh the token.
|
|
46
50
|
- **`skill.updateAvailable`** — covers all nine skills; the local files are
|
|
47
51
|
older than the MCP server. Mention it ONCE per session, with the what's-new
|
|
48
|
-
line the context includes, and offer to run `awesomate_skill_update`.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
line the context includes, and offer to run `awesomate_skill_update`. Its
|
|
53
|
+
response carries `restart.instruction` — the ONE step for THIS user's
|
|
54
|
+
surface, detected from the session itself (terminal / VS Code / desktop
|
|
55
|
+
app). Relay that line verbatim. Never read out a menu of surfaces: a
|
|
56
|
+
Windows desktop-app user told to "type `exit`" is being given a step that
|
|
57
|
+
does not exist for them. If the response includes `restart.note2` (the
|
|
58
|
+
surface could not be detected), ask the user how they run Claude Code
|
|
59
|
+
rather than guessing steps. Never raise the update mid-task, never nag
|
|
60
|
+
twice in a session. If `serverVersion` is still older than
|
|
61
|
+
`latestMcpVersion` after a restart, the npx cache is stale — the remedy is
|
|
53
62
|
`rm -rf ~/.npm/_npx`, then restart again.
|
|
54
63
|
- **`cpanel`** routing (host/user), present once hosting is provisioned.
|
|
55
64
|
|
|
56
65
|
If `awesomate_get_context` fails with a connectivity error, it's the user's
|
|
57
66
|
network or the API base — not an auth problem; say so.
|
|
58
67
|
|
|
68
|
+
### Hosting not set up yet (the most likely day-one state)
|
|
69
|
+
|
|
70
|
+
If `awesomate_get_context` returns **`provisioned: false`**, or the hosting
|
|
71
|
+
tools 404 with `"No hosting account"`, this account has a connection but no
|
|
72
|
+
hosting yet. Nothing else in this skill works until that changes, and
|
|
73
|
+
**there is no MCP tool that provisions hosting** — don't hunt for one, and
|
|
74
|
+
don't retry the 404.
|
|
75
|
+
|
|
76
|
+
Say it plainly and send them to the one place it happens: *"Your Awesomate
|
|
77
|
+
account isn't hosting a site yet. Set that up at hub.awesomate.ai/sites —
|
|
78
|
+
takes a couple of minutes — then come back and I can work on it."* Then
|
|
79
|
+
stop; offer the n8n / app-builder / SEO work that doesn't need hosting
|
|
80
|
+
instead of stalling on it.
|
|
81
|
+
|
|
82
|
+
Read `references/voice.md` before writing to the user — most people here
|
|
83
|
+
are business owners, not developers, and that file is the tone this skill
|
|
84
|
+
is written in.
|
|
85
|
+
|
|
59
86
|
References: `references/multi-account.md` (profiles, pins, resolution order,
|
|
60
87
|
wrong account) · `references/connect-troubleshooting.md` (bootstrap, sandbox/
|
|
61
88
|
proxy failures, resuming a connect, support report) ·
|
|
62
|
-
`references/rest-fallback.md` (no `awesomate_*` tools — serve over REST)
|
|
89
|
+
`references/rest-fallback.md` (no `awesomate_*` tools — serve over REST) ·
|
|
90
|
+
`references/voice.md` (how to talk to a non-technical owner).
|
|
63
91
|
|
|
64
92
|
## 0a. Tool map — reach for it when
|
|
65
93
|
|
|
@@ -69,6 +97,8 @@ proxy failures, resuming a connect, support report) ·
|
|
|
69
97
|
| `awesomate_get_context` | Session start — plan, capabilities, PAT expiry, `attention`, skill updates |
|
|
70
98
|
| `awesomate_get_limits` | Before any create/change — live plan limits + workflow/AI-editor credit balances |
|
|
71
99
|
| `awesomate_get_plan_features` | The live plan ladder, so upgrade talk is accurate |
|
|
100
|
+
| `awesomate_get_hosting_status` | Is hosting provisioned at all — eligible/provisioned flags, in-progress step, primary domain, DNS targets. Check before suggesting any site action |
|
|
101
|
+
| `awesomate_get_hosting_account` | cPanel account details: package, server, provisioned-at, masked username |
|
|
72
102
|
| `awesomate_list_sites` | What WordPress sites exist on this account |
|
|
73
103
|
| `awesomate_site_create` | Spin up a new WordPress site (check limits first) |
|
|
74
104
|
| `awesomate_list_domains` | What domains are attached, and to which site |
|
|
@@ -79,11 +109,12 @@ proxy failures, resuming a connect, support report) ·
|
|
|
79
109
|
| `awesomate_list_snapshots` | What restore points a site has |
|
|
80
110
|
| `awesomate_rollback_site` | Restore a snapshot after something went wrong (confirm first) |
|
|
81
111
|
| `awesomate_site_staging_create` / `_promote` / `_discard` | Private full copy on awesomate.dev to review changes; publish or throw away (§5a) |
|
|
82
|
-
| `awesomate_run_wp_cli` |
|
|
112
|
+
| `awesomate_run_wp_cli` | The 10 allowlisted WP-CLI verbs only (see below) — plugin/theme list, activate, install-by-slug, update; `cache flush`; `option get`; `post`/`media`/`menu`/`comment`/`user list` |
|
|
113
|
+
| `awesomate_wp_settings` | Site title, tagline, timezone, date/time format, posts-per-page, search-engine visibility — THE path for any multi-word value, and it flushes the cache (Support Plus+) |
|
|
83
114
|
| `awesomate_wp_post` | Create/update/read a WP post or page — drafts by default (writes are Support Plus+) |
|
|
84
115
|
| `awesomate_wp_media_import` | Pull an image/file into the WP media library from an https URL (Support Plus+) |
|
|
85
116
|
| `awesomate_uninstall_site` | Remove a WordPress install (destructive — confirm explicitly) |
|
|
86
|
-
| `awesomate_privacy_settings` | Read which privacy/consent toggles are on — explain a 403 `consent_required` precisely (the user flips toggles themselves at hub.awesomate.ai/settings
|
|
117
|
+
| `awesomate_privacy_settings` | Read which privacy/consent toggles are on — explain a 403 `consent_required` precisely (the user flips toggles themselves under n8n → Settings → Privacy at hub.awesomate.ai/n8n/settings) |
|
|
87
118
|
| `awesomate_notifications` | The hub notification bell — `list` unread (quota warnings, quote ready, support-access events), `read`/`read_all` to clear |
|
|
88
119
|
| `awesomate_dashboard_metrics` | Account-wide numbers: executions by status, error rate, time saved, chat sessions, 7-day trend |
|
|
89
120
|
| `awesomate_account_report` | A monthly-report-shaped read: working / not working / engagement / commercials |
|
|
@@ -91,6 +122,36 @@ proxy failures, resuming a connect, support report) ·
|
|
|
91
122
|
| `awesomate_support` | Raise a support ticket / reach a human |
|
|
92
123
|
| `awesomate_request_build` | Request a done-for-you build (spends a credit — confirm first) |
|
|
93
124
|
|
|
125
|
+
### What WP-CLI CANNOT do from here
|
|
126
|
+
|
|
127
|
+
`awesomate_run_wp_cli` is not a WP-CLI passthrough. Ten verbs are allowed,
|
|
128
|
+
each with its own predicate; everything else returns **400
|
|
129
|
+
`wp_cli_not_allowed`**. Know the gaps before you promise anything:
|
|
130
|
+
|
|
131
|
+
- **`user` allows `list` only.** No password reset, no adding or removing
|
|
132
|
+
users, no changing the admin email, no role changes. A locked-out user
|
|
133
|
+
goes through the 1-click WP-admin SSO link or cPanel, not through you.
|
|
134
|
+
- **`core` allows `version` and `check-update` only.** **There is no way to
|
|
135
|
+
update WordPress core from Claude.** You can tell them an update is
|
|
136
|
+
waiting; they apply it in wp-admin. (Plugins and themes DO have `update`.)
|
|
137
|
+
- **No `search-replace`, no `db` anything, no `plugin delete` /
|
|
138
|
+
`theme delete`, no `option delete`.** Changing a site's URL, resetting or
|
|
139
|
+
dumping the database, and removing a plugin outright all happen in
|
|
140
|
+
wp-admin, over SSH (`scripts/ssh-connect.sh`, Support Plus+), or via the
|
|
141
|
+
hub — never as a tool call.
|
|
142
|
+
- **`option update` is a 10-option allowlist** (blogname, blogdescription,
|
|
143
|
+
timezone_string, date_format, time_format, start_of_week, posts_per_page,
|
|
144
|
+
blog_public, default_comment_status, default_ping_status) — and use
|
|
145
|
+
`awesomate_wp_settings` for those anyway.
|
|
146
|
+
- **Arguments cannot contain spaces** (letters, digits and `-_./=:@+,`
|
|
147
|
+
only). The remote shell re-parses them, so the gate refuses anything
|
|
148
|
+
quoted. Any multi-word value — a business name, a tagline, post content —
|
|
149
|
+
is impossible here: `awesomate_wp_settings` or `awesomate_wp_post`.
|
|
150
|
+
- **Installs take wp.org slugs only** — never a URL or a zip.
|
|
151
|
+
|
|
152
|
+
A 400 is a policy answer, not a transport hiccup: don't rephrase and retry.
|
|
153
|
+
(A 502 `wp_cli_unavailable` IS transient — that one you can retry.)
|
|
154
|
+
|
|
94
155
|
## 1. The plan model (so your nudges are accurate)
|
|
95
156
|
|
|
96
157
|
| Plan | WP sites | Hosted apps | Custom domains | Shell / Claude Code | Notes |
|
|
@@ -121,6 +182,19 @@ Never attempt SSH, WP-CLI, snapshot/rollback, staging, deploy, multi-site —
|
|
|
121
182
|
those tools will 403. Instead, surface the specific limit and what
|
|
122
183
|
Support Plus/Pro unlocks (§4), and link the hub billing page.
|
|
123
184
|
|
|
185
|
+
**The plan table's "1 site / 1 custom domain" is not a Claude allowance.**
|
|
186
|
+
On Essentials, a PAT is read-and-advise: `awesomate_site_create`,
|
|
187
|
+
`awesomate_domain_add` and every WordPress write (`awesomate_wp_post`,
|
|
188
|
+
`awesomate_wp_media_import`, `awesomate_wp_settings`,
|
|
189
|
+
`awesomate_run_wp_cli`) return **403 `upgrade_required`** — the server
|
|
190
|
+
enforces it, so no phrasing gets past it. That site and that domain are
|
|
191
|
+
real; they are created and changed **in the hub UI at
|
|
192
|
+
hub.awesomate.ai/sites**, by the user, with deliberate clicks. Say exactly
|
|
193
|
+
that rather than letting them discover it as a failure: *"Your plan lets me
|
|
194
|
+
read and advise on your hosting. Creating the site itself is a couple of
|
|
195
|
+
clicks at hub.awesomate.ai/sites — I'll walk you through it — or Support
|
|
196
|
+
Plus lets me do it from here."*
|
|
197
|
+
|
|
124
198
|
### Support Plus and above (shell) — full workflow
|
|
125
199
|
|
|
126
200
|
You additionally have: jailed SSH to the client's own cPanel account, WP-CLI
|
|
@@ -137,9 +211,13 @@ at it. Their dev copy is invisible to Google and AI crawlers by policy.
|
|
|
137
211
|
|
|
138
212
|
## 3. Safety rules (non-negotiable)
|
|
139
213
|
|
|
140
|
-
- **Before ANY change to a live site** — plugin/theme
|
|
141
|
-
|
|
142
|
-
`snapshotId`. If it goes wrong,
|
|
214
|
+
- **Before ANY change to a live site** — a plugin/theme update, a settings
|
|
215
|
+
change, a content write, a deploy — call **`awesomate_snapshot_site`**
|
|
216
|
+
first and tell the user the `snapshotId`. If it goes wrong,
|
|
217
|
+
`awesomate_rollback_site` restores files + DB. Snapshot first too when the
|
|
218
|
+
USER is about to do something heavy themselves in wp-admin or over SSH (a
|
|
219
|
+
URL change / `search-replace`, a core update, a database import): you
|
|
220
|
+
can't run those, but you can hand them a restore point before they start.
|
|
143
221
|
- **WP content writes are snapshot-first and drafts-first.** Before the FIRST
|
|
144
222
|
content write of a session on a live site (an `awesomate_wp_post` write, a
|
|
145
223
|
content-touching WP-CLI command), take one `awesomate_snapshot_site`.
|
|
@@ -148,12 +226,38 @@ at it. Their dev copy is invisible to Google and AI crawlers by policy.
|
|
|
148
226
|
to publish.
|
|
149
227
|
- **Confirm before destructive actions** — `awesomate_rollback_site`,
|
|
150
228
|
`awesomate_site_staging_promote` (replaces live), `_site_staging_discard`
|
|
151
|
-
(loses unpublished staging work),
|
|
152
|
-
|
|
229
|
+
(loses unpublished staging work), deleting content. State exactly what
|
|
230
|
+
will be lost and wait for an explicit "yes". The same care applies when
|
|
231
|
+
you're TALKING someone through a destructive step you cannot run for them
|
|
232
|
+
(dropping tables, `wp db reset`, deleting a plugin) — snapshot first, spell
|
|
233
|
+
out what it destroys, and let them run it.
|
|
153
234
|
- **Site deletion has no MCP tool.** The user deletes sites themselves at
|
|
154
235
|
**hub.awesomate.ai** — deep-link them there; never script around it.
|
|
155
236
|
- Prefer building/testing in **WordPress Studio locally**, then deploy (§5).
|
|
156
|
-
-
|
|
237
|
+
- Read before you write: `option get`, `plugin list`, `theme list` cost
|
|
238
|
+
nothing and tell you what the current state actually is.
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
### Changing site title, tagline and other WordPress settings
|
|
242
|
+
|
|
243
|
+
Use **`awesomate_wp_settings`** (domain + any of: title, tagline, timezone,
|
|
244
|
+
dateFormat, timeFormat, postsPerPage, searchEngineVisible). It flushes the
|
|
245
|
+
object cache for you, so the change actually shows on the live site.
|
|
246
|
+
|
|
247
|
+
**Do not reach for `awesomate_run_wp_cli` for these.** Its arguments cannot
|
|
248
|
+
contain spaces — the transport re-parses them on the remote shell, so the
|
|
249
|
+
charset gate refuses anything with a space. `option update blogname "Care
|
|
250
|
+
Connect AI"` will always be rejected there, and a business name is multi-word
|
|
251
|
+
by definition. Same rule for post and page content: that is `awesomate_wp_post`.
|
|
252
|
+
|
|
253
|
+
`awesomate_run_wp_cli` remains right for space-free operations: plugin/theme
|
|
254
|
+
list, activate, install by slug, `option get`, `cache flush`, listing posts,
|
|
255
|
+
media, users and comments.
|
|
256
|
+
|
|
257
|
+
Snapshot before the session's first change to a live site
|
|
258
|
+
(`awesomate_snapshot_site`), and tell the user the snapshot id so they know
|
|
259
|
+
rollback exists. `searchEngineVisible: false` de-indexes the site — always
|
|
260
|
+
confirm that one explicitly before setting it.
|
|
157
261
|
|
|
158
262
|
## 4. Limits & upgrade etiquette
|
|
159
263
|
|
|
@@ -198,7 +302,14 @@ AI crawlers — anyone with the link can view, perfect for client review).
|
|
|
198
302
|
|
|
199
303
|
- `awesomate_site_staging_create <live domain>` — clones files + DB, rewrites
|
|
200
304
|
URLs. One staging copy per site (409 `staging_exists` → promote or discard
|
|
201
|
-
first). Takes a few minutes on large sites.
|
|
305
|
+
first). Takes a few minutes on large sites. On an account whose primary
|
|
306
|
+
site this is, the copy lands at `staging.{slug}.awesomate.dev`; a second
|
|
307
|
+
site keeps its own first label.
|
|
308
|
+
- **A 409 `no_dev_domain` is not your mistake.** Some accounts have no
|
|
309
|
+
awesomate.dev address on file yet, and staging needs one. The message says
|
|
310
|
+
so: relay it and offer to raise it with support (`awesomate_support`) —
|
|
311
|
+
there is no tool that adds the dev address, so don't retry or improvise a
|
|
312
|
+
staging copy on a live domain.
|
|
202
313
|
- Make the changes ON the staging domain (WP-CLI / wp-admin / deploy.sh with
|
|
203
314
|
`--domain <staging domain>`), send the user the staging URL to review.
|
|
204
315
|
- `awesomate_site_staging_promote <live domain>` — publishes staging over live.
|
|
@@ -45,7 +45,7 @@ doubt: outcome first, cost before spend, one question at a time.
|
|
|
45
45
|
9. **Confirm names and anything hard to undo before acting.** App names
|
|
46
46
|
become web addresses; deletes are forever.
|
|
47
47
|
Bad: "Created app xk9-test-2."
|
|
48
|
-
Good: "I'll call it 'bookings' — that becomes bookings.acme.awesomate.
|
|
48
|
+
Good: "I'll call it 'bookings' — that becomes bookings.acme.awesomate.app.
|
|
49
49
|
OK?"
|
|
50
50
|
|
|
51
51
|
10. **When something fails, say what you're doing about it.** Never paste a
|
|
@@ -30,10 +30,17 @@ platform's answer beats anything you remember.
|
|
|
30
30
|
- `upgrade_required: true` → relay the included upsell copy + billing
|
|
31
31
|
link once, honestly, then help within what reads allow. Never retry
|
|
32
32
|
into the gate.
|
|
33
|
-
- `consent.knowledge_platform_enabled: false` → the user must
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
- `consent.knowledge_platform_enabled: false` → the user must turn it on
|
|
34
|
+
themselves: hub.awesomate.ai/n8n/settings, under the heading
|
|
35
|
+
**"Knowledge Base"**, the toggle **"Send My Content to the Knowledge
|
|
36
|
+
Platform"**. Name it exactly like that — one heading and one switch, so
|
|
37
|
+
they can find it without hunting. You cannot flip it for them, and
|
|
38
|
+
there is no tool that can. If you're unsure which toggle is blocking
|
|
39
|
+
(or a knowledge call 403s), call `awesomate_privacy_settings` — it
|
|
40
|
+
reads which consents are on or off and names the one that's stopping
|
|
41
|
+
you. Explain what it consents to (their selected content is indexed in
|
|
42
|
+
Sydney, kept isolated to their account, deletable any time; turning it
|
|
43
|
+
off suspends the Knowledge Base immediately), wait, re-check.
|
|
37
44
|
- `tenant: null` or `status: 'provisioning'` → not enabled yet /
|
|
38
45
|
still building; `usage` → month-to-date vs `usage.included` quota.
|
|
39
46
|
3. Only then design: what content exists, what's already ingested, what the
|
|
@@ -64,10 +71,18 @@ Local FILES (PDFs, videos on disk) cannot travel through these tools — send
|
|
|
64
71
|
the user to the hub's Knowledge → Sources upload page (100 MB per file;
|
|
65
72
|
bigger media by URL). Formats + caps: [ingestion-sources.md](references/ingestion-sources.md).
|
|
66
73
|
|
|
74
|
+
**`awesomate_knowledge_upload {path, title?}`** — ingest ONE file from the
|
|
75
|
+
user's own computer. Pass a local path; the server streams it from disk, so
|
|
76
|
+
file contents never pass through the conversation. 100 MB max, one call per
|
|
77
|
+
file, explicit approval first (it spends allowance). URLs and sitemaps stay on
|
|
78
|
+
`awesomate_knowledge_sources`.
|
|
79
|
+
|
|
67
80
|
## 2. References — read on demand
|
|
68
81
|
|
|
69
82
|
| When | Read |
|
|
70
83
|
|---|---|
|
|
84
|
+
| **"Train this on my files and put a chat on my site"** — the full path | [from-your-files.md](references/from-your-files.md) |
|
|
85
|
+
| Showing a cited image or video (and why a built page breaks) | [showing-media.md](references/showing-media.md) |
|
|
71
86
|
| Choosing/adding sources, estimating ingest cost & time | [ingestion-sources.md](references/ingestion-sources.md) |
|
|
72
87
|
| Explaining citations, refusals, "verified" semantics | [citations-and-grounding.md](references/citations-and-grounding.md) |
|
|
73
88
|
| Wiring the knowledge base into n8n agents | [n8n-connection.md](references/n8n-connection.md) |
|
|
@@ -110,6 +125,10 @@ enough to route through explicit REST calls the user has just approved.
|
|
|
110
125
|
| Action | Endpoint |
|
|
111
126
|
|---|---|
|
|
112
127
|
| Status / provision / sources / jobs / agent / ask | `GET\|POST /api/knowledge/{status,provision,sources,jobs,agent,chat}` (tool equivalents) |
|
|
128
|
+
| Faceted search (what `awesomate_knowledge_search` calls) | `GET /api/knowledge/explore?q=…` + the same facet params. **Add `&include=media` to get `url`/`poster_url` on image/video hits** — without it you get titles with nothing to display. |
|
|
129
|
+
| Business-data warehouse (what `awesomate_knowledge_data` calls) | `GET /api/knowledge/data/{metrics,datasets,datasets/:id,imports,imports/:id}` · `PATCH /api/knowledge/data/datasets/:id` · `POST /api/knowledge/data/imports/:id/:action` · `POST /api/knowledge/data/query` (read-only SQL) |
|
|
130
|
+
| Agent builder (what `awesomate_knowledge_agents` calls) | `GET\|POST /api/knowledge/agents` · `GET\|PATCH\|DELETE /api/knowledge/agents/:agent_id` · `POST /api/knowledge/agents/:agent_id/{publish,suspend,resume}` |
|
|
131
|
+
| **Test a DRAFT agent** (`action:'test'`) | `POST /api/knowledge/agents/:agent_id/chat` `{message, session_id?}`. There is **no** `/test` endpoint — guessing one returns 404. |
|
|
113
132
|
| Entity layer probe (`available` false = not enabled yet, stop) | `GET /api/knowledge/entities` |
|
|
114
133
|
| People list / detail | `GET /api/knowledge/people?status=named\|unknown\|hidden\|all` · `GET /api/knowledge/people/:id` |
|
|
115
134
|
| Name or hide/unhide a person (after approval) | `PATCH /api/knowledge/people/:id` `{display_name}` or `{status: "hidden"\|"unknown"}` |
|
|
@@ -122,6 +141,20 @@ enough to route through explicit REST calls the user has just approved.
|
|
|
122
141
|
| Delete the WHOLE knowledge base | hub UI only (owner types the account slug) — never via PAT |
|
|
123
142
|
| Fleet/admin views (Awesomate team) | `/api/fleet/knowledge/*` — admin JWT, not a client PAT |
|
|
124
143
|
|
|
144
|
+
|
|
145
|
+
**The two chat endpoints take OPPOSITE field names, and both reject unknown keys.**
|
|
146
|
+
Learning one shape and applying it to the other is a guaranteed `400`:
|
|
147
|
+
|
|
148
|
+
| Endpoint | Body |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `POST /api/knowledge/chat` — ask the knowledge base | `{question, session?, filters?}` |
|
|
151
|
+
| `POST /api/knowledge/agents/:id/chat` — test a draft agent | `{message, session_id?, filters?}` |
|
|
152
|
+
|
|
153
|
+
`question` vs `message`, `session` vs `session_id`. Both are strict objects, so
|
|
154
|
+
sending both spellings to be safe fails too. Measured on a real first-time
|
|
155
|
+
session (2026-09-01): fourteen `400`s and one `404` were spent rediscovering
|
|
156
|
+
exactly this.
|
|
157
|
+
|
|
125
158
|
## 5. Hard rules
|
|
126
159
|
|
|
127
160
|
- **Never ask for, paste, or echo an API key** — not the platform key, not
|