@awesomate/hosting-mcp 0.20.5 → 0.20.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -41877,6 +41877,26 @@ server.registerTool(
41877
41877
  }
41878
41878
  }
41879
41879
  );
41880
+ server.registerTool(
41881
+ "awesomate_site_audit",
41882
+ {
41883
+ description: "Run the SEO + AEO build gates against ONE live page the user owns, fetched AS GPTBot. Returns pass/fail per gate with specific fixes: is the content in the raw HTML at all (a React/Vue site is invisible to ChatGPT, Claude and Perplexity \u2014 only Gemini and Applebot run JavaScript), can the four retrieval bots reach it, is there an accidental noindex/nosnippet, does the canonical point at THIS domain (a leftover pointing at a Replit/Vercel/staging host silently de-indexes the real site), is the structured data valid AND mirrored in visible text, is the content structured so a single section survives being quoted, robots.txt + sitemap, and time-to-first-byte. Run it after building or changing any public page, and before telling the user their site is discoverable \u2014 reads on every plan. Two gates are reported as `skipped` because they need a headless browser or a full crawl; treat skipped as unknown, never as passing.",
41884
+ inputSchema: {
41885
+ domain: external_exports.string().min(3).max(253).describe("a domain on the user's own hosting account"),
41886
+ path: external_exports.string().max(400).optional().describe("page path to audit, default /")
41887
+ },
41888
+ annotations: READ_ONLY
41889
+ },
41890
+ async ({ domain, path }) => {
41891
+ try {
41892
+ const dom = encodeURIComponent(domain.toLowerCase());
41893
+ const q = path && path !== "/" ? `?path=${encodeURIComponent(path)}` : "";
41894
+ return textResult(await hubGet(requireConfig(), `/api/client-hosting/sites/${dom}/audit${q}`));
41895
+ } catch (err) {
41896
+ return errorResult(err);
41897
+ }
41898
+ }
41899
+ );
41880
41900
  server.registerTool(
41881
41901
  "awesomate_wp_media_import",
41882
41902
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomate/hosting-mcp",
3
- "version": "0.20.5",
3
+ "version": "0.20.6",
4
4
  "description": "Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -1,5 +1,12 @@
1
1
  {
2
2
  "versions": [
3
+ {
4
+ "version": "0.20.6",
5
+ "highlights": [
6
+ "Ask Claude to check any page and it now runs a full findability audit - whether AI assistants can actually read and quote it, not just whether Google can find it",
7
+ "Catches the faults that silently make a site invisible to ChatGPT and Perplexity, like content that only appears once the browser runs it"
8
+ ]
9
+ },
3
10
  {
4
11
  "version": "0.20.5",
5
12
  "highlights": [
@@ -105,6 +105,7 @@ proxy failures, resuming a connect, support report) ·
105
105
  | `awesomate_domain_add` | Attach a custom domain to a site |
106
106
  | `awesomate_dns_check` | Live answer to "where does this domain actually point" — before and after any DNS change |
107
107
  | `awesomate_site_uptime` | 30-day availability, incidents, downtime per domain (cached, free) |
108
+ | `awesomate_site_audit` | SEO + AEO build gates for one page, fetched as GPTBot — content present without JS, retrieval bots reachable, canonical, schema, structure, speed. Not plan-gated. Run it after any public-page change, and see the awesomate-seo skill for the fixes |
108
109
  | `awesomate_snapshot_site` | Before ANY change to a live site — files + DB restore point |
109
110
  | `awesomate_list_snapshots` | What restore points a site has |
110
111
  | `awesomate_rollback_site` | Restore a snapshot after something went wrong (confirm first) |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: awesomate-seo
3
- description: Make the user's site findable by Google AND by AI assistants. Adds title/meta/Open Graph tags, sitemap.xml, robots.txt, canonical tags, JSON-LD structured data, and a general llms.txt. Works for static sites, Node apps, and WordPress. Use when the user says "SEO", "get found on Google", "rank higher", "make my site discoverable", "sitemap", "meta tags", "schema", or after building/changing a public site. Companion to awesomate-app-builder.
3
+ description: Make the user's site findable by Google AND quotable by AI assistants (SEO + AEO). Runs the build gates with awesomate_site_audit, then fixes what fails: title/meta/Open Graph, sitemap.xml, robots.txt, canonical tags, JSON-LD, answer-shaped content structure, and llms.txt. Works for static sites, Node apps, and WordPress. Use when the user says "SEO", "AEO", "GEO", "answer engine optimisation", "get found on Google", "get cited by ChatGPT", "rank higher", "make my site discoverable", "sitemap", "meta tags", "schema", or after building/changing any public page. Companion to awesomate-app-builder.
4
4
  ---
5
5
 
6
6
  # Awesomate SEO — get found on Google and AI
@@ -43,11 +43,13 @@ branch honestly.
43
43
  `plugin list`) — the whole route is behind the write gate, so "just reading
44
44
  the options" is not a way round it. The account-level reads do work
45
45
  (`awesomate_get_context`, `awesomate_list_sites`, `awesomate_list_domains`,
46
- `awesomate_dns_check`, `awesomate_site_uptime`).
46
+ `awesomate_dns_check`, `awesomate_site_uptime`, and **`awesomate_site_audit`** —
47
+ the full gate sweep works on every plan, because it reads the public page).
47
48
 
48
49
  **What Essentials CAN do — which is most of the value:** audit and advise
49
- from the outside. `curl` the pages, the sitemap, robots.txt and the rendered
50
- HTML; combine that with what they tell you; then produce the exact changes
50
+ from the outside. Start with `awesomate_site_audit` it runs the whole sweep
51
+ in one call and is NOT plan-gated, so an Essentials user gets exactly the same
52
+ findings as anyone else. Then produce the exact changes —
51
53
  the titles and descriptions to paste, the JSON-LD block, the llms.txt
52
54
  content, which plugin to install and where its settings live. They apply
53
55
  them in wp-admin; you verify by fetching the live page again. Say that up
@@ -67,12 +69,18 @@ formats + length limits. In short, per site:
67
69
  3. **`sitemap.xml`** at the root — list every real URL with `<loc>` (+ `<lastmod>`).
68
70
  4. **JSON-LD** (`<script type="application/ld+json">`) — the right schema.org
69
71
  type (`Organization` / `WebSite` / `Product` / `Article` / `LocalBusiness`).
70
- 5. **`llms.txt`** at the root a short, plain-markdown summary of what the
71
- site/business is and its key pages, so AI assistants can understand and cite
72
- it. (This is the general, non-shop counterpart to the Woo `llms.txt`.)
73
- Be honest about what it does: Google ignores it it serves the *other*
74
- assistants. For Google's AI features, normal SEO is the whole strategy.
75
- Details + crawler/rendering gotchas: [references/ai-discoverability.md](references/ai-discoverability.md).
72
+ 5. **Answer-shaped content** the part that decides whether the page is
73
+ actually *quoted* rather than merely found: answer-first sections of 120–180
74
+ words, no section opening with "it"/"this"/"also", comparisons in a real
75
+ `<table>`, specific numbers and dates inline, and every schema fact also
76
+ present in the visible copy.
77
+ Full discipline: [references/answer-structure.md](references/answer-structure.md).
78
+ This is the highest-leverage item on the list and the one most often skipped.
79
+ 6. **`llms.txt`** at the root — cheap, so write it, but keep it in proportion:
80
+ Google ignores it entirely and one study of 137,210 domains found 97% of
81
+ published files got zero requests. Generate it, never present it as a pillar,
82
+ never bill for it. Crawler/rendering gotchas:
83
+ [references/ai-discoverability.md](references/ai-discoverability.md).
76
84
 
77
85
  Then commit + deploy (awesomate-github). On content changes, update the
78
86
  affected `<head>` tags, `sitemap.xml` `<lastmod>`, and `llms.txt`.
@@ -142,7 +150,24 @@ On WordPress those three come from:
142
150
  the robots rules, the JSON-LD block, and tell them precisely where each goes
143
151
  — that is the useful half, and it works on every plan.
144
152
 
145
- ## 3. Verify
153
+ ## 3. Verify — run the gates, don't eyeball it
154
+
155
+ **`awesomate_site_audit { domain, path }`** runs the mechanical gates against
156
+ the live page, fetched *as GPTBot*, and returns pass/fail with specific fixes:
157
+ content present without JavaScript, all four retrieval bots reachable, no
158
+ accidental `noindex`/`nosnippet`, canonical pointing at this domain, valid
159
+ structured data whose facts also appear in the copy, section structure,
160
+ robots.txt + sitemap, and time-to-first-byte.
161
+
162
+ Run it after building or changing any public page, and **before telling the user
163
+ their site is discoverable**. Checking in a browser is not equivalent — the
164
+ browser runs the JavaScript that hides the biggest failure.
165
+
166
+ Two gates come back `skipped` because they need a headless browser (content
167
+ revealed only on click) or a full crawl (internal 404s). **Skipped means
168
+ unknown, not passing** — say so rather than reporting a clean sweep.
169
+
170
+ Then confirm by hand what the tool can't judge:
146
171
  - `robots.txt` and `sitemap.xml` (or the WP sitemap) return 200 at the root.
147
172
  - Each key page has a unique title + description and valid JSON-LD (no syntax
148
173
  errors — a broken `application/ld+json` block is worse than none).
@@ -23,7 +23,7 @@ it, but present it as that, never as a Google requirement.
23
23
 
24
24
  | Kind | Bots | Blocking means |
25
25
  |---|---|---|
26
- | Search-indexing | OAI-SearchBot, Claude-SearchBot, PerplexityBot | The site can't be cited in that assistant's answers. **Allow these.** |
26
+ | Search-indexing | OAI-SearchBot, Claude-SearchBot, PerplexityBot, **Bingbot** | The site can't be cited in that assistant's answers. **Allow these.** Bingbot belongs here because Copilot and several assistants ground on Bing's index. |
27
27
  | Training | GPTBot, ClaudeBot, Google-Extended, CCBot, Applebot-Extended, Meta-ExternalAgent | Owner's policy choice about model training; doesn't remove the site from answers |
28
28
  | User-triggered retrieval | ChatGPT-User, Perplexity-User, Claude-User | Fetches when a live user asks; may not fully respect robots.txt |
29
29
 
@@ -75,14 +75,34 @@ the edge. Where to fix it:
75
75
  - **Awesomate-managed domain** (`*.awesomate.site` etc.): the zone is managed
76
76
  by Awesomate — the user can't change it. Raise it via `awesomate_support`
77
77
  so the zone's AI Crawl Control settings get reviewed.
78
- - **Custom domain on the user's own Cloudflare account**: they fix it
79
- themselves in the Cloudflare dashboard → Security → Bots → AI Crawlers.
78
+ - **Custom domain on the user's own Cloudflare account**: fix it with a WAF
79
+ custom rule, action **Skip**, expression:
80
80
 
81
- ## AI crawlers do not run JavaScript
81
+ ```
82
+ cf.verified_bot_category in {"AI Crawler" "Search Engine Crawler"}
83
+ ```
82
84
 
83
- Only Googlebot renders JS. GPTBot, ClaudeBot, PerplexityBot, and the other AI
84
- crawlers read the **raw HTML response**. A client-rendered app (React/Vue SPA)
85
- is invisible to every AI assistant regardless of its meta tags and llms.txt.
85
+ Match on the **verified category, never on user-agent strings** a UA
86
+ allowlist is trivially spoofed and silently rots as bots are renamed.
87
+ Cloudflare's own AI-bot toggle does not separate citation bots from training
88
+ bots, which is why the toggle alone is the wrong instrument.
89
+
90
+ Verified 2026-09-02 across awesomate.ai, hub.awesomate.ai and eight live client
91
+ sites: all four retrieval bots got **200**, so this is not currently biting the
92
+ fleet. Re-check per site rather than assuming either way — it is a per-zone
93
+ setting and new zones are steered into blocking at signup.
94
+
95
+ ## Most AI crawlers do not run JavaScript
96
+
97
+ **Googlebot, Gemini and Applebot render JS. GPTBot, ClaudeBot, PerplexityBot,
98
+ OAI-SearchBot and Claude-SearchBot do not** — they read the **raw HTML
99
+ response**. So a client-rendered app (React/Vue/Next SPA without SSR) is
100
+ invisible to ChatGPT, Claude and Perplexity regardless of its meta tags,
101
+ schema or llms.txt.
102
+
103
+ `awesomate_site_audit` checks this automatically (gate G1) — run it rather
104
+ than eyeballing the page in a browser, which renders the JS and hides the
105
+ problem.
86
106
 
87
107
  Red flags — check the raw response, not the browser:
88
108
 
@@ -100,6 +120,29 @@ app projects, static marketing/landing pages in front of the app is usually
100
120
  enough. Don't rebuild a working app over this, but never claim AI
101
121
  discoverability for client-rendered content.
102
122
 
123
+ ## The accidental opt-out — check before blaming anything else
124
+
125
+ A page can be perfectly built, reachable and fast, and still be barred from
126
+ every AI answer by one directive. Sweep for these before investigating
127
+ anything subtler:
128
+
129
+ - `<meta name="robots" content="noindex">` — out of search AND AI answers
130
+ - `nosnippet` or `max-snippet:0` — nothing may be quoted, which is the same as
131
+ being uncitable even though the page still ranks
132
+ - an `X-Robots-Tag` response **header** carrying any of the above (easy to miss:
133
+ it is not in the HTML, so viewing source shows nothing)
134
+ - a staging `robots.txt` that shipped to production with `Disallow: /`
135
+ - in Search Console, the Search generative AI control left off
136
+
137
+ The usual causes are an SEO plugin default, a staging file promoted by mistake,
138
+ or a "private launch" setting nobody turned back off. `awesomate_site_audit`
139
+ covers the meta and header cases (gate G3); the Search Console control has to be
140
+ checked by the owner in their own account.
141
+
142
+ Note that blocking `Google-Extended` does **not** remove a site from AI
143
+ Overviews or AI Mode — that control is about training, not answers. Don't
144
+ "fix" it expecting a visibility change.
145
+
103
146
  ## llms.txt rules
104
147
 
105
148
  - Optional inventory for non-Google assistants — Google ignores it.
@@ -0,0 +1,128 @@
1
+ # Writing to be quoted — structure for AI answers
2
+
3
+ SEO gets a page found. This gets a page **cited**. Answer engines retrieve
4
+ **passages, not pages**: they lift a section, attribute it, and drop the rest.
5
+ So the section — not the page — is the unit of competition, and a section that
6
+ cannot stand alone cannot be quoted.
7
+
8
+ Run `awesomate_site_audit` to catch the mechanical faults (gate G8). It cannot
9
+ judge whether an answer is any good; that part is a human read.
10
+
11
+ ## The one rule that matters most
12
+
13
+ **Answer first.** Under every heading, the first 40–60 words must be a
14
+ complete, standalone statement that names the subject.
15
+
16
+ Roughly **55% of AI Overview citations come from the first 30% of the page**, so
17
+ an answer buried under three paragraphs of preamble is an answer nobody quotes.
18
+
19
+ ```
20
+ Bad: ## Our pricing
21
+ It depends on a few things. Every job is different, and we always…
22
+
23
+ Good: ## Our pricing
24
+ Robs Plumbing charges $180 for a standard callout in metropolitan Perth,
25
+ including the first 30 minutes on site. Emergency after-hours callouts
26
+ are $290. Quotes for larger jobs are free and fixed.
27
+ ```
28
+
29
+ The second one survives being lifted out of the page. The first one is useless
30
+ the moment it loses its heading.
31
+
32
+ ## Never open a section with a back-reference
33
+
34
+ "It", "this", "that", "these", "they", "also", "however", "as above", "as
35
+ mentioned". Once a section is extracted, there is no "above" — the subject has
36
+ vanished. Name it again, every time, even when it reads slightly repetitively on
37
+ the page. Repetition is the cost of being quotable, and it is a small cost.
38
+
39
+ ## Section length: 120–180 words
40
+
41
+ Long enough to answer, short enough to be one clean retrieval unit. A 900-word
42
+ section under one heading competes with itself: the engine has to choose which
43
+ part to lift, and often lifts none of it. Split it and give each part a heading.
44
+
45
+ ## Say the specific thing
46
+
47
+ Vague copy loses to specific copy, measurably. Adding **quotations from credible
48
+ sources raised a source's share of an AI answer by roughly 41%, statistics by
49
+ about 31%, and citations by about 28%**.
50
+
51
+ So: real numbers, real dates, named sources, units and currency **inline in the
52
+ sentence** rather than implied by a table header or an image.
53
+
54
+ ```
55
+ Bad: We serve the whole metro area and have done for years.
56
+ Good: We service Perth from Joondalup to Rockingham, and have since 2009.
57
+ ```
58
+
59
+ ## Comparisons go in a real `<table>`
60
+
61
+ `<table>` with `<th>`, never styled divs and never an image of a table. A
62
+ comparison rendered as divs is a wall of unlabelled fragments to a parser; an
63
+ image of a price list is invisible to everything. This is the single most
64
+ common way a genuinely useful pricing page fails to get cited.
65
+
66
+ ## Headings: descriptive, with the question phrasing in the first line
67
+
68
+ The evidence here is genuinely mixed, so hold it loosely:
69
+
70
+ - **FAQ *schema* shows a small negative correlation** with citations (one
71
+ analysis: 3.6 citations with it against 4.2 without). The effect is modest and
72
+ probably confounded — FAQ blocks tend to sit on thin support pages that would
73
+ earn fewer citations anyway. Google also retired FAQ rich results in May 2026.
74
+ - **Question-shaped *content*, on the other hand, is the extraction unit
75
+ everyone describes**: a question followed by a 40–80 word answer.
76
+
77
+ The safe position that satisfies both readings: **plain descriptive headings,
78
+ with the question phrasing carried in the first body line.** You keep the
79
+ question language on the page where models read it, without betting the page on
80
+ FAQ markup.
81
+
82
+ Keep real FAQs because users want them. Just don't expect the schema to be the
83
+ lever.
84
+
85
+ ## Every schema fact must also be visible
86
+
87
+ The hard rule, and the one most often broken: **no fact may exist only in
88
+ JSON-LD.** Models read the rendered text; structured data helps machines agree
89
+ on entities, but a phone number, address or price that appears *only* in the
90
+ markup is invisible to the thing you are optimising for.
91
+
92
+ `awesomate_site_audit` cross-checks this automatically (gate G7b) and lists any
93
+ schema value missing from the page copy. The fix is always **add it to the
94
+ page** — never delete it from the schema.
95
+
96
+ ## Freshness
97
+
98
+ A visible "Last updated" date, matching `dateModified` in the JSON-LD. Bump it
99
+ only on substantive change; a date that moves nightly while the words stay the
100
+ same is a stale-content signal, not a freshness one.
101
+
102
+ Sensible cadence: pricing quarterly, comparisons six-monthly, evergreen guides
103
+ annually.
104
+
105
+ ## What not to bother with
106
+
107
+ - **llms.txt as a priority.** Generate it if it's free — it is one small file —
108
+ but one study of 137,210 domains found 97% of published files received zero
109
+ requests, and Google ignores it outright. Never present it as a pillar, and
110
+ never bill for it.
111
+ - **Speakable schema.** No engine confirms using it.
112
+ - **Hidden text or instructions aimed at crawlers.** Zero measured effect, and
113
+ classed as spam by both Google and Microsoft.
114
+ - **Mass AI-written listicles.** Hit hard by the August 2026 spam update, and an
115
+ organic penalty propagates into AI visibility.
116
+
117
+ ## Local businesses: the profile usually outranks the site
118
+
119
+ For anything with a location or a service area, **Google Business Profile
120
+ supplies about 67% of local citations in AI Overviews** — more than the website
121
+ does. So a correct primary category, the full services list, real hours and
122
+ real photos are higher-leverage than another page of copy.
123
+
124
+ Keep the name, address and phone **identical** across the site, the profile and
125
+ the main directories for the vertical. Contradictions are what stop an engine
126
+ treating the business as one confident entity. For AU service businesses that
127
+ means ProductReview.com.au plus the relevant trade directories — not a blast to
128
+ hundreds of listing sites, which does nothing.