Migrar un sitio existente a Crafty
Prompt de MCP:
migrate-site. Ejecuta todo este runbook por ti y se detiene en cada punto de control para que lo confirmes. Argumentos:site_id(el sitio de destino),source(la URL del sitio antiguo, susitemap.xmlo una descripción de la exportación) y, opcionalmente,environment(por defectoproduction) yresearch(por defectoyes: también investiga la marca en la web y propone contenido que el sitio antiguo no tiene; usanopara una migración 1:1 estricta). Necesita un token concrafty:write.En Claude Code, escribe
/y eligemcp__<server>__migrate-site, donde<server>es el nombre que le diste al servidor de Crafty; otros clientes lo muestran en su menú de prompts. Si tu cliente no muestra los prompts de MCP, pide al agente que llame aget_guide migratey que lo siga.¿Rediseño en lugar de una migración 1:1? Prompt de MCP:
redesign-site. Estudia el sitio actual del cliente, sus redes sociales y lo que el resto de la web dice de él, resume su marca, tono y contenido, y propone un sitio nuevo (mapa del sitio, secciones construidas con tus tipos de bloque, textos borrador y dirección visual) antes de crear nada. Una vez que apruebes la propuesta, lo construye como borradores y nunca publica. Argumentos:website(la URL del sitio actual) y, opcionalmente,social(URLs de perfiles o usuarios),goalsysite_id(omítelo para hacer la propuesta antes de que el cliente tenga un sitio en Crafty). Necesita un token concrafty:write. Las redes sociales suelen bloquear la lectura automatizada, así que prepárate para pegar la biografía y algunas publicaciones o compartir capturas de pantalla.
Runbook para mover un sitio que ya existe (WordPress, Webflow, Wix, un sitio estático, otro CMS headless) a Crafty con un agente y el servidor MCP, sin romper sus URLs. Trabaja en este orden; cada fase tiene un punto de control donde una persona confirma antes de pasar a la siguiente.
Herramientas usadas: bulk_upsert_entries, import_media_from_urls, upsert_redirects (además de las habituales create_block_type, create_collection, create_page, publish_*). Ámbitos del token: crafty:read + crafty:write; añade crafty:publish solo para la fase final.
Reglas básicas
- Todo se guarda como borrador. Nunca pases
publish: truehasta que una persona haya revisado el contenido en el panel. dry_run: trueprimero en cada lote debulk_upsert_entriesyupsert_redirects; corrige los elementosfailedy luego ejecútalo de verdad.- Usa
external_id(el ID de la entrada o página del CMS antiguo, o la URL antigua si no hay ID) en cada entrada. Volver a ejecutar una importación actualiza en lugar de duplicar. - Lotes: hasta 100 entradas, 50 URLs de medios y 500 redirecciones por llamada. Mantén un manifiesto local (JSON/CSV) de lo que envió cada lote y de lo que devolvió (
entry_id,media_id), para poder reanudar una ejecución fallida. - Cuota de medios: las importaciones cuentan contra la cuota de medios del tenant. Importa solo lo que usan las páginas, omite miniaturas y copias redimensionadas (las variantes
-300x200.jpgde WordPress) y pregunta antes de importar más de unos cientos de archivos. - Trabaja contra el entorno
productiondel sitio de destino salvo que el usuario pida otro (las herramientas aceptanenvironment).
Fase 1 — Rastreo
Crea un inventario de cada URL del sitio antiguo:
- Fuentes, de mejor a peor: la exportación o API del CMS (REST de WordPress
/wp-json/wp/v2/posts?per_page=100&page=N,/pages,/media; o la exportación WXR),sitemap.xml(y los índices de sitemap) y, después, un rastreo de los enlaces internos desde la página de inicio. - Para cada URL registra: ruta antigua, título, tipo estimado, idioma, última modificación, contenido principal (HTML), imágenes y archivos que usa y el ID antiguo si lo conoces.
- Recopila también las URLs que ya redirigen (HTTP 301/302) y todo lo que esté en el plugin de redirecciones o en el
.htaccessdel sitio antiguo: también hay que trasladarlas. - Investiga la marca más allá de su sitio: busca su nombre en la web (perfil de Google Business y reseñas, redes sociales, prensa, directorios y marketplaces, páginas de premios o socios). Enumera lo que le falta al sitio antiguo como adiciones propuestas: reseñas y testimonios, preguntas frecuentes tomadas de las consultas de clientes, horarios, ubicaciones, servicios o productos publicados en otros lugares, premios, menciones en prensa y enlaces a redes sociales. Indica la URL de origen de cada una y qué tan seguro estás de ella, marca la información que contradiga el sitio o parezca desactualizada, y nunca inventes datos. Mantén las adiciones separadas del inventario: son propuestas, no contenido migrado. Omite este paso en una migración 1:1 estricta (el prompt
migrate-siteusaresearch: "no").
Punto de control: muestra al usuario los recuentos por tipo, las URLs que no pudiste obtener y las adiciones propuestas. Solo se añaden las adiciones que el usuario elija, en la fase 5, como borradores nuevos.
Fase 2 — Clasificar
Agrupa las URLs en:
- Páginas únicas (inicio, nosotros, contacto, páginas de aterrizaje) → páginas de Crafty construidas con tipos de bloque.
- Contenido repetitivo (entradas, noticias, productos, miembros del equipo, casos de estudio, eventos) → una colección por tipo, una entrada por elemento.
- Archivos y listados de taxonomía (
/category/x,/tag/y,/page/2, páginas de autor, archivos por fecha) → normalmente no se migran como contenido: el nuevo frontend los genera; solo necesitan redirecciones. - Basura (resultados de búsqueda, feeds, páginas de adjuntos,
?replytocom=…) → descártala; redirige a la página útil más cercana si tenía tráfico.
Decide con el usuario el nuevo esquema de URLs (por ejemplo /blog/2019/05/hello-world → /blog/hello-world) y escribe ya en el inventario la asignación de antiguo a nuevo.
Punto de control: el usuario aprueba los tipos de contenido y el esquema de URLs.
Fase 3 — Modelar
Sigue "Modelar el contenido con tipos de bloque primero" en SKILL.md:
- Inspecciona los esquemas actuales:
list_block_types,list_collections. - Para las páginas únicas,
create_block_typepor cada sección recurrente (hero, texto + imagen, tarjetas →repeater, preguntas frecuentes →repeater, CTA). Reutiliza los tipos de bloque existentes cuando encajen. - Para cada tipo repetitivo,
create_collectioncon los campos que el contenido realmente tiene:title(string),excerpt(text),body(longText, HTML),cover(reference,model: "Media"),gallery(multiReference),published_on(datetime),tags(stringList),category(select) y campos de SEO (seo_title,seo_description). Sin camposjsonpara contenido que las personas editoras mantienen. - Marca primero como público el repositorio al que irán las imágenes si el sitio necesita URLs permanentes:
manage_media_collectionconis_public: true.
Punto de control: el usuario revisa los esquemas en el panel antes de cualquier importación.
Fase 4 — Medios
- Del inventario, lista las URLs distintas de imágenes y archivos que usa el contenido migrado (solo los originales a tamaño completo).
import_media_from_urlsen lotes de hasta 50:{ site_id, urls, collection_name }. Cada resultado tienestatus(imported,existingcuando la URL ya se había importado,duplicatedentro del lote,failed) ymedia_id/original_url.- Guarda el mapa de URL antigua →
media_id/original_url. Reintenta una vez los elementosfailede informa del resto (los hosts privados, las redirecciones, los archivos demasiado grandes o de tipos no compatibles se rechazan a propósito: descárgalos localmente y usarequest_media_upload).
Fase 5 — Contenido (como borradores)
- Transforma cada elemento al esquema de la colección: limpia el HTML (elimina shortcodes del constructor, estilos en línea y píxeles de seguimiento), reescribe los enlaces internos a las rutas nuevas y reemplaza las URLs de imágenes en el HTML por los valores
original_urlde la fase 4. Pasa las referencias de medios (cover,gallery) como valoresmedia_id. bulk_upsert_entriescon{ site_id, collection_slug, entries: [{ slug, external_id, data }], dry_run: true }. Corrige cada elementofailed(los errores indican el campo, por ejemplodata.published_on: …) y revisa loswarnings(claves descartadas = un campo que falta en el esquema).- Ejecuta el mismo lote sin
dry_run. Las entradas se crean como borradores; las existentes (mismoexternal_idoslug) se actualizan con una revisión. - Escribe las adiciones que el usuario eligió en la fase 1 como borradores nuevos (sin
external_iddel sitio antiguo) y enuméralas, con sus fuentes, en el informe de revisión. - Páginas únicas:
create_pageconblocksen el idioma predeterminado; también empiezan como borradores. Los otros idiomas del sitio antiguo se añaden conconfigure_localesyupsert_translation, no como páginas adicionales.
Fase 6 — Redirecciones
- Del inventario, una redirección por cada URL antigua cuya ruta cambie:
{ source: "/old/path", destination: "/new/path", status_code: 301 }. Usa 301 para los cambios permanentes; 302/307 solo para los temporales. - Agrupa los patrones en reglas dinámicas cuando sea posible (
/category/*→/blog,/blog/:year/:month/:slug→/blog/:slug): el alojamiento de Crafty permite 2000 reglas estáticas y 100 dinámicas por despliegue, incluido el_redirectspropio del sitio. sourcedebe ser una ruta (sin dominio, sin?query, sin#fragment);destinationuna ruta o una URL absoluta http(s). No redirijas una URL a sí misma ni crees cadenas (A → B → C: apunta A directamente a C).upsert_redirectscondry_run: true, corrige losfailedy luego ejecútalo de verdad (500 por llamada). Verifica conlist_redirects.- Alojado en Crafty: se aplican en el siguiente despliegue. Frontend propio: lee
GET /api/v1/redirectsen el middleware (middleware.tsde Next.js, middleware de servidor de Nuxt) y responde con elstatus_codey la cabeceraLocation.
Fase 7 — Revisión humana
Entrega al usuario un informe breve: recuentos de creados, actualizados y fallidos por tipo; medios importados y omitidos; redirecciones creadas; y la lista de elementos que necesitan una persona (transformaciones fallidas, imágenes que faltan, páginas que no se asignaron a un tipo de bloque). Pídele que revise los borradores en el panel (y en el editor visual si está configurado). Aplica sus correcciones con update_entry / update_page, o vuelve a ejecutar el lote de importación (actualiza por external_id).
Fase 8 — Publicar y cambiar el tráfico
Solo después de la aprobación explícita del usuario:
- Publica:
bulk_upsert_entriesde nuevo conpublish: true(token concrafty:publish) opublish_entry/publish_pagepor elemento; oschedule_publicationpara una hora de lanzamiento programada. - Despliega el nuevo frontend, apunta el dominio a él y luego revisa una muestra de URLs antiguas (deben responder 301 a las nuevas) y el sitemap.
- Mantén las redirecciones: eliminarlas más adelante rompe enlaces y el posicionamiento en buscadores.
Aún no cubierto
El panel no tiene importador WXR de WordPress, importador de sitemap ni informe de enlaces rotos: el agente realiza esos pasos por sí mismo con las herramientas anteriores.