@typeroll/mcp-server 0.29.0 → 0.32.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.
@@ -20,13 +20,43 @@ agency) reviews each step in their terminal.
20
20
 
21
21
  ## Preconditions
22
22
 
23
+ **Run the readiness check FIRST — before touching any content:**
24
+
25
+ ```
26
+ get_migration_readiness source_url="https://oldsite.com"
27
+ ```
28
+
29
+ Pass `source_url` — that adds the checks on the site you're migrating FROM.
30
+ An old host that answers 403/429 to server-side requests is a **blocker**: the
31
+ import would produce empty pages, or pages containing the host's block page,
32
+ which reads as real content and is worse. Whether `/wp-json` answers is a
33
+ warning, since scraping is a real fallback (it just loses ACF/custom fields).
34
+
35
+ If `ready` is false, STOP and report the blockers to the user. Do not start
36
+ the import "and fix it after": every blocker is one whose failure is invisible
37
+ once the work is done, so discovering it late means redoing the expensive part.
38
+
39
+ - **Media storage** — without it, every `<img>` keeps its WordPress URL. The
40
+ new site looks perfect and is still served images by the old host. It breaks
41
+ the day the customer cancels that hosting, months later, all at once.
42
+ - **Hosting adapter** — without credentials, deploys return a job id and
43
+ publish nothing, while reporting success.
44
+
45
+ Warnings are worth relaying but don't stop you: no verification origin (the
46
+ pre-cutover parity check can't run), no AI reconstruction key, forms without a
47
+ notification address, or a target site with no design to rebuild INTO.
48
+
49
+ Then the ordinary preconditions:
50
+
23
51
  - `@typeroll/mcp-server` configured with a valid `TYPEROLL_API_KEY`.
24
52
  - The source WP site has `/wp-json` reachable (Google for "wordpress
25
53
  REST API disabled" if not — common for hardened hosts).
26
- - The Typeroll target site exists. New, blank sites with the
27
- starter design work best. If the target already has content, you
28
- must NOT clobber it always `list_pages` first and only write to
29
- slugs that don't already exist.
54
+ - The Typeroll target site exists **and already carries the design** —
55
+ settings, header/footer, one or two example pages. The migration rebuilds
56
+ old content in the NEW design; with nothing to imitate it inherits the old
57
+ site's look.
58
+ - If the target already has content, you must NOT clobber it — always
59
+ `list_pages` first and only write to slugs that don't already exist.
30
60
 
31
61
  ## Recipe
32
62
 
@@ -112,8 +142,43 @@ create_redirect from_path="/old-services" to_path="/services"
112
142
 
113
143
  Walk the inventory; for each URL: did it become a page with the same
114
144
  path? If yes, no redirect. If renamed, `create_redirect`. If
115
- intentionally dropped, mark it excluded in your notes (the customer
116
- should sign off on every dropped URL).
145
+ intentionally dropped, mark it `excluded` via `update_migration_url` (the
146
+ customer should sign off on every dropped URL).
147
+
148
+ **Use wildcards for WordPress's URL families.** A WP site's dead URLs come in
149
+ shapes, not as individuals — and the inventory only knows the ones it found,
150
+ while the old site had more (paginated archives, feeds, attachment pages). One
151
+ pattern rule retires the whole family:
152
+
153
+ | WordPress shape | Rule |
154
+ |---|---|
155
+ | Category archives | `from_path="/category/*"` → `to_path="/blogg/:splat"` (or a single landing page) |
156
+ | Tag archives | `from_path="/tag/*"` → `to_path="/blogg"` |
157
+ | Author archives | `from_path="/author/*"` → `to_path="/om-oss"` |
158
+ | Date-based permalinks | `from_path="/2019/*"` → `to_path="/blogg/:splat"` — one rule per year |
159
+ | Old post prefix → new | `from_path="/blog/:slug"` → `to_path="/artiklar/:slug"` |
160
+ | Feeds | `from_path="/feed/*"` → `to_path="/blogg"` |
161
+
162
+ Rules:
163
+
164
+ - **Trailing `*` only.** A mid-path splat (`/blog/*/comments`) is dropped
165
+ silently by Cloudflare — the platform refuses it at write time.
166
+ - **`:splat`** carries the captured remainder; **`:name`** matches exactly one
167
+ segment and can be replayed by name.
168
+ - **A pattern that would hide a live page is refused**, naming the pages. That
169
+ is the platform protecting you: redirects are applied before static files, so
170
+ `/blogg/*` would make every real article under `/blogg/` unreachable. Narrow
171
+ the prefix instead.
172
+ - **Query-string URLs can't be matched.** WP's `/?p=123` has no path to key on;
173
+ those need handling at the source (or accept the loss and mark them excluded).
174
+ - Rules are emitted most-specific-first, so a narrow rule always beats a broad
175
+ one — you can safely have `/blogg/recept/*` alongside `/blogg/*`.
176
+
177
+ Then verify against reality before anything is cut over:
178
+
179
+ ```
180
+ verify_migration_urls # after trigger_deploy
181
+ ```
117
182
 
118
183
  ### 5. Preview + review with the user
119
184