@typeroll/mcp-server 0.45.65 → 0.45.66

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/skills/tr-seo.md CHANGED
@@ -36,7 +36,8 @@ read_site_settings
36
36
  ```
37
37
 
38
38
  For each page, check:
39
- - Is `seo_title` set? (if not, Google uses `title` + suffix — often fine)
39
+ - Is `seo_title` set? (if not, Google uses `title` + suffix — often fine;
40
+ aim for 50–60 characters, longer gets truncated)
40
41
  - Is `seo_description` set? (150–160 chars, unique per page, includes keywords)
41
42
  - Is `og_image` set for the homepage and key landing pages?
42
43
  - Does the page have exactly one `<h1>`?
@@ -79,6 +80,20 @@ update_page page_id="home" patch={
79
80
  }
80
81
  ```
81
82
 
83
+ ### 3b. URL and article conventions
84
+
85
+ When creating or moving pages:
86
+
87
+ - Slugs are lowercase kebab-case: `our-services`, not `Our_Services`.
88
+ - Reflect hierarchy in the address. A team member lives at `/team/jane-doe`
89
+ (set `path`, or use a content type whose `route_template` adds the
90
+ prefix), not at `/jane-doe`. Breadcrumbs and their BreadcrumbList schema
91
+ follow the resolved route.
92
+ - Blog posts and news get `kind: "article"` and an `author`: that emits
93
+ Article JSON-LD and `og:type=article`. No author means no author in the
94
+ rich result.
95
+ - Give shared pages, especially articles, their own `og_image`.
96
+
82
97
  ### 4. Add Open Graph images
83
98
 
84
99
  Set `og_image` on pages that get shared on social media. If the site has
@@ -116,6 +131,37 @@ repeating it on every page (`null` clears it):
116
131
  update_site_settings organization={"name":"Acme Studio","logo":"<cdn_url>","same_as":["https://www.linkedin.com/company/acme"]}
117
132
  ```
118
133
 
134
+ **FAQ, recipe and event pages have tools.** They validate the input, build
135
+ the schema.org JSON-LD and merge it into the page's `json_ld` (a node of the
136
+ same type is replaced, anything else is kept). Use them instead of
137
+ hand-writing JSON-LD, and copy the content from what the page visibly shows:
138
+
139
+ ```
140
+ add_faq_schema page_id="faq" items=[
141
+ {"question": "Do you deliver on weekends?", "answer": "Yes, Saturdays 9–15."}
142
+ ]
143
+ add_recipe_schema page_id="kanelbullar" name="Kanelbullar"
144
+ ingredients=["500 g vetemjöl", "2 tsk kanel"] instructions=["Blanda degen.", "Grädda i 225 °C."]
145
+ prep_time="PT1H30M" cook_time="PT10M" recipe_yield="24 bullar" image_url="<cdn_url>"
146
+ add_event_schema page_id="sommarkonsert" name="Sommarkonsert"
147
+ start_date="2026-06-12T19:00:00+02:00" location_name="Stadshuset"
148
+ location_address="Storgatan 1, Sundsvall" offers_price=250 offers_currency="SEK"
149
+ ```
150
+
151
+ Rules they enforce: FAQ needs at least one question with an answer; a recipe
152
+ needs a name, ingredients and steps, durations are ISO 8601 (`PT30M`) and
153
+ URLs absolute; an event needs a name and an ISO 8601 `start_date` (include
154
+ the UTC offset), `end_date` not before it, and a price needs
155
+ `offers_currency`. Read the returned `warnings`: a recipe without an image or
156
+ an event without a location is valid but not eligible for Google's rich
157
+ results. Like other content writes they land in the draft — `save: true` or
158
+ `commit_working_copy` when approved.
159
+
160
+ FAQ markup only belongs on a page that visibly presents those questions and
161
+ answers; Google penalizes FAQ markup for content the page does not show.
162
+
163
+ For other types write `json_ld` yourself:
164
+
119
165
  ```
