Todos los recursos

Dejar que un modelo escriba tu migración de esquema no tiene nada de malo; dejar que la aplique directo a producción es la forma perfecta de arruinarte un sábado. El servidor MCP de Supabase le da a Claude una rama de base de datos donde trabajar (diseña, aplica, revisa los advisors y después haces merge) para que una respuesta tan equivocada como segura de sí misma le caiga a una copia desechable y no a tus tablas en producción.

MCP de Supabase para migraciones seguras por rama

En resumen

  • El servidor expone un set acotado de tools: listar tablas, generar tipos, crear/fusionar/resetear ramas, aplicar migraciones y leer logs y advisors.
  • La clave de todo es la rama: una copia aislada de tu base de datos donde una migración mala se borra y se reintenta, en vez de convertirse en un incidente.
  • Déjalo en --read-only por defecto; quítalo solo para trabajar en una rama, y limita el access token a un solo proyecto, nunca a toda la organización.
  • Correr get_advisors después de cada migración atrapa lo que los modelos pasan por alto: políticas RLS que faltan y foreign keys sin índice.
  • El orden que funciona: create_branch → apply_migration → get_advisors → merge_branch. Si algo sale mal, resetea o borra la rama.

Las migraciones de esquema son el único terreno donde una respuesta equivocada y muy segura de un modelo no sale gratis. Es una columna que borraste un martes por la tarde, con tres minutos de downtime y sin un rollback limpio. El servidor MCP de Supabase no arregla al modelo, sino el radio de daño: le da a Claude una rama de base de datos real donde trabajar, así la migración que escribe cae primero en una copia desechable. La diseñas con el modelo, la aplicas en la rama, lees las advertencias de los advisors y solo entonces haces merge a producción. Aquí va el setup, los guardarraíles y el orden exacto con que lo hago.

01 · Qué expone realmente el servidor

El servidor MCP de Supabase es un plugin de mantenimiento oficial que conecta a Claude con tu proyecto de Supabase a través del Model Context Protocol. No le da al modelo acceso directo a la base de datos. Expone un set acotado de tools, donde cada una es una acción tipada y con nombre que el modelo puede invocar. Las que importan para trabajar con migraciones:

  • list_tables y list_extensions: leer el esquema actual antes de proponer un cambio. El modelo nunca debería escribir una migración a ciegas.
  • generate_typescript_types: generar tipos directo del esquema en vivo, para que tu código de app y tu base de datos dejen de desincronizarse.
  • create_branch, list_branches, merge_branch, reset_branch, rebase_branch, delete_branch: el ciclo de vida de la rama. Esta es la parte que hace que todo sea seguro.
  • apply_migration: correr una migración DDL versionada y con nombre. Este es el camino de escritura, y es el que controlas con más cuidado.
  • execute_sql: correr SQL arbitrario. Útil para lecturas y arreglos de datos; peligroso como camino de escritura porque nada queda registrado como migración.
  • list_migrations: ver qué ya se aplicó, para que el modelo construya sobre el historial en vez de pelearse con él.
  • get_advisors y get_logs: el ciclo de feedback. Los advisors marcan problemas de seguridad y rendimiento; los logs te dicen por qué falló la última llamada.

El modelo mental es este: apply_migration es para el esquema, execute_sql para todo lo demás y get_advisors es el revisor que corre después de ambos. Saber qué hace cada tool es media batalla ganada, porque si lo dejas, el modelo va a echar mano de execute_sql para hacer trabajo de esquema, y entonces tu cambio existe en la base de datos pero no en tu historial de migraciones.

Nota

Las migraciones versionadas y el SQL ad-hoc no son intercambiables. Un cambio de esquema aplicado con execute_sql funciona una vez y después desaparece de tu historial. La próxima rama no lo va a tener. Mantén el DDL en apply_migration para que cada entorno se pueda reconstruir desde la misma lista ordenada.

02 · Setup: token, alcance, config

Necesitas un personal access token de Supabase. Genéralo desde la configuración de tu cuenta y trátalo como la credencial de producción que es. Quien lo tenga puede actuar sobre tus proyectos.

La decisión más importante del setup es el alcance. El servidor acepta un flag --project-ref que lo amarra a un solo proyecto. Úsalo. Sin él, todo el alcance del token queda expuesto, y "el modelo solo tocó el proyecto que yo quería" deja de ser un hecho y pasa a ser una ilusión.

