@bettercms-ai/mcp 0.63.2 → 0.64.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/README.md +1 -0
- package/SKILL.md +1 -1
- package/dist/index.js +908 -487
- package/dist/index.js.map +1 -1
- package/dist/skills/bettercms/SKILL.md +175 -0
- package/dist/skills/bettercms/references/astro.md +67 -0
- package/dist/skills/bettercms/references/bindings.md +201 -0
- package/dist/skills/bettercms/references/componentize.md +106 -0
- package/dist/skills/bettercms/references/components.md +228 -0
- package/dist/skills/bettercms/references/content-experiments.md +62 -0
- package/dist/skills/bettercms/references/content-modeling.md +185 -0
- package/dist/skills/bettercms/references/editor-chrome.md +88 -0
- package/dist/skills/bettercms/references/external-content.md +78 -0
- package/dist/skills/bettercms/references/finish-site.md +123 -0
- package/dist/skills/bettercms/references/forms-and-interactions.md +203 -0
- package/dist/skills/bettercms/references/frameworks.md +149 -0
- package/dist/skills/bettercms/references/getting-started.md +106 -0
- package/dist/skills/bettercms/references/localization.md +81 -0
- package/dist/skills/bettercms/references/media-and-brand.md +142 -0
- package/dist/skills/bettercms/references/next.md +93 -0
- package/dist/skills/bettercms/references/other-frameworks.md +66 -0
- package/dist/skills/bettercms/references/portable-text.md +206 -0
- package/dist/skills/bettercms/references/programmatic-seo.md +98 -0
- package/dist/skills/bettercms/references/publishing.md +146 -0
- package/dist/skills/bettercms/references/seo.md +156 -0
- package/dist/skills/bettercms/references/shopify-headless.md +52 -0
- package/dist/skills/bettercms/references/site-blueprints.md +250 -0
- package/dist/skills/bettercms/references/site-review.md +73 -0
- package/dist/skills/bettercms/references/write-limits.md +84 -0
- package/package.json +2 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Site blueprints"
|
|
3
|
+
description: "Route, collection and section plans per business type: portfolio, agency, corporate, SaaS/AI and ecommerce."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Site blueprints by business type
|
|
7
|
+
|
|
8
|
+
A route and content model that fits the business, while editor folders, public URLs and reusable
|
|
9
|
+
components stay separate. A blueprint is a starting hypothesis, not permission to replace a
|
|
10
|
+
working site's taxonomy. The platform rules behind each layer are in
|
|
11
|
+
[content-modeling.md](content-modeling.md).
|
|
12
|
+
|
|
13
|
+
## Contents
|
|
14
|
+
|
|
15
|
+
- [Common decision process](#common-decision-process)
|
|
16
|
+
- [Starter rules](#starter-rules)
|
|
17
|
+
- [Deliverables](#deliverables)
|
|
18
|
+
- Catalogs, read only the one that matches (a mixed site can use two, but give each page family
|
|
19
|
+
one route owner):
|
|
20
|
+
- [Portfolio](#portfolio-website): a person or studio presents selected work, services and a
|
|
21
|
+
contact path
|
|
22
|
+
- [Agency](#agency-website): services, sectors, proof and lead generation drive the site
|
|
23
|
+
- [Corporate](#corporate-website): several business units, regions, audiences, governance or
|
|
24
|
+
regulated content coexist
|
|
25
|
+
- [SaaS, AI, enterprise tech](#saas-ai-and-enterprise-technology-website): product,
|
|
26
|
+
solutions, industries, integrations, trust and education need separate models
|
|
27
|
+
- [Large ecommerce](#large-ecommerce-website): catalog, categories, products and shopping
|
|
28
|
+
journeys dominate; a Shopify-backed store also reads [shopify-headless.md](shopify-headless.md)
|
|
29
|
+
|
|
30
|
+
Data-generated page families (glossary, integrations, locations): [programmatic-seo.md](programmatic-seo.md).
|
|
31
|
+
|
|
32
|
+
## Common decision process
|
|
33
|
+
|
|
34
|
+
1. Inventory existing public URLs, navigation, templates, source content, business goals,
|
|
35
|
+
locales, owners, analytics and design tokens. Keep established URLs and brand rules unless a
|
|
36
|
+
change is in scope.
|
|
37
|
+
2. Give each family a **source of truth**: a BetterCMS page, a collection entry, an external
|
|
38
|
+
system (commerce, ATS, docs), or application runtime. Name its editorial owner and publishing
|
|
39
|
+
gate. Record capabilities BetterCMS does not have as gaps; never invent fields that imply
|
|
40
|
+
them.
|
|
41
|
+
3. Produce a route matrix: pattern, purpose, static / list / detail, content source, template,
|
|
42
|
+
canonical, indexability, sitemap eligibility, and the redirect it replaces. A collection's
|
|
43
|
+
list is a page; its entries render through one dynamic detail page.
|
|
44
|
+
4. Produce a model matrix: fields and groups, references, taxonomy, reusable sections, global
|
|
45
|
+
nav/footer, labels, and variants. Components for reusable presentation, collections for
|
|
46
|
+
entities with their own lifecycle. Whether bands become components or fields follows
|
|
47
|
+
`authoringPreference` from `get_project`, which only the owner answers.
|
|
48
|
+
5. Propose **Content sidebar** folders for editor tasks, **component groups** for definitions,
|
|
49
|
+
and **media folders** for assets. None of these changes a URL. **URL page folders** do change
|
|
50
|
+
paths, and renaming one 301s its pages, so they need explicit review. Sidebar doctrine:
|
|
51
|
+
`bettercms://playbook/structure`.
|
|
52
|
+
6. Define per-family SEO policy: one canonical target, real indexable content, native SEO
|
|
53
|
+
metadata (never modelled fields, §5b of `bettercms://playbook/schema`), structured data only
|
|
54
|
+
where visible facts support it, and the treatment of filters, search, pagination, drafts,
|
|
55
|
+
gated pages and deleted records. Pages marked noindex are left out of the generated sitemap.
|
|
56
|
+
7. Validate one representative route per family and the edge cases: empty collection, long
|
|
57
|
+
title, unpublished detail, duplicate slug, moved URL, mobile nav, optional section, locale,
|
|
58
|
+
no-result state. Confirm edit, preview and public render, then the build and binding reports.
|
|
59
|
+
|
|
60
|
+
## Starter rules
|
|
61
|
+
|
|
62
|
+
- Reference page lists illustrate common shapes; do not create pages the business does not have.
|
|
63
|
+
- Prefer a few stable, human-readable route patterns. The best URL is often the existing one.
|
|
64
|
+
- Keep a slug unique within its route namespace; check static against dynamic paths and locales.
|
|
65
|
+
When a published URL changes, add a redirect (`create_redirect`).
|
|
66
|
+
- Keep a dedicated 404 and access/error pages. Leave drafts, private areas, internal search,
|
|
67
|
+
parameter duplicates and 404s out of the sitemap.
|
|
68
|
+
- Sitemaps hold absolute, canonical, indexable URLs; Google documents a limit of 50,000 URLs /
|
|
69
|
+
50 MB uncompressed per file. [Google sitemap guide](https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap)
|
|
70
|
+
- Content sidebar folders are navigation for editors. Public hierarchy comes from routes and
|
|
71
|
+
internal links, never from folder labels. [Google ecommerce site structure](https://developers.google.com/search/docs/specialty/ecommerce/help-google-understand-your-ecommerce-site-structure)
|
|
72
|
+
- With locale variants, keep explicit equivalent-page mappings and one `hreflang`
|
|
73
|
+
implementation, verified in the rendered head. [Google localized versions](https://developers.google.com/search/docs/specialty/international/localized-versions)
|
|
74
|
+
|
|
75
|
+
## Deliverables
|
|
76
|
+
|
|
77
|
+
Return a route tree, route matrix, content and model matrix, folder plan, component inventory,
|
|
78
|
+
sitemap and redirect policy, open ownership decisions, and a phased implementation plan. On a
|
|
79
|
+
live project, implement only the scope the user asked for and verify the routes you touched.
|
|
80
|
+
|
|
81
|
+
## Portfolio website
|
|
82
|
+
|
|
83
|
+
Use this when the primary job is to show selected work and make an individual or small studio credible. First determine whether the work is private, client-approved, dated, or still under embargo.
|
|
84
|
+
|
|
85
|
+
### Route and model starter
|
|
86
|
+
|
|
87
|
+
| Family | Example path | BetterCMS model | Index and sitemap |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| Home | `/` | Static page with selected projects and clear contact action | Yes |
|
|
90
|
+
| Work index | `/work/` | Static index page querying Projects | Yes if substantive |
|
|
91
|
+
| Project detail | `/work/{slug}/` | Projects collection + one dynamic template | Published, approved projects only |
|
|
92
|
+
| About / services | `/about/`, `/services/` | Static pages unless services need independent owners and detail pages | If public and useful |
|
|
93
|
+
| Writing / speaking | `/writing/`, `/writing/{slug}/` | Optional collection and index | Published articles only |
|
|
94
|
+
| Contact | `/contact/` | Static page + form | Usually yes |
|
|
95
|
+
| Password/preview case study | Existing route | Other page or protected runtime route | No |
|
|
96
|
+
|
|
97
|
+
Keep the existing work prefix if it is `/projects/`, `/case-studies/`, or another established route; route changes need a redirect map.
|
|
98
|
+
|
|
99
|
+
### Editor structure
|
|
100
|
+
|
|
101
|
+
Content sidebar: `Start here` (Home, About, Contact), `Portfolio` (Work index, Projects), `Writing` if used, `Site essentials` (legal/other). Component groups: `Globals`, `Portfolio` (project hero, gallery, outcomes), `Shared sections` (CTA, quote, logo strip). Media folders may separate approved client work, self-initiated work, portraits, and downloadable files. These folders do not determine URLs.
|
|
102
|
+
|
|
103
|
+
Project entry fields: display title, slug, client display name, service/category references, summary, role, dates when relevant, hero image plus alt text, ordered gallery items with captions/alt, challenge, approach, verified outcomes, credits, related projects, SEO, approval/visibility state. Do not require a public client name, metric, or testimonial when consent is absent. Support anonymous case studies without accidentally exposing the original client in image filenames, alt text, schema, or social previews.
|
|
104
|
+
|
|
105
|
+
Use repeatable gallery items rather than a long list of `image1` fields. Give each item a meaningful editor label and image metadata. Keep project-specific storytelling sections as instances; make hero/gallery/quote layouts reusable definitions with instance overrides.
|
|
106
|
+
|
|
107
|
+
### Validation
|
|
108
|
+
|
|
109
|
+
Check case-study consent, working gallery at different aspect ratios, captions, full-size media performance, downloadable file links, contact submission, related-work references, archived projects, and redirect behavior for renamed slugs. A portfolio with only a few projects does not need auto-generated service × industry pages.
|
|
110
|
+
|
|
111
|
+
## Agency website
|
|
112
|
+
|
|
113
|
+
Use when the site must explain services, prove results, and convert qualified leads. The key distinction from a portfolio is a durable offer taxonomy and repeatable proof linked to each offer.
|
|
114
|
+
|
|
115
|
+
### Route and model starter
|
|
116
|
+
|
|
117
|
+
| Family | Example path | Model and purpose |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Home | `/` | Static overview, positioning, primary CTA |
|
|
120
|
+
| Services index/detail | `/services/`, `/services/{slug}/` | Static index + Services collection only if multiple services have owners, proof, and maintained detail content; otherwise static pages |
|
|
121
|
+
| Industries | `/industries/`, `/industries/{slug}/` | Optional collection; publish only distinct industry expertise |
|
|
122
|
+
| Work index/detail | `/work/`, `/work/{slug}/` | Case studies collection and dynamic detail template |
|
|
123
|
+
| Insights | `/insights/`, `/insights/{slug}/` | Editorial collection, authors, categories |
|
|
124
|
+
| Agency | `/about/`, `/team/`, `/careers/` | Static or collection by update cadence |
|
|
125
|
+
| Contact | `/contact/` | Form with routing/consent behavior |
|
|
126
|
+
|
|
127
|
+
Use the established `/case-studies/`, `/blog/`, etc. when the current site already has them. A service × industry matrix should be created only for combinations with distinct evidence, offer, and maintenance owner; otherwise link the existing service and industry pages instead of generating thin duplicates.
|
|
128
|
+
|
|
129
|
+
### Content relationships and components
|
|
130
|
+
|
|
131
|
+
Cases reference services, industries, client permission state, outcome evidence, and optional quotes. Service pages reference relevant cases, deliverables, process, FAQ, and CTA. Industry pages reference services/cases and sector-specific language. Avoid duplicating client logos or metrics across pages: maintain permission and source context on the case/client record.
|
|
132
|
+
|
|
133
|
+
Component groups: `Globals` (nav/footer), `Proof` (case card, metrics, testimonial), `Offers` (service card, process), `Conversion` (CTA, contact form), `Editorial`. Reuse definitions with page-specific props, and allow section order to vary by page. Editors should see grouped fields such as `Primary button → Label, Link`, `Proof item → Metric, Context, Source`.
|
|
134
|
+
|
|
135
|
+
Content sidebar folders should match editor work: `Core pages`, `Services`, `Industries`, `Case studies`, `Insights`, `Company`. These are dashboard folders, not paths.
|
|
136
|
+
|
|
137
|
+
### Validation
|
|
138
|
+
|
|
139
|
+
Review lead form destination, attribution and consent, internal links from every offer to relevant proof, case-study rights, schema claims, duplicate service routes, old URL redirects, and mobile CTA visibility. Keep draft or client-confidential work out of sitemaps and public data feeds.
|
|
140
|
+
|
|
141
|
+
## Corporate website
|
|
142
|
+
|
|
143
|
+
Use for multiple audiences, brands, regions, business units, approval chains, or regulated statements. The main modeling problem is ownership: who can update a statement, which sites reuse it, and when it expires.
|
|
144
|
+
|
|
145
|
+
### Route and model starter
|
|
146
|
+
|
|
147
|
+
| Family | Example path | Owner and model |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| Corporate home | `/` | Global communications; static page |
|
|
150
|
+
| Business units | `/businesses/{slug}/` | Collection if units share a template and lifecycle |
|
|
151
|
+
| Products/services | Existing taxonomy | Collection or static pages by unit ownership |
|
|
152
|
+
| Newsroom | `/news/`, `/news/{slug}/` | News collection, media contact, publish date |
|
|
153
|
+
| Leadership | `/leadership/`, `/leadership/{slug}/` | People collection if profiles recur |
|
|
154
|
+
| Careers | `/careers/` | Landing page; job details may remain in an ATS |
|
|
155
|
+
| Investor / governance | `/investors/`, `/governance/` | Gated approval; files with version/date |
|
|
156
|
+
| Policies and legal | `/privacy/`, `/terms/` | Static pages with accountable owner |
|
|
157
|
+
| Contact / locations | `/contact/`, `/locations/{slug}/` | Form plus locations collection when needed |
|
|
158
|
+
|
|
159
|
+
Do not copy ATS jobs, stock prices, investor filings, or regulated data into BetterCMS unless BetterCMS is deliberately the system of record. Preserve external systems and public links.
|
|
160
|
+
|
|
161
|
+
### Governance and editor structure
|
|
162
|
+
|
|
163
|
+
Record owner, reviewer, source of claim, effective date, review date, and version where these matter. Separate draft, legal-reviewed, approved, and published states with the project's own editorial board: read its stages and which one is the publish gate with `get_workflow_board` before `move_stage`, because stage keys are per project. Do not claim an approval stage exists if the board has none. Scope access and publishing by the product's real permissions. High-risk copy (financial figures, certifications, compliance claims, regulated products) needs a verified source and designated reviewer.
|
|
164
|
+
|
|
165
|
+
Content sidebar: `Corporate pages`, `Business units`, `Newsroom`, `People`, `Investors`, `Legal`, `Regions` if used. Component groups: `Globals`, `Corporate identity`, `Business unit`, `Newsroom`, `Data/proof`. Distinguish sitewide global identity from unit-specific branding and local navigation. A shared global component should not overwrite an independently branded unit page.
|
|
166
|
+
|
|
167
|
+
### Regions and languages
|
|
168
|
+
|
|
169
|
+
Choose a deliberate URL strategy, such as `/{locale}/...` or regional domains. Keep locale-to-locale equivalent-page IDs, fallback behavior, canonical target, and language switcher destinations. Check what the connected project models for locales before planning; implement and verify `hreflang` output in the frontend, where the rendered head is decided. Do not auto-redirect by IP or index machine placeholders. Follow [Google's localized-page guidance](https://developers.google.com/search/docs/specialty/international/localized-versions).
|
|
170
|
+
|
|
171
|
+
### Validation
|
|
172
|
+
|
|
173
|
+
Test unit-specific nav/footers, ownership permissions, embargoed news, expiring files, superseded legal pages, regional links, localization fallbacks, 404/redirects, accessibility, and the published head for every major template. Separate search visibility from access control: `noindex` does not protect private information.
|
|
174
|
+
|
|
175
|
+
## SaaS, AI, and enterprise technology website
|
|
176
|
+
|
|
177
|
+
Use when a product site must explain a platform to multiple buyers and evaluators. Distinguish product truth, marketing interpretation, developer documentation, and live application behavior.
|
|
178
|
+
|
|
179
|
+
### Route and model starter
|
|
180
|
+
|
|
181
|
+
| Family | Example path | Suggested ownership |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| Home | `/` | Static marketing composition |
|
|
184
|
+
| Product/platform | `/product/`, `/features/{slug}/` | Static overview; Features collection only if repeated and maintained |
|
|
185
|
+
| Solutions | `/solutions/{slug}/` | Collection for distinct jobs-to-be-done/use cases |
|
|
186
|
+
| Industries | `/industries/{slug}/` | Collection where sector-specific workflows/proof exist |
|
|
187
|
+
| Integrations | `/integrations/{slug}/` | Collection with provider status, auth, capability, owner |
|
|
188
|
+
| Customers | `/customers/{slug}/` | Case studies with approvals and proof sources |
|
|
189
|
+
| Pricing | `/pricing/` | Static page or runtime-driven product data; one owner for actual pricing |
|
|
190
|
+
| Resources | `/resources/{slug}/`, `/blog/{slug}/` | Editorial collections and their list pages |
|
|
191
|
+
| Glossary | `/glossary/{term}/` | Definition collection with editorial gates |
|
|
192
|
+
| Comparisons / alternatives | `/compare/{slug}/` | Dedicated reviewed model, never blind competitor templating |
|
|
193
|
+
| Trust and legal | `/security/`, `/privacy/`, `/trust/` | Static pages or external trust center |
|
|
194
|
+
| Docs / API | `/docs/...` | Often a separate docs system/repository; link rather than duplicate |
|
|
195
|
+
| Conversion | `/demo/`, `/contact/` | Forms with routing, consent, and success states |
|
|
196
|
+
|
|
197
|
+
These are options, not required pages. Keep existing routes and product naming. For a large enterprise site, consider ownership by product line/market and a shared navigation contract; avoid separate page schemas for identical layouts.
|
|
198
|
+
|
|
199
|
+
### Model and section kit
|
|
200
|
+
|
|
201
|
+
Entities: Solutions, Industries, Features, Integrations, Cases, Resources, Glossary Terms, and optional Comparisons. Use references across them so an integration or proof item updates once. Each entry needs an owner, lifecycle, canonical URL, native SEO metadata, and sufficient unique content. Integration entries need a clear status (live, beta, planned) and must never imply a planned connector is available.
|
|
202
|
+
|
|
203
|
+
Shared sections: product hero, outcome grid, workflow steps, feature visual, integration grid, proof strip, case excerpt, FAQ, security/trust callout, pricing CTA. Keep a single component definition per visual family and use variants/instance overrides. Give buttons and media grouped editor controls. Expose only supported rich-text headings; a hero title may be plain text rendered as H1 while an article body may allow H2/H3, links, lists, and code if the renderer supports them.
|
|
204
|
+
|
|
205
|
+
Content sidebar: `Core pages`, `Product`, `Solutions`, `Industries`, `Integrations`, `Customers`, `Resources`, `Trust`, `Other`. Component groups should reflect role, not route.
|
|
206
|
+
|
|
207
|
+
### Search and AEO
|
|
208
|
+
|
|
209
|
+
Build topic hubs and link related solution, industry, integration, case, and glossary pages. Only publish a specific solution × industry page when it adds differentiated workflow, evidence, and value. Answer questions directly with verifiable facts and useful context; do not fabricate FAQ, schema, or “AI answer” pages. Use [programmatic-seo.md](programmatic-seo.md) for generated page families and [Google's AI-search guidance](https://developers.google.com/search/docs/fundamentals/ai-optimization-guide) for the current search-policy boundary.
|
|
210
|
+
|
|
211
|
+
### Validation
|
|
212
|
+
|
|
213
|
+
Verify product claims against shipped capability, integration statuses, pricing consistency, demo form routing, docs links, internal topic paths, glossary duplicates, comparison accuracy, rendering of code/rich text, and desktop/mobile navigation. Noindex preview, gated assets, and incomplete pages.
|
|
214
|
+
|
|
215
|
+
## Large ecommerce website
|
|
216
|
+
|
|
217
|
+
Use for a catalog-heavy site regardless of commerce engine. The core choice is the boundary between **commerce facts** and **editorial merchandising**.
|
|
218
|
+
|
|
219
|
+
### Source-of-truth contract
|
|
220
|
+
|
|
221
|
+
Products, variants, SKUs, price, availability, tax, orders, checkout, customer accounts, and fulfillment normally belong to the commerce platform. BetterCMS owns editorial landing pages, category storytelling, buying guides, banners, proof, and selected product-page content blocks. A CMS reference to a product uses a stable external ID plus a verified lookup; don't silently duplicate transactional fields into editable CMS text.
|
|
222
|
+
|
|
223
|
+
### Route and model starter
|
|
224
|
+
|
|
225
|
+
| Family | Example path | Index policy |
|
|
226
|
+
|---|---|---|
|
|
227
|
+
| Home and campaigns | `/`, `/campaigns/{slug}/` | Public, unique campaigns |
|
|
228
|
+
| Catalog root / category | `/shop/`, `/collections/{slug}/` | Curated category pages with products and links |
|
|
229
|
+
| Product | `/products/{slug}/` | Available public products; decide retired-product policy |
|
|
230
|
+
| Brand | `/brands/{slug}/` | Only substantive brand pages |
|
|
231
|
+
| Buying guides | `/guides/{slug}/` | Unique advice with product references |
|
|
232
|
+
| Editorial | `/stories/{slug}/` | Published articles |
|
|
233
|
+
| Search, cart, account, checkout | Runtime routes | Usually excluded from sitemap; private data protected |
|
|
234
|
+
| Filters and sort | Parameters on category routes | Explicit crawl/index policy; avoid unbounded URL combinations |
|
|
235
|
+
|
|
236
|
+
Keep existing paths if the store already uses another taxonomy. Decide whether unavailable products stay indexable, redirect to a successor, or return 404/410 based on permanence and user value. Do not redirect every missing product to the homepage.
|
|
237
|
+
|
|
238
|
+
### Editor model and reuse
|
|
239
|
+
|
|
240
|
+
Models: Campaigns, Buying Guides, optional Brand and Category editorial records, plus product references. Category merchandising groups can include hero, intro, featured products, editorial cards, filters, and FAQs. Components: global store nav, search, promo bar, product card, variant selector, add-to-cart, category hero, recommendation rail, cart feedback. Commerce controls remain functional code tied to live data; an editor can change allowed presentation and copy but must not create an unfulfillable cart action.
|
|
241
|
+
|
|
242
|
+
Content sidebar: `Campaigns`, `Collections`, `Guides`, `Stories`, `Store pages`; group media by campaigns/editorial needs. Content sidebar folders never change a URL; URL page folders do, and renaming one 301s its pages, so do not turn category folders into URL folders unless a route change is intended.
|
|
243
|
+
|
|
244
|
+
### Crawl and scale
|
|
245
|
+
|
|
246
|
+
Provide crawlable category → subcategory → product links and paginated result URLs. Decide which facet combinations deserve dedicated curated landing pages; keep the rest out of the index/crawl space by an intentional policy. Do not rely on canonical alone to control a near-infinite faceted URL space. Keep canonical, internal link, and sitemap URLs consistent. Sitemaps should include only eligible canonical pages and split before protocol limits. Product price/availability markup must match the current displayed commerce data; validate variant markup against Google's current `ProductGroup` guidance. [Google ecommerce structure](https://developers.google.com/search/docs/specialty/ecommerce/help-google-understand-your-ecommerce-site-structure) · [Faceted navigation](https://developers.google.com/crawling/docs/faceted-navigation) · [Product variants](https://developers.google.com/search/docs/appearance/structured-data/product-variants)
|
|
247
|
+
|
|
248
|
+
### Validation
|
|
249
|
+
|
|
250
|
+
Test a product with several variants, a sold-out product, missing image, empty category, deep pagination, filter combinations, mobile search, currency/market change, cart handoff, and changed price after cache expiry. Verify that sitemap counts match eligible catalog records and that deleted routes/redirects do not strand internal links.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Site review"
|
|
3
|
+
description: "A read-only launch review: what to check per route and how to report findings without fixing them."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Read-only site review
|
|
7
|
+
|
|
8
|
+
**Outcome.** An evidence-backed issue list, scoped to the actual project and revision, that a
|
|
9
|
+
developer can reproduce and prioritise. Change no data or code during a review unless the user
|
|
10
|
+
separately asks for repairs.
|
|
11
|
+
|
|
12
|
+
## Establish a baseline
|
|
13
|
+
|
|
14
|
+
Identify the project, source commit, import or release revision, hosting mode (`get_project`),
|
|
15
|
+
public or staging URL, and expected route inventory. Then read the control plane and record when
|
|
16
|
+
each report was generated:
|
|
17
|
+
|
|
18
|
+
| Read | Tells you |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `get_site_composition` | Which pages are made of sections, and which components they use |
|
|
21
|
+
| `get_binding_report` | Per route: `mode` (`declared` or `text-match`), `coverage.pending`, and `refreshReason` when there is no current report |
|
|
22
|
+
| `list_seo_issues` | Native SEO problems per page |
|
|
23
|
+
| `get_component_readiness` | Per component: validation and Output state |
|
|
24
|
+
| `list_forms` | Which forms exist and whether each is published |
|
|
25
|
+
| `get_deploy_status` | The last build and release |
|
|
26
|
+
| `get_next_steps` | What the platform itself still counts as unfinished |
|
|
27
|
+
|
|
28
|
+
A binding report is created only by a BetterCMS release (a content apply later updates its Layout
|
|
29
|
+
rows), so a headless site may never have one; `never-generated` is missing evidence, not a clean
|
|
30
|
+
result. A green control plane cannot prove a route answers:
|
|
31
|
+
fetch rendered pages too, cache-busted.
|
|
32
|
+
|
|
33
|
+
Sample every **route class** (static, list, collection detail, 404 or protected, locale) and
|
|
34
|
+
every **component family**. Include two instances of a reused component, one variant, one nested
|
|
35
|
+
slot, the global nav and footer, long and empty content, and a custom Portable Text block when
|
|
36
|
+
present. Widen the sample when a failure looks systematic.
|
|
37
|
+
|
|
38
|
+
## Review dimensions
|
|
39
|
+
|
|
40
|
+
| Dimension | Evidence to collect |
|
|
41
|
+
|---|---|
|
|
42
|
+
| Structure | Page / collection / entry classification, which of the four folder systems is used for what, route and redirect integrity |
|
|
43
|
+
| Reuse | Definition, default, variant and instance ownership; override isolation; global chrome; slot limits |
|
|
44
|
+
| Editability | Schema, stored value, reader, prop, bound leaf or attribute, preview, published output; intended fields against verified bindings |
|
|
45
|
+
| Editor UX | Field types, allowed Portable Text controls, labels, grouping, defaults, required states, repeatable-item previews |
|
|
46
|
+
| Design and media | Brand tokens, font loading, logo roles, asset delivery from the project's media origin, alt / caption / crop, desktop and mobile fidelity |
|
|
47
|
+
| Behaviour | Forms and their destinations, keyboard and focus, navigation, accordion / modal / consent logic, custom code |
|
|
48
|
+
| Discoverability | Native SEO, canonical and noindex, structured data matching visible content, sitemap and robots, internal links |
|
|
49
|
+
| Delivery | Build, cache and revalidation, live status and content, draft isolation, secrets and the server/client boundary |
|
|
50
|
+
|
|
51
|
+
Use automated checks where they answer a concrete question, and manual visual or editor checks
|
|
52
|
+
where automation cannot show intent. Never edit production as a test. If an edit-to-render test
|
|
53
|
+
needs a write, mark it unverified in a read-only review, or get the user's authorisation for a
|
|
54
|
+
safe draft test.
|
|
55
|
+
|
|
56
|
+
Useful anchors while reviewing: a draft form refuses public submissions (403), so a form that
|
|
57
|
+
renders but is not published cannot take a lead; a headless project is never built by BetterCMS,
|
|
58
|
+
so its proof is the external host's public response; a Content sidebar folder never changes a
|
|
59
|
+
URL, while renaming a URL page folder 301s its pages.
|
|
60
|
+
|
|
61
|
+
## Issue format and decision
|
|
62
|
+
|
|
63
|
+
For each issue record severity (blocker, high, medium, low), the route / component / field,
|
|
64
|
+
expected against observed, exact reproduction, evidence (link, screenshot, report time), likely
|
|
65
|
+
owner, and a specific acceptance check. Separate a verified defect from an inference or missing
|
|
66
|
+
evidence. Summarise coverage as verified intended editable fields divided by discovered intended
|
|
67
|
+
editable fields, with exclusions listed separately.
|
|
68
|
+
|
|
69
|
+
Recommend **ready**, **ready with named exceptions**, or **not ready**. A blocker includes a
|
|
70
|
+
broken public route, lost content or reference, an unbound core editorial value, a form sending
|
|
71
|
+
to the wrong destination, an exposed secret, or a live state that contradicts what the user
|
|
72
|
+
intended. For each, give the smallest repair path and whether it belongs to code, CMS data, a
|
|
73
|
+
platform capability, or a user decision.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Write limits"
|
|
3
|
+
description: "What the server checks on a content write (lengths, patterns, uniqueness, references, body size) and what it does not."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Write limits: what the server checks on a content write
|
|
7
|
+
|
|
8
|
+
Use this before you rely on a limit. "Exists" means the server refuses a bad value. "Does not
|
|
9
|
+
exist" means the value is stored, so you are the check.
|
|
10
|
+
|
|
11
|
+
## The write path
|
|
12
|
+
|
|
13
|
+
Entry writes from the MCP and the Management API run `createEntry` / `updateEntry` in
|
|
14
|
+
`src/lib/content/entry-write.ts`:
|
|
15
|
+
|
|
16
|
+
1. Request schema (Zod). Failure: 400 with `{ errors }`, keyed by field, no `code`.
|
|
17
|
+
2. Value normalisation (shapes below). Failure: a validation result with `errors`.
|
|
18
|
+
3. Per-field value checks against the model. Failure: a validation result with `errors`.
|
|
19
|
+
4. Uniqueness, inside the insert transaction. Failure: `kind: "unique_conflict"` with `conflicts`.
|
|
20
|
+
|
|
21
|
+
The batch route reports the same two outcomes as `code: "UNIQUE_CONFLICT"` or `"VALIDATION"`.
|
|
22
|
+
|
|
23
|
+
Rule: read `errors` by field key, fix exactly those fields, write again once.
|
|
24
|
+
|
|
25
|
+
`update_content_entry` `data` REPLACES the entry's whole value object: an optional field left out
|
|
26
|
+
is deleted. Send `merge: true` to lay `data` over the stored value by top-level key (a group or
|
|
27
|
+
repeater you send still replaces that whole key). Pass `ifMatch` (the `optimisticVersion` from
|
|
28
|
+
`get_content_entry`) so a 409 tells you someone wrote since your read; with `merge` it defaults to
|
|
29
|
+
the version the merge read.
|
|
30
|
+
|
|
31
|
+
## Limits that exist
|
|
32
|
+
|
|
33
|
+
| Limit | Behaviour |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `maxLength` / `minLength` in text field config | Counted in characters. An empty value is left to `required` |
|
|
36
|
+
| `pattern` in text field config | Tested against every non-empty value |
|
|
37
|
+
| Numeric limit config (`maxLength`, `minLength`, `min`, `max`, `step`) on model save | A numeric string (`"60"`) is stored as a number; an impossible value (`"abc"`, a negative length, `step: 0`, `min` above `max`, a pattern that does not compile) is refused with `FIELD_CONFIG_INVALID`, naming the field and the fix |
|
|
38
|
+
| Repeater `maxItems` | Enforced when a number |
|
|
39
|
+
| `select` value | Must be one of the field's options |
|
|
40
|
+
| Rich text top-level `_type` | A name nothing renders is refused, naming `_type` and `_key`. Top level only — a foreign mark keeps its text unmarked, a foreign inline child renders nothing |
|
|
41
|
+
| Request body | 260 MB for the whole server |
|
|
42
|
+
|
|
43
|
+
## Limits that do not exist (you hold them)
|
|
44
|
+
|
|
45
|
+
| Missing check | Rule for the agent |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Limit config saved as a string before the model-save check existed | Write every numeric config value as a JSON number; re-save a model you find with string limits |
|
|
48
|
+
| Modular (block) field `blockSlugs`, `minItems`, `maxItems` | Check the block list against the field config yourself before writing |
|
|
49
|
+
| Reference existence on draft save and publish (shape only) | Read each referenced entry id before you write the reference |
|
|
50
|
+
| Component `overrides` (any keys, any types; required props not enforced) | Write only declared prop keys with the declared type; fill every prop the component needs |
|
|
51
|
+
| Size or depth of text, richtext and JSON values | Keep values to what the page renders; never paste whole documents into one field |
|
|
52
|
+
| Publish re-validation (publish copies the draft to live) | Only publish a draft you wrote through the write path above |
|
|
53
|
+
| Version restore re-validation (restore writes the stored snapshot) | After a restore, read the entry and write it back through `update_content_entry` so checks run |
|
|
54
|
+
|
|
55
|
+
## Normaliser output shapes
|
|
56
|
+
|
|
57
|
+
What you read back after a write:
|
|
58
|
+
|
|
59
|
+
| Field | Stored shape |
|
|
60
|
+
|---|---|
|
|
61
|
+
| richtext | `{ format, value, html }` envelope |
|
|
62
|
+
| image | `{ id, url, name, altText }`. An asset id or media URL resolves to its asset; a site-relative path resolves to the asset the build adopted; an external URL on a project-scoped write is fetched and stored as a new asset. Only when none of that works (fetch refused or failed, no project scope) is it kept as `{ url }` (plus `altText` if given) |
|
|
63
|
+
| group / repeater (zoned) | Zone envelopes `{ nonRepeatable, repeatable }`, walked field by field |
|
|
64
|
+
| repeater given a bare array | Wrapped as `{ repeatable: [...] }` |
|
|
65
|
+
|
|
66
|
+
Rich text written as HTML or markdown may be stored in the older Lexical format depending on a
|
|
67
|
+
server flag. Portable Text arrays are always stored as Portable Text
|
|
68
|
+
([portable-text.md](portable-text.md)).
|
|
69
|
+
|
|
70
|
+
A stored value of `{ html }` is the shape starter templates and `bcms-content.json` seed. Writes
|
|
71
|
+
accept it and store the full envelope, so sending an entry's data back unchanged works. Do not
|
|
72
|
+
write new rich text in that shape.
|
|
73
|
+
|
|
74
|
+
## Other refusal codes that exist today
|
|
75
|
+
|
|
76
|
+
| Area | Codes | Where described |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Content sidebar structure | `NAV_SYSTEM_FOLDER`, `NAV_TYPE_MISMATCH`, `NAV_KIND_MISMATCH`, `NAV_PAGE_BOUND_MODEL`, `SCHEMA_ACCESS_REQUIRED` | the folder tool descriptions |
|
|
79
|
+
| Hosting | `HEADLESS_NO_BUILD`, `HEADLESS_NEEDS_CUSTOM_HOST`, `HEADLESS_ARTIFACT_TARGET` | [frameworks.md](frameworks.md) |
|
|
80
|
+
| Components | `COMPONENT_*` publish codes | [components.md](components.md) §4 |
|
|
81
|
+
| Content models | `FIELD_CONFIG_INVALID` | this file |
|
|
82
|
+
| Forms | `FORM_FIELD_INVALID`, `FORM_DEFINITION_INVALID`, `FORMS_WORKER_NOT_CONFIGURED`, `FORMS_WORKER_SECRET_UNSET`, `FORM_SUBMISSION_NOT_FOUND`, `FORM_SECRET_DASHBOARD_ONLY` | [forms-and-interactions.md](forms-and-interactions.md) |
|
|
83
|
+
|
|
84
|
+
`SCHEMA_ACCESS_REQUIRED` (403): see the owner boundary in SKILL.md.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bettercms-ai/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "BetterCMS MCP server — schema, content, forms + components authoring tools over the Management API, authed via OAuth device-code.",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@bettercms-ai/device-auth": "^0.2.0",
|
|
35
|
-
"@bettercms-ai/sdk": "^1.
|
|
35
|
+
"@bettercms-ai/sdk": "^1.25.0",
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
37
37
|
"zod": "^4.3.6"
|
|
38
38
|
},
|