120
166
  update_page page_id="home" patch={
121
167
  "json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"LocalBusiness\",\"name\":\"Acme Studio\",\"url\":\"https://acme.se\",\"telephone\":\"+46812345\",\"address\":{\"@type\":\"PostalAddress\",\"streetAddress\":\"Drottninggatan 1\",\"addressLocality\":\"Stockholm\",\"postalCode\":\"111 51\",\"addressCountry\":\"SE\"}}"
@@ -124,16 +170,25 @@ update_page page_id="home" patch={
124
170
 
125
171
  **Important:** JSON-LD goes in the `json_ld` field as a JSON *string*
126
172
  (not a nested object). The renderer injects it inside
127
- `<script type="application/ld+json">`.
173
+ `<script type="application/ld+json">`. To keep several nodes on one page,
174
+ store them as `{"@context":"https://schema.org","@graph":[…]}` — the
175
+ `add_*_schema` tools do this for you. Read the page first: an update
176
+ replaces the whole `json_ld` value.
128
177
 
129
178
  Common schemas worth adding:
130
179
  - Homepage: `LocalBusiness` or `Organization`
131
180
  - About: `AboutPage`
132
181
  - Contact: `ContactPage`
133
182
  - Blog articles: auto-generated from `kind:"article"` + `author`
134
- - Events: `Event` with `startDate`, `location`
183
+ - FAQ, recipe and event pages: the `add_*_schema` tools above
135
184
  - Products: `Product` with `offers`
136
185
 
186
+ **Instead of the `schema_markup` workflow.** That workflow runs the model with
187
+ the Organization's own AI key; on a Site without that access it fails with
188
+ `failure_code: "ai_not_enabled"`. Don't retry it. Do the same work here: read
189
+ each published page, pick the one type it genuinely represents (or none),
190
+ apply the tool or `json_ld` above, and tell the user you did it yourself.
191
+
137
192
  ### 6. robots.txt
138
193
 
139
194
  The default robots.txt allows all crawlers. Update if needed:
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: tr-starter-design
3
+ description: Reference for the default design new Typeroll sites start with — CSS variables, spacing, radii, container width, header and footer skeletons. Read it when a site is blank or clearly follows these conventions and you need new markup or CSS to fit in; skip it for sites with their own design.
4
+ ---
5
+
6
+ # Starter design system
7
+
8
+ A reference for the *default* design that ships with new Typeroll sites.
9
+ The customer may have replaced it — always inspect the actual header partial
10
+ (`read_partial partial_id="header"`) and an existing page before assuming any
11
+ of this is in use. On a site with its own design, mirror what is there.
12
+
13
+ ## CSS variables
14
+
15
+ Colors (set in site settings `colors`; each key becomes `--color-<key>`,
16
+ `text_light` becomes `--color-text-light`):
17
+ --color-primary brand CTAs, links, accents
18
+ --color-secondary supporting brand color (rarely used)
19
+ --color-accent a third highlight (badges, callouts)
20
+ --color-background page background (the body)
21
+ --color-surface slightly raised areas (header, footer, cards)
22
+ --color-text body copy + headings
23
+ --color-text-light secondary text (captions, meta, footer fine-print)
24
+
25
+ For subtle borders/dividers that follow the text color without being heavy,
26
+ use `color-mix(in srgb, var(--color-text) 8%, transparent)` (6% for very soft).
27
+
28
+ Spacing scale:
29
+ --spacing-xs (0.25rem) --spacing-sm (0.5rem) --spacing-md (1rem)
30
+ --spacing-lg (2rem) --spacing-xl (4rem)
31
+
32
+ Layout:
33
+ --container-medium (1080px) Center page content with
34
+ `max-width: var(--container-medium); margin: 0 auto; padding: var(--spacing-md);`
35
+ --container-narrow (720px) and --container-wide (1400px) exist for prose
36
+ and wide layouts.
37
+
38
+ Radii:
39
+ --radius-sm (0.25rem) --radius-md (0.5rem) --radius-lg (1rem)
40
+
41
+ Typography (set in site settings `fonts`):
42
+ --font-heading Use for h1-h6 and brand wordmark
43
+ --font-body Default for everything else
44
+ --font-size-base (the rem baseline)
45
+
46
+ Block-mode pages get these through the blocks and named styles; reach for the
47
+ variables in custom CSS, HTML-mode pages and template markup.
48
+
49
+ ## Default header skeleton
50
+
51
+ Surface-tinted bar with a hairline bottom border. Brand text on the left
52
+ in the heading font, bold, slight negative letter-spacing. Nav on the
53
+ right. Last nav item is typically a primary CTA: `background:
54
+ var(--color-primary); color: var(--color-background); border-radius:
55
+ var(--radius-md)`.
56
+
57
+ ## Default footer skeleton
58
+
59
+ Three-column responsive grid (brand+tagline / Site links / Get in touch),
60
+ then a fine-print row with copyright + Typeroll attribution. Top border
61
+ uses the same color-mix() recipe as the header.
62
+
63
+ ## When to use this
64
+
65
+ - A brand new site, or one where the header partial still matches this
66
+ layout.
67
+ - A page or block where the customer wants something that "fits the rest
68
+ of the site" and the rest follows these conventions.
69
+
70
+ ## When NOT to use this
71
+
72
+ - The customer has a totally different design (e.g. dark mode, custom
73
+ utility classes, no CSS variables, migrated theme).
74
+ - The customer says "use this brand color" — honor their literal request
75
+ instead of substituting a CSS variable.
76
+ - Mid-edit on an existing page that doesn't follow these conventions —
77
+ match what's already there.
78
+ - Choosing a new palette or fonts is brand work (the MCP recipe `tr-brand`),
79
+ not this reference.