Esta es la config que uso en un proyecto de Claude Code. Fíjate en los flags. Son el guardarraíl, no un adorno:

{
  "mcpServers": {
    "supabase": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase@latest",
        "--read-only",
        "--project-ref=your_project_ref"
      ],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here"
      }
    }
  }
}

Dos flags cargan con todo el peso:

  1. --read-only limita a solo lectura el rol de base de datos que usa el servidor. Mientras está activo, no puede entrar ninguna migración ni ninguna escritura, punto. El modelo explora todo lo que quiera y no rompe nada. Este es tu estado por defecto.
  2. --project-ref amarra cada llamada a un solo proyecto. Un token llega a toda tu organización; este flag dice "solo este".

Atención

Nunca pongas un token en texto plano en un archivo que podrías subir al repo. Mantén SUPABASE_ACCESS_TOKEN en una variable de entorno o en un manejador de secretos, y confirma que el archivo esté en el gitignore antes del primer commit. Un token de Supabase filtrado es acceso directo a tus datos. No hay un segundo factor entre él y tus tablas.

Para el día a día de exploración ("cómo se ve el esquema", "genérame los tipos", "por qué esta query es lenta") deja --read-only activo y ni te acuerdes de él. Solo lo quitas a propósito, para trabajar en una rama, y lo vuelves a poner apenas terminas.

03 · La rama es la clave de todo

Una rama de Supabase es una base de datos separada y efímera que copia el esquema de tu proyecto. Es la diferencia entre que una migración sea una tarea de rutina o un riesgo. El trabajo ocurre en la rama; producción queda intacta hasta que tú decidas otra cosa.

El orden que sigo, siempre:

  1. create_branch: levanta una copia aislada. Ahora el modelo tiene un lugar donde equivocarse sin consecuencias.
  2. apply_migration: aplica el DDL en la rama. Si el modelo se equivocó en el tipo de la columna u olvidó una restricción, aquí te enteras, en una base de datos de la que no depende nadie.
  3. get_advisors: corre el revisor contra el nuevo estado de la rama. Más sobre esto abajo; no es negociable.
  4. merge_branch: una vez que la migración aplica limpio y los advisors no se quejan, promuévela a producción.

Si el paso 2 o 3 se tuerce, no tienes que hacer rollback de producción porque producción nunca cambió. Haces reset_branch para botar el trabajo y empezar de cero, o delete_branch y listo. El costo de un error baja de "incidente" a "borrar y reintentar", y ese solo cambio es lo que vuelve razonable dejar que un modelo se acerque a tu esquema.

// El orden que corro con el modelo, en palabras simples:
// 1. create_branch        -> copia aislada del esquema
// 2. apply_migration      -> el DDL cae solo en la rama
// 3. get_advisors         -> revisión de RLS + índices del nuevo estado
// 4. merge_branch         -> promover a producción
// Si hay problema: reset_branch (rehacer) o delete_branch (abandonar).

Una concesión honesta: las ramas no son gratis ni instantáneas. Para agregar un índice de una sola línea quizás juzgues que la ceremonia pesa más que el riesgo y lo apliques directo, con --read-only quitado y tus propios ojos sobre el SQL. Perfecto, pero que sea una decisión consciente, no el default. La rama es para todo lo que no puedas revertir cómodamente a mano.

04 · Los advisors atrapan lo que al modelo se le escapa

Este es el patrón que se gana el sueldo. Los modelos escriben migraciones que funcionan. La tabla se crea, la columna se agrega, la query corre. Lo que se saltan sin avisar es el andamiaje de seguridad y rendimiento que hace que el esquema esté listo para producción. Están optimizando para "el DDL no falla", y una migración puede no fallar y aun así dejarte expuesto de par en par.

