@typeroll/mcp-server 0.45.44 → 0.45.46
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/AGENTS.md +186 -38
- package/README.md +83 -20
- package/dist/bundled-content.js +8 -7
- package/dist/client.js +15 -1
- package/dist/compact-tools.js +1 -1
- package/dist/server.js +59 -3
- package/dist/tools/access.js +75 -0
- package/dist/tools/block-types.js +110 -62
- package/dist/tools/domain.js +33 -0
- package/dist/tools/email.js +69 -0
- package/dist/tools/extensions.js +131 -0
- package/dist/tools/forms.js +20 -3
- package/dist/tools/media.js +12 -0
- package/dist/tools/pages.js +1 -1
- package/dist/tools/partials.js +1 -1
- package/dist/tools/reusable-blocks.js +1 -1
- package/dist/tools/settings.js +20 -10
- package/dist/tools/sites.js +25 -3
- package/dist/tools/versions.js +21 -3
- package/dist/tools/workflows.js +61 -0
- package/dist/tools/working-copy.js +62 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/README.md +1 -0
- package/skills/tr-custom-blocks.md +104 -0
- package/skills/tr-forms.md +18 -4
- package/skills/tr-migrate-wp.md +7 -3
- package/skills/tr-new-site.md +3 -1
- package/skills/tr-redesign-branch.md +15 -1
- package/skills/tr-seo.md +14 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tr-custom-blocks
|
|
3
|
+
description: Use when a Typeroll site needs a block the core library does not have (an icon list, cards, steps, a team strip), so the user wants a reusable block type with its own fields.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Build a site block type
|
|
7
|
+
|
|
8
|
+
A site block type is reusable: editors place it and fill in its fields, and
|
|
9
|
+
every instance updates when the type changes. Build one when the same section
|
|
10
|
+
shape recurs, or when editors should fill in fields rather than arrange
|
|
11
|
+
blocks. For a one-off section use plain blocks; for a section copied and then
|
|
12
|
+
adapted per page use a block template; for content that must be identical
|
|
13
|
+
everywhere use a global block.
|
|
14
|
+
|
|
15
|
+
Creating, changing and deleting block types needs admin permission. A changed
|
|
16
|
+
block type reaches the live site with the next deploy.
|
|
17
|
+
|
|
18
|
+
## 1. Look before you build
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
list_block_types # core and site types: maybe it exists
|
|
22
|
+
list_block_type_starters # icon_list, feature_cards, steps
|
|
23
|
+
list_styles # the site's named styles to use inside
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Prefer a starter or a core block with the right settings over a new type.
|
|
27
|
+
|
|
28
|
+
## 2. Compose it from existing blocks
|
|
29
|
+
|
|
30
|
+
Composed is the default. Declare the editable fields in `schema` and build the
|
|
31
|
+
markup from core blocks in `composition`:
|
|
32
|
+
|
|
33
|
+
- An inner block field set to exactly `"{{props.name}}"` takes the block's
|
|
34
|
+
field value. Bindings keep their type (lists, links, booleans).
|
|
35
|
+
- For a repeating group, add a `core/repeater` with
|
|
36
|
+
`items: "{{props.items}}"`, `source_type: "static"` and no `item_block`. Its
|
|
37
|
+
children render once per item and read the item with `"{{item.title}}"`.
|
|
38
|
+
- Make a whole item a link with a `core/container`
|
|
39
|
+
`{ tag: "a", href: "{{item.link.href}}", new_tab: "{{item.link.new_tab}}" }`.
|
|
40
|
+
Items without a link render as a plain container.
|
|
41
|
+
- Use `core/text` for values from text fields (always escaped), `core/heading`
|
|
42
|
+
for headings, `core/icon`, `core/image`, `core/button`.
|
|
43
|
+
- Give inner blocks named styles (`style_id`) instead of CSS where you can.
|
|
44
|
+
|
|
45
|
+
Field types: `text`, `textarea`, `richtext`, `image`, `icon` (`{name}_svg`),
|
|
46
|
+
`link` (`{ page_id }` or `{ url }` plus `new_tab`; resolves to `href`, `target`,
|
|
47
|
+
`rel` and follows page renames), `select` with `options`, `boolean`, `number`,
|
|
48
|
+
`array` (`fields`, `item_label`, `min_items`, `max_items`), `object`.
|
|
49
|
+
|
|
50
|
+
## 3. Check and preview before saving
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
validate_block_type definition={…} # problems with paths, e.g. /schema/0/fields/1/name
|
|
54
|
+
preview_block_type definition={…} # html + css with sample data, as published
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Fix every error. Read warnings: a binding inside other text
|
|
58
|
+
(`"Call {{props.phone}}"`) is shown as typed; only whole-value bindings resolve.
|
|
59
|
+
|
|
60
|
+
## 4. CSS
|
|
61
|
+
|
|
62
|
+
`styles` apply only inside the block: selectors are prefixed automatically,
|
|
63
|
+
`:scope` is the block element, and `html`, `body` and `:root` are refused. Use
|
|
64
|
+
`var(--color-primary)` and the site's spacing, not fixed colours, and keep text
|
|
65
|
+
at WCAG AA contrast.
|
|
66
|
+
|
|
67
|
+
## 5. Create, place, deploy
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
create_block_type name="icon_list" label="Icon list" category="content" schema=[…] composition=[…] styles="…"
|
|
71
|
+
add_block page_id=<id> block={ type: "icon_list", data: { items: [ … ] } }
|
|
72
|
+
get_preview_link page_id=<id>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Show the preview to the user. Deploy only when they approve.
|
|
76
|
+
|
|
77
|
+
## Template block types (advanced)
|
|
78
|
+
|
|
79
|
+
When the markup cannot be built from blocks, use `template` instead of
|
|
80
|
+
`composition`: `{{field}}` (escaped), `{{{richtext_field}}}`, `{{#field}}…{{/field}}`,
|
|
81
|
+
`{{^field}}…{{/field}}` (empty), `{{#each items}}…{{/each}}` with `{{@index}}`,
|
|
82
|
+
`{{@number}}`, `{{@first}}`, `{{@last}}`, and `{{#link field class="x"}}…{{/link}}`.
|
|
83
|
+
A type has a composition or a template, never both.
|
|
84
|
+
|
|
85
|
+
## Changing a type in use
|
|
86
|
+
|
|
87
|
+
- Rename a field with `renames: { "old": "new" }` (`"items.old": "new"` inside a
|
|
88
|
+
group): Typeroll moves the data everywhere the type is used.
|
|
89
|
+
- Removing or retyping a field that holds data is refused with the list of
|
|
90
|
+
usages unless you send `confirm_data_loss: true`. Ask the user first.
|
|
91
|
+
- `find_pages_using_block_type` before deleting; a type in use cannot be
|
|
92
|
+
deleted.
|
|
93
|
+
|
|
94
|
+
## Pitfalls
|
|
95
|
+
|
|
96
|
+
- Pasting HTML into a `core/html` block inside a composition: editors cannot
|
|
97
|
+
edit it and it skips the site's styles. Compose from real blocks.
|
|
98
|
+
- Binding a text field into `core/prose`: the value becomes HTML. Use `core/text`.
|
|
99
|
+
- Nesting links: an icon or button with its own link inside a linked container.
|
|
100
|
+
- Linked containers on a site below render version 4: every icon sits in a
|
|
101
|
+
link of its own, so the icon list starter nests links, and an item without
|
|
102
|
+
an address is still a link. The write warns; upgrade the site's rendering
|
|
103
|
+
(`tr-upgrade-rendering`) first.
|
|
104
|
+
- Writing `script` without the user's explicit request.
|
package/skills/tr-forms.md
CHANGED
|
@@ -112,8 +112,19 @@ update_form form_id=contact patch={ actions: [
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
A webhook needs `url` (https), an explicit `fields` allowlist and a signing
|
|
115
|
-
`secret`; send the masked value back to keep a stored secret.
|
|
116
|
-
|
|
115
|
+
`secret`; send the masked value back to keep a stored secret.
|
|
116
|
+
`get_form_capabilities` lists every action type the site offers, including
|
|
117
|
+
types from installed apps, with the config fields each one takes.
|
|
118
|
+
|
|
119
|
+
Email actions send through the site's email provider. Check it with
|
|
120
|
+
`get_email_settings`; if `email` is null, connect one with `set_email_settings`
|
|
121
|
+
(for example `type: "postmark"`, `from`, `config: { server_token }`) and confirm
|
|
122
|
+
with `send_test_email`. Without a provider, submissions are stored but nobody is
|
|
123
|
+
notified. These tools need admin permission, like Settings → Email & notifications.
|
|
124
|
+
|
|
125
|
+
`list_form_submissions` reads what visitors sent, `read_form_submission` reads
|
|
126
|
+
one entry (admins also see webhook delivery status) and `delete_form_submission`
|
|
127
|
+
removes one.
|
|
117
128
|
|
|
118
129
|
## Verify
|
|
119
130
|
|
|
@@ -121,8 +132,11 @@ reads what visitors sent.
|
|
|
121
132
|
2. Preview the page and confirm the authoring reference has expanded to a form
|
|
122
133
|
with `data-tr-form-el`, a signed token, and the platform runtime.
|
|
123
134
|
3. Submit a test entry and confirm it appears in Forms → Submissions.
|
|
124
|
-
4. If a webhook is configured, confirm its delivery status
|
|
125
|
-
system's idempotency key before
|
|
135
|
+
4. If a webhook is configured, confirm its delivery status
|
|
136
|
+
(`read_form_submission`) and the receiving system's idempotency key before
|
|
137
|
+
deploying.
|
|
138
|
+
5. If an email action is configured, confirm `get_email_settings` shows a
|
|
139
|
+
provider and the test message arrived.
|
|
126
140
|
|
|
127
141
|
## Common patterns
|
|
128
142
|
|
package/skills/tr-migrate-wp.md
CHANGED
|
@@ -19,9 +19,13 @@ Its shared evidence record is required for visual acceptance.
|
|
|
19
19
|
> `trigger_deploy`. Preview your drafts with `include_working_copy: true`.
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
The platform's
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
The platform's migration workflow is the "managed" path for customers who
|
|
23
|
+
want one-click. It runs on the server and is also available to you:
|
|
24
|
+
`start_workflow type="migration" config={ wp_url }` on an existing site, or
|
|
25
|
+
`create_site_and_migrate` (organization key) for a new one; poll `get_workflow`
|
|
26
|
+
and approve its review gate only with the user's consent. This skill is the
|
|
27
|
+
"power-user" path: you do it locally, mix data sources freely, and the user
|
|
28
|
+
reviews each step in their terminal.
|
|
25
29
|
|
|
26
30
|
## Preconditions
|
|
27
31
|
|
package/skills/tr-new-site.md
CHANGED
|
@@ -32,7 +32,9 @@ wrapper. Load only the relevant guide section and recipe. Discover site apps wit
|
|
|
32
32
|
read_app_documentation when needed; do not bundle private app guides locally.
|
|
33
33
|
|
|
34
34
|
No Site yet? Use hosted MCP with an Organization key and create_site, or create it
|
|
35
|
-
in the portal.
|
|
35
|
+
in the portal. To start from an AI site plan instead of a blank Site, use
|
|
36
|
+
create_site_and_plan, poll get_workflow and approve its structure review only
|
|
37
|
+
with the user's consent. Read back its ID before editing. Use one explicit Site/Version for
|
|
36
38
|
related operations. Larger changes to an existing site should use a branch.
|
|
37
39
|
|
|
38
40
|
Before importing content or a media library, require get_import_readiness to pass.
|
|
@@ -245,6 +245,15 @@ compiled output or merge. Wait for an explicit "looks good, ship it."
|
|
|
245
245
|
|
|
246
246
|
### 7. Merge + deploy
|
|
247
247
|
|
|
248
|
+
Before asking for sign-off, summarise exactly what will land:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
diff_version version_id="<branch>" # added / modified / deleted per collection
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Then, once approved (creating and merging branches need site admin
|
|
255
|
+
permission):
|
|
256
|
+
|
|
248
257
|
```
|
|
249
258
|
merge_branch version_id="<branch>" # branch's diffs land on main
|
|
250
259
|
trigger_deploy
|
|
@@ -274,7 +283,12 @@ disk cost is tiny.)
|
|
|
274
283
|
the DB, reflects edits on reload); deploy only for the compiled static
|
|
275
284
|
output or merge (steps 6–7).
|
|
276
285
|
- **Auto-merge.** Don't `merge_branch` without explicit user sign-off.
|
|
277
|
-
Once merged, the only undo is another branch + reverse edits
|
|
286
|
+
Once merged, the only undo is another branch + reverse edits (or
|
|
287
|
+
restoring individual saved states with `restore_page_revision` /
|
|
288
|
+
`restore_partial_revision` on main).
|
|
289
|
+
- **Starting over.** To abandon a direction but keep the branch and its
|
|
290
|
+
address, `reset_version version_id="<branch>"` discards every change on it
|
|
291
|
+
(check `diff_version` and ask first); `delete_branch` removes it entirely.
|
|
278
292
|
- **Header rewrites that drop the brand block.** Even when the
|
|
279
293
|
redesign is dramatic, preserve the brand mark + the nav skeleton
|
|
280
294
|
unless the user said to redo them.
|
package/skills/tr-seo.md
CHANGED
|
@@ -97,11 +97,25 @@ batch_update_pages updates=[
|
|
|
97
97
|
OG image dimensions: 1200×630px ideal. The platform doesn't resize —
|
|
98
98
|
use a correctly-sized source image.
|
|
99
99
|
|
|
100
|
+
For pages without their own image, set a site-wide fallback and the X/Twitter
|
|
101
|
+
handle (admin permission, as in the portal Settings form):
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
update_site_settings default_og_image="<cdn_url>" twitter_handle="@acmestudio"
|
|
105
|
+
```
|
|
106
|
+
|
|
100
107
|
### 5. Add structured data (JSON-LD)
|
|
101
108
|
|
|
102
109
|
Typeroll auto-generates Article and Page schema, but you can override or
|
|
103
110
|
extend with custom JSON-LD per page. Example: LocalBusiness on the homepage.
|
|
104
111
|
|
|
112
|
+
The site-wide Organization schema comes from settings — set it once instead of
|
|
113
|
+
repeating it on every page (`null` clears it):
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
update_site_settings organization={"name":"Acme Studio","logo":"<cdn_url>","same_as":["https://www.linkedin.com/company/acme"]}
|
|
117
|
+
```
|
|
118
|
+
|
|
105
119
|
```
|
|
106
120
|
update_page page_id="home" patch={
|
|
107
121
|
"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\"}}"
|