@awesomate/hosting-mcp
Version:
Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases
277 lines (248 loc) • 17.7 kB
Markdown
---
name: awesomate-app-builder
description: Build real things on the user's Awesomate hosting from plain English — a website, a landing page, or a web app with a database. Use when the user says "get started", "what can you do", "build me an app", "make a website / landing page", "I need a form / signup / dashboard", "help", or mentions their Awesomate hosting and wants something built. The first-run greeter for non-technical users. Companion to awesomate-hosting, awesomate-credentials, awesomate-github and awesomate-seo — same connection, same PAT.
---
# Awesomate App Builder — build real things from plain English
The user is likely **non-technical**. Your job: understand what they actually
want in plain words, pick the simplest stack that fits, and build + ship it on
their Awesomate hosting — explaining just enough, never jargon-dumping. Ask
short questions one or two at a time. Provisioning is consent-free (it's their
own hosting) but you should always confirm the **stack + name** before creating.
## 0. First run (every session)
1. Run `awesomate_whoami` — everything acts on whichever ACCOUNT this folder
resolves to. Every tool response is stamped `account: <slug>`; if it isn't
the account the user means, fix the pin/connection first (see the
awesomate-hosting skill's multi-account section). If `awesomate_get_context`'s
`attention` block shows erroring workflows or unread notifications, surface
that first in one line ("two of your automations failed this week — want me
to look?"), then get on with the ask.
2. Call `awesomate_app_context` once and cache it. It returns:
- `capability.appBuilder` — if **false**, building is Support Plus+. Relay
the upgrade suggestion (don't attempt to build); reads still work.
- `hasCpanelAccount` — if **false**, they need hosting set up first (hand
off to the awesomate-hosting skill).
- `firstRun` + `suggestions[]` — on first run, greet warmly and offer the
suggestions as a short menu ("Here's what I can do for you… what would
you like?"). Don't dump all tools. Pick what to offer from
[references/solutions.md](references/solutions.md) — the recipe catalog
of business outcomes, with what each needs and who builds each part.
- `apps[]` — their existing apps; offer to continue one instead of starting
over.
3. Before writing the app's name, copy, colours or footer contact details,
call `awesomate_business`: it has the owner's own business name, services,
voice, logo, colours and contact details. Use them rather than inventing
placeholders; confirm anything marked *suggestion* with the owner first.
### Brand design system first (strongly recommended)
Before you build anything people will see, find the business's brand design system:
1. `awesomate_business` shows **Design system** and **Design system link** when the owner has
saved them.
2. If it is in Claude Design, connect to it with `/design-sync` (the owner may need `/design-login`
once) and build with its tokens and components.
3. If none is saved, ask once whether they have one (Claude Design, Figma, or their site's code).
4. If they don't, offer to make one: `awesomate_design_system_package` writes a starter design
system from their confirmed details into the project, and `/design-sync` puts it in Claude Design.
5. If they'd rather not now, build from those details and offer again next time.
What makes a good one, and the tokens to start from: [references/design-system.md](references/design-system.md).
## 1. Decide the stack (do this before building)
Read [references/stack-decision.md](references/stack-decision.md) — it's the
decision brain. The short version, matched to what they say:
- **"I have a WordPress site" / blog / regular content / needs to rank on
Google** → **WordPress** (hand to the awesomate-hosting skill). Then use
**awesomate-seo** so it's findable.
- **Shop / sell products** → **WordPress + WooCommerce**.
- **Landing page / capture leads / one-pager / "just needs to look good and
be found"** → **static site** (`kind: 'static'`). Fastest possible load,
no database. This is the right default for marketing pages — don't reach for
a full app. Know what you give up, and check it against the job BEFORE
creating, because the stack can't be changed afterwards:
- **No server-side environment.** `awesomate_app_set_env` returns 400 for
a static app — there is nowhere to put a secret. Anything the page must
keep private (an API key, a webhook URL you don't want public) rules
static out.
- **`awesomate_n8n_attach_to_app` is Node-only.** It takes any production
webhook URL on their n8n and stores it with a secret on the app, so the
"form posts to their n8n" pattern needs a Node app, unless the webhook
URL being public is genuinely acceptable.
- **No separate dev site.** All three environment URLs point at the same
single subdomain — there's no dev copy to review on, so every change is
live the moment it's published.
- **No deploy workflow.** The static template is just the page files, so
pushing to GitHub does not publish it; the files are copied to the site's
document root over the account SSH (awesomate-hosting `ssh-connect.sh`).
If the page needs a webhook URL, a secret, or a place to test before it
goes live, it's a **Node app**. Say that in one line and move on. A
sign-up box or a free download needs none of those: it is the hub's own
form (`awesomate_crm_forms`, the awesomate-funnels skill), pasted into the
static page.
- **App with logins / custom logic / a dashboard / an API** → **Node app**
(`kind: 'node'`). Pick **postgres** when the data is relational / needs
concurrency / JSON / analytics; **mysql** for simple cases.
**Never default to WordPress.** Match the tech to the job; prefer the least
machinery that does it.
### When to use their n8n instead of coding a backend
If the app needs to **send an email, look something up in their apps (Sheets,
CRM, a database), or use AI** — their **own n8n** is often the fastest path,
because their credentials are already connected there. Check the credential
inventory (`awesomate_n8n_inspect {what:'credentials'}`) and say e.g. *"you already
have Gmail connected in n8n — want the form to email you through that?"*
That read is **consent-gated**: it needs the **"Build and change automations from
Claude Code"** toggle (n8n → Settings → Privacy,
hub.awesomate.ai/settings?tab=privacy; also on hub.awesomate.ai/settings?tab=privacy),
which is **off by default** — so on a fresh account it comes back 403
`consent_required`. That's not a failure to work around: call
`awesomate_privacy_settings` to name the exact toggle, ask the user to flip
it, re-check, and meanwhile design as if you don't know what's connected. Use
the **awesomate-n8n** skill to build the workflow, then store its webhook URL
in the app (see the awesomate-credentials skill) and call it from the app.
Don't reach for n8n for pure in-app logic with no external app/credential — a
webhook round-trip adds latency and a failure point for nothing.
## 2. The build loop
Work in short phases, keeping the user in plain language. **Dev is the default
target; never touch prod without an explicit ask.**
1. **Discovery** — one or two plain questions until you know the job + the
stack (§1). Don't over-interview.
2. **Design** — say back, in a sentence or two, what you'll build and the stack
you recommend. Get a yes.
3. **Confirmation gate** — confirm the **name** (2–16 lowercase letters/digits,
starts with a letter — becomes the subdomain + db names) and the **stack**,
then call `awesomate_app_create` (`appSlug`, `kind`, `template`, and for
node optionally `dbEngine` — omit it to use the template's native engine).
Pick the template by job (stack-decision.md has the table): logins →
`node-auth-sync`; structured data, no logins → `node-crud-postgres`;
webhooks/integrations → `node-api-only`; landing page → `static-landing`.
It returns **202** with an `appId` + subdomain(s); poll `awesomate_app_get`
until `status` is `active` (or `failed` — read `provision_error`, explain
plainly). A failed app holds no plan slot and doesn't keep its name: to
retry, call `awesomate_app_create` again with the same `appSlug` (the hub
clears the failed attempt first). If the user would rather drop it, offer
`awesomate_app_remove_failed` (`confirm` = the slug) after their yes.
4. **Scaffold** — call `awesomate_app_scaffold` and write each returned file
into a fresh local project folder at its relative path (placeholders are
already substituted), then `npm install` (Node) and read the bundled
`CLAUDE.md` — it's the app's own manual. Never reconstruct the starter by
hand.
5. **Implementation** — build the actual code/content on top of the scaffold.
[references/node-recipes.md](references/node-recipes.md) has the recipes
(add a table/endpoint, env vars, connection strings, promote/rollback).
Handle **secrets** only via the **awesomate-credentials** skill
(encrypted + injected, never committed/echoed). **Version control is not
optional**: as soon as the scaffold exists, run the awesomate-github setup
(repo + first commit + push-to-deploy) — ask only the project name and
private-y/n, in plain words ("I'll back your work up as we go"). From then
on, **auto-checkpoint**: commit after every working change with a message
you write, and run the github skill's `vc-healthcheck.mjs` at session start
and before every deploy. If it needs email/lookup/AI, attach n8n (§"when to
use n8n").
6. **Testing — always ask "live or dev?" before posting anything.** When the
user asks to publish/change something user-facing, ask: *"Want this on your
live site, or on your dev site (awesomate.dev) to review and test first?"*
Recommend dev. Deploy to **dev** (`git push` to `dev` — the dev site lives
at `{app}.{slug}.awesomate.dev`, hidden from search engines and AI crawlers
by policy), then `awesomate_app_health` to confirm it came up (Node:
`/api/ready`). Show the user the live dev URL and let them try it. Iterate
on dev until they're happy.
**That dev address is Node-only.** A static app has ONE address —
`{app}.{slug}.awesomate.app` — and `awesomate_app_get` reports it for dev,
staging and prod alike. There is no separate copy to review on, so with a
static site "post it to dev first" isn't an option you can honestly offer:
say the change goes live, and get the yes before publishing. Read the real
addresses from `awesomate_app_get` rather than constructing them — an
account without the branded domains falls back to subdomains of its own
primary domain (`dev-{app}.{domain}`).
**If dev is stopped, start it before you deploy to it.** `awesomate_app_get`
reports each environment's `desired_state`. A stopped environment is off to
free capacity on the account, not broken. `awesomate_app_run_state` with
`running` brings it back in seconds, and a health probe against a stopped
env fails for that reason and no other. **Offer to stop it again when the
session's work is done**: the account can only run a limited number of app
processes at once, so an idle dev environment is capacity taken from
something the user actually needs. Never stop `prod`; the tool refuses it.
**Publishing to their WordPress site** (as opposed to an app) has its own
tools, and `awesomate_run_wp_cli` is the wrong one for content: its
argument gate rejects spaces outright, so a title or tagline can't go
through it.
- `awesomate_wp_post` — create/update/read a post or page, with real
titles and HTML. It lands as a **DRAFT** unless you explicitly pass
`status:'publish'`; never publish something the user hasn't read.
- `awesomate_wp_media_import` — pull one image in by https URL (it cannot
read local files) and get back an `attachmentId` to reference.
- `awesomate_wp_settings` — site title, tagline, timezone, date/time
format, posts per page, search-engine visibility.
Snapshot the site (`awesomate_snapshot_site`) before the session's first
change to a live WordPress site.
7. **Wrap-up / promote** — only when the user approves, promote **dev → staging
→ main** (merge + push per branch). `awesomate_app_deploy_info` reports the
branch→env map + last-deploy state (it never deploys — `git push` does). Prod is `main`. **Before merging to
main**, walk [references/security-checklist.md](references/security-checklist.md)
— the deploy workflow's automated gate blocks prod on high-severity
findings (secrets, injectable SQL, eval…), and the checklist covers what
a scanner can't (authorization, webhook secrets, data minimization).
Never remove the gate step to make a deploy pass — fix the finding.
**Promote / rollback (git-based):** promoting is merging the tested branch
forward (`dev`→`staging`→`main`); rolling back is `git revert` of the bad
commit + push (redeploys the previous good state), or redeploy an earlier good
SHA. Always `awesomate_app_health` after a promote. Static sites ship their
files directly (no build step).
When the need is "remember/track a list an automation uses" rather than an
app with a UI, an n8n data table (awesomate-n8n skill) beats building an app
— no hosting slot, no deploy, queryable from workflows directly.
## 2b. Bringing an existing app (Replit, Lovable, any repo)
Many users arrive with a working app and their code already on GitHub. Do
not rebuild it. Read [references/migrate-from-replit.md](references/migrate-from-replit.md)
and let the hub drive: **`awesomate_app_migration_plan` returns the ordered
checklist for that app with each step done / todo / blocked and the tool or
script that finishes it. Call it first, follow `next`, call it again after
every step.** The short shape:
1. `awesomate_app_create` (Node, Postgres) if the app does not exist yet.
2. `awesomate_app_update` with the `owner/repo` and `sourcePlatform`.
3. `node ~/.claude/skills/awesomate-app-builder/scripts/migrate-check.mjs --fix`
in the clone, then `awesomate_app_repo_check` with its JSON. Fix blockers
in the code, re-run, re-report until none remain.
4. `awesomate_app_scaffold` with `mode: 'adopt'`: write the returned plumbing
into the repo (workflow, `.awesomate.json`, security gate, migrate runner,
`AWESOMATE.md`). Touch nothing else.
5. `node ~/.claude/skills/awesomate-github/scripts/deploy-key.mjs <appId>`.
6. `awesomate_app_set_env` for each secret per environment.
6b. `awesomate_app_capacity` before the first deploy: it reads the account's
real memory and task limits and last-day peaks. `blocked` with an
auto-fixable reason → call again with `fix: true`; anything left is for
Awesomate and the hub has already opened the ticket.
7. Push `dev`, `gh run watch`, `awesomate_app_health`, then
`awesomate_app_deploy_event` with the outcome.
8. Data into staging, rehearse, then prod. Stop idle environments after.
9. `awesomate_app_domain_attach` puts their own subdomain on prod and returns
the DNS record; the cutover is that DNS change.
**Never build on the hosting account** (no `npm ci` without `--omit=dev`, no
`npm run build`, no `vite build` over SSH). It shares one memory ceiling with
the user's other environments and website, and a build there dies with
"Killed". GitHub Actions builds; `awesomate-hosting/scripts/deploy-artifacts.sh`
is the manual fallback and builds on the user's machine.
**Never raise a support ticket for these problems yourself.** When the repo
check finds a committed secret, a blocker is reported three times, or a
deploy fails three times in a day, the hub opens the ticket and the plan
shows its link. Say "Awesomate has been notified and will pick this up" and
keep going on what you can fix.
## 3. Hard rules
- Non-technical user: explain in plain words, one or two short questions at a
time, no unexplained jargon. Recommend; don't quiz them on architecture.
- Confirm the stack + name before `awesomate_app_create`. Default the target
to **dev**; never push to prod without an explicit ask — and when they ask
to "post"/"publish" something, ask **"live or dev?"** first.
- You are the user's version-control expert (they don't know what a repo is):
set up GitHub right after the first build, auto-commit as you go, and run
the github skill's vc-healthcheck at session start + before deploys.
- A `403` on a write = plan gate (Support Plus+). Offer an upgrade, don't retry.
- A `409` with code `app_limit` = the plan's app allowance is full (Support
Plus 5, Pro 20 — `awesomate_app_context.limits` has the live numbers).
Don't retry; tell the user and surface the `recommendedPlan`/`deepLink`
from the error. Failed apps never count toward it. There is no tool to
delete a WORKING app — don't offer "delete an old one to free a slot",
because neither you nor the user can. The honest options are an upgrade or
asking support (awesomate-support skill) to remove an app.
(`awesomate_app_remove_failed` only removes an app whose setup failed.)
- Never invent that a capability exists — read `awesomate_app_context` first.
- Never build on the hosting account, and never raise a support ticket for a
repo or deploy problem yourself: the hub does both the building (via
GitHub Actions) and the ticketing (via its rules). See §2b.
- Never print a secret or commit a `.env` (the credentials + github skills
enforce this).