get_advisors es justo el chequeo contra eso. Después de cada migración, córrelo en la rama y lee los resultados antes de hacer merge. Las dos clases de fallo que más atrapa:

  • Políticas RLS que faltan. Una tabla nueva con row-level security desactivado, o activado pero sin ninguna política, queda o totalmente abierta o totalmente cerrada, y las dos están mal. En Supabase, donde las tablas son alcanzables desde el cliente, una tabla expuesta sin RLS es una fuga de datos esperando a que alguien se dé cuenta. El modelo crea la tabla y sigue de largo; el advisor no te lo deja pasar.
  • Foreign keys sin índice. El modelo agrega una foreign key y se olvida del índice que va detrás. Funciona bien con tus diez filas de prueba y se degrada feo cuando crece, y te enteras meses después, cuando un join se vuelve cuadrático. El advisor lo marca ahora, cuando arreglarlo es una línea más en la misma migración.

Importante

Trata get_advisors como una compuerta obligatoria, no como un opcional. Todo el flujo de ramas existe para darte ese momento de atrapar estas cosas antes de que lleguen a producción. Saltarte la lectura del advisor desperdicia ese momento, y entonces es como si hubieras aplicado directo a producción.

Cuando el advisor marca algo, el arreglo normalmente va en la misma migración: agrega la sentencia enable row level security, escribe la política, crea el índice. Aplica la migración corregida a la rama, corre los advisors de nuevo, y haz merge solo cuando vuelva limpio.

05 · Fallos que sí te vas a topar

Ninguno de estos es raro. Cada uno va a aparecer si usas el servidor en serio.

  1. Cambio de esquema por execute_sql. El modelo usa execute_sql para alterar una tabla porque es el camino de menor resistencia. El cambio funciona en la rama, pero después no queda en tu historial de migraciones, así que la próxima rama no lo va a tener y tus entornos se desincronizan. Dirige el DDL a apply_migration; reserva execute_sql para lecturas y arreglos de datos.
  2. Hacer merge con un apply en verde pero un advisor en rojo. La migración aplicó limpio, así que parece que ya está, pero los advisors marcaron una política RLS faltante que no leíste. Integras un hueco directo a producción. Lee los advisors antes de cada merge, sin excepción.
  3. El token tiene demasiado alcance. Sin --project-ref, una llamada confundida o mal dirigida cae en el proyecto equivocado. Fija el project ref y eliminas la posibilidad por completo.
  4. Olvidar que --read-only quedó quitado. Lo quitaste para trabajar en una rama, terminaste y lo dejaste quitado. La próxima sesión de exploración ya puede escribir. Haz que volver a ponerlo sea parte de cerrar la tarea.
  5. Rama atascada. Una migración a medio aplicar o en conflicto deja la rama en un estado que no puedes fusionar. No pelees con eso. Usa reset_branch para limpiarla, o delete_branch y crea una nueva. La rama es desechable; ese es su propósito.

Consejo

Cuando una llamada falla, echa mano de get_logs antes de volver a correr nada. Una migración fallida normalmente deja un error específico de Postgres en los logs (una violación de constraint, un type mismatch, un choque de nombres) y leerlo una vez le gana a dejar que el modelo adivine y reintente hasta dejar la rama atascada.

06 · Cuándo recurrir a él (y cuándo no)

Vale la pena conectar este servidor cuando iteras sobre el esquema lo bastante seguido como para que "el modelo lo escribe, la rama lo aguanta, el advisor lo revisa, tú fusionas" le gane a hacer cada paso a mano. A mí me ha pasado en proyectos como la CME Platform, donde el esquema no paraba de moverse y el flujo de ramas convirtió las migraciones de una operación con la respiración contenida en algo de rutina.

Es exagerado cuando tu esquema es estable y lo tocas dos veces al año. A ese ritmo, escribir tú mismo la migración y aplicarla con el CLI de Supabase bajo tu propia revisión es más simple que montar un loop manejado por un modelo. Y para cualquier cosa de verdad irreversible contra datos de producción, deja a una persona leyendo el diff antes del merge. La rama protege tu esquema; no protege datos que borras a propósito.

Usado así, el servidor MCP de Supabase es un buen ejemplo de cómo debería verse un plugin bien hecho: un set de tools acotado y bien descrito, una postura --read-only segura por defecto, una credencial limitada al proyecto y un flujo que enruta cada cambio riesgoso por una copia aislada, con una revisión obligatoria antes de que llegue a algo que importa. Deja que el modelo escriba; tú mantén el radio de daño dentro de una rama.

Puntos clave

  • El servidor MCP de Supabase no arregla al modelo, sino el radio de daño: le da a Claude una rama para que una migración mala se borre y se reintente, en vez de volverse un incidente.
  • Déjalo en --read-only por defecto y quítalo solo para trabajar en una rama; fija --project-ref para que el token no pueda actuar sobre el proyecto equivocado, y nunca lo subas al repo.
  • Mantén los cambios de esquema en apply_migration para que queden versionados; reserva execute_sql para lecturas y arreglos de datos que no tienen por qué estar en tu historial de migraciones.
  • Corre get_advisors después de cada migración y antes de cada merge. Atrapa las políticas RLS que faltan y las foreign keys sin índice que los modelos dejan atrás.
  • Úsalo cuando iteras sobre el esquema seguido; para un esquema estable o cualquier cosa irreversible contra datos reales, sale más simple una migración por CLI revisada por una persona.

Preguntas frecuentes

¿La rama también copia mis datos de producción, o solo el esquema?

Las ramas son sobre el esquema, no un clon completo de los datos. Obtienes una base de datos aislada que refleja la estructura de tu proyecto, para que una migración se aplique y se revise por separado, que es justo lo que quieres para probar DDL. No la veas como una manera de experimentar tranquilo sobre una copia de datos reales de clientes; velo como un lugar seguro donde aterrizar un cambio de esquema antes de que toque producción.

¿Por qué usar apply_migration en vez de execute_sql para un cambio de esquema?

Porque apply_migration registra el cambio como una migración versionada y con nombre, y execute_sql no. Un cambio DDL corrido por execute_sql funciona una vez y después desaparece de tu historial. La próxima rama no lo va a tener y tus entornos se desincronizan. Mantén el esquema en apply_migration para que cada entorno se pueda reconstruir desde la misma lista ordenada, y reserva execute_sql para lecturas y arreglos de datos puntuales.

¿Qué revisa realmente get_advisors, y por qué es obligatorio?

Corre chequeos de seguridad y rendimiento contra tu esquema. Los dos que más atrapa son las políticas RLS que faltan (una tabla alcanzable desde el cliente sin row-level security es una fuga de datos) y las foreign keys sin índice, que funcionan bien con filas de prueba y se degradan feo cuando crece. Los modelos escriben migraciones que funcionan pero se saltan ese andamiaje, así que correr los advisors después de cada migración y antes de cada merge es el momento en que atrapas el hueco antes de que lo descubra producción.

¿Basta con --read-only para mantener segura mi base de datos de producción?

Es el default que evita que las sesiones del día a día escriban algo, pero no es toda la historia. Combínalo con --project-ref para que el token no pueda actuar sobre el proyecto equivocado, mantén el access token fuera de cualquier archivo que se suba al repo, y acuérdate de volver a poner --read-only después de trabajar en una rama. El flag te protege mientras está activo; la disciplina está en asegurarte de que lo esté siempre que no estés aplicando a propósito una migración ya revisada.

Mi rama quedó en un estado que no puedo fusionar. ¿Y ahora qué?

No pelees con eso. La rama es desechable, que es justamente la idea. Lee get_logs primero para entender el error de Postgres que la dejó atascada, luego usa reset_branch para limpiar la rama y reaplicar tu migración desde cero, o delete_branch y crea una nueva. Gastar esfuerzo en reparar una rama con bisturí normalmente cuesta más que empezar de nuevo en una copia de la que no depende nada.

¿Cuándo este servidor es demasiado para mi proyecto?

Cuando tu esquema es estable y lo cambias un par de veces al año. A ese ritmo, escribir tú mismo la migración y aplicarla con el CLI de Supabase bajo tu propia revisión es más simple que montar un loop de ramas manejado por un modelo. El servidor se gana su lugar cuando iteras sobre el esquema seguido, y aun así, deja a una persona leyendo el diff para cualquier cosa irreversible contra datos reales.

¿Prefieres que lo hagamos por ti?

Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.

Escríbenos por WhatsApp

Escríbenos por WhatsApp

Escanéalo con tu teléfono para escribirnos por WhatsApp.

Escanéalo con tu teléfono para escribirnos por WhatsApp.

¿Estás desde el teléfono y no puedes escanear? Escríbenos a info@ilustrari.com

Primera conversación gratis. Te responde el fundador.

Recursos relacionados