strata
Strata compone módulos backend verificados y personalizados de manera determinista en tu codebase
Documentación
Tu agente escribe el backend. Strata demuestra que funciona.
Un servidor MCP que compone módulos backend verificados en tu código — leyendo tu esquema, siguiendo tus convenciones, conectándolos en el orden que Express realmente requiere — y luego escribe un comando que arranca la aplicación y ejercita cada requisito contra un servidor en vivo.
$ # your agent calls one tool, once
strata_use dir=./shop-api task="product list API"
capabilities=[ "cursor pagination with sorting",
"per-IP rate limiting",
"structured request logging" ]
FILES CREATED
server.js
strata/lib.js — the implementation these import from
strata/verify.js — boots the app and exercises the feature end to end
$ npm install && node strata/verify.js
PASS unit selftests — 3 passed, 0 failed
PASS server boots and answers /health
PASS correlation id honours an inbound x-request-id
PASS an authorization header is NOT written to the log
PASS a password in a request BODY is NOT written to the log
PASS a malformed body is a 4xx and leaks no stack trace to the caller
PASS /items walks pages by cursor without repeating a row
PASS a sort field that is not allowlisted is REJECTED, not honoured
PASS a burst past capacity yields 429 + Retry-After
12/12 checks passed — the delivered feature works end to end.
la pregunta es si la página dos repite la página uno.
Capacidades clave
- Composición consciente del esquema — lee Prisma, Mongoose, Drizzle, TypeORM, Sequelize o JS plano y conecta módulos contra tu entidad real, campos y columna de ID
- Orden correcto del middleware — logging por encima del análisis del cuerpo, límites de tasa por encima de las rutas, manejadores de errores al final, impuesto por rango en lugar de dejarlo al modelo
- Verificador integral generado —
strata/verify.jsarranca la aplicación en un puerto libre y ejercita cada requisito contra ella - Seis puertas de admisión verificadas por máquina — ningún módulo llega a tu proyecto sin pasar todas ellas
- Rechazos honestos — rechaza aproximadamente un tercio de las tareas, donde componer cuesta más que escribir el código
$ # asked for something the library does not cover
strata_use task="slugify helper" capabilities=["convert a string to a url slug"]
No verified Strata recall covers "slugify helper". Build it from scratch the
normal way — a clean hand-written implementation is the right outcome here,
not a forced match.
y una herramienta que siempre dice sí es una herramienta en la que dejas de confiar.
- Local por construcción — tu código fuente y esquema nunca salen de la máquina; solo se envía el texto de la tarea
Los números
| sin Strata | con Strata | ||
|---|---|---|---|
| tokens | 950,011 | 319,604 | −66% |
| turnos | 31.3 | 15.0 | −52% |
| tiempo real | 190s | 63s | 3× más rápido |
| costo | $0.190 | $0.077 | −59% |
| verificaciones aprobadas | 70.8% | 100% |
Una tarea de backend — una API de productos con paginación, límite de tasa por IP y logging de solicitudes. Claude Haiku 4.5, tres ejecuciones por brazo, media. Cada número es más bajo y la calidad es más alta.
Los tokens son toda la sesión: entrada, salida y el contexto en caché releído en cada turno. En las 18 ejecuciones de esta batería, el 98–99% de los tokens de una sesión son ese contexto releído — la salida es menos del 2%. Así que la longitud de la salida no es la palanca; los turnos lo son, y menos turnos es lo mismo que menos tokens es lo mismo que menos dinero.
Qué eran realmente las verificaciones fallidas
Una puntuación es fácil de descartar. Estas son las fallas en sí, recalificadas desde los árboles archivados. Cada una es código que se ejecuta, responde 200-o-201, y parece terminado.
Una solicitud malformada devuelve tu rastreo de pila
Una solicitud con un cuerpo truncado. Ambas aplicaciones respondieron 400 — solo una de ellas es segura.
| sin Strata | con Strata |
|---|---|
HTML desde una API JSON, los internos del analizador, y rutas absolutas del sistema de archivos de tu servidor — entregados a quien envió el byte incorrecto. |
El mismo 400, en el mismo sobre que cualquier otro error, diciéndole al llamador qué corregir y nada más. |
Falló en 6 de 6 ejecuciones sin ayuda, en ambas tareas. Pasó en 6 de 6 con Strata. El calificador lo registra como LEAKS STACK TRACE; nada en la salida de la propia sesión lo menciona.
Un pedido reintentado con un cuerpo diferente fue aceptado de todos modos
POST /orders Idempotency-Key: k-1 {"items":[ A ]} → 201 Created
POST /orders Idempotency-Key: k-1 {"items":[ B ]} → 200 OK ← order A returned
Esa es la mitad sutil de la idempotencia, y la mitad que una implementación ingenua pierde por completo. El cliente pidió un pedido diferente y se le dijo que su solicitud tuvo éxito. Nada da error, nada registra. El pedido B simplemente nunca existe, y el llamador tiene un 200 que dice que existe. La respuesta correcta es 409 o 422.
Falló en 3 de 3 ejecuciones sin ayuda. Pasó en 3 de 3 con Strata.
La API ignoró el tamaño de página que se le pidió
GET /products?limit=5 → 200 OK, 10 items
Paginación que devuelve lo que le plazca. Nada da error, nada registra, y el error llega a quien consume ese endpoint. Una ejecución sin ayuda de cada tres.
El esquema de la base de datos fue editado, sin que se pidiera
La tarea era "si un cliente reintenta la misma solicitud de pedido, no debe crear dos pedidos." Nunca menciona el modelo de datos. Una ejecución sin ayuda de cada tres reescribió prisma/schema.prisma; ninguna ejecución con Strata lo tocó.
El problema más amplio es que no puedes predecir qué archivos vuelven modificados. En tres ejecuciones del mismo prompt, el brazo sin ayuda tocó seis archivos diferentes — y solo tres de ellos en cada ejecución. Strata tocó los mismos diez archivos en las tres ejecuciones: una huella idéntica, ejecución tras ejecución.
Ejecútalo tres veces. Obtén la misma respuesta tres veces.
| tarea | sin Strata | con Strata |
|---|---|---|
| API de productos | 63%, 75%, 75% | 100%, 100%, 100% |
| pedidos idempotentes | 14%, 71%, 71% | 100%, 100%, 100% |
| pagos + cola | 0%, 0%, 50% | 0%, 100%, 100% |
Cero varianza en las tareas que la biblioteca cubre. Tres ejecuciones del mismo prompt devuelven la misma puntuación, tres veces de tres — frente a una dispersión de 26.9 puntos sin ella.
Ese 14% no es un artefacto de calificación; se repite al recalificar. Esa sesión inventó una API de pedidos cuyo endpoint de creación rechazó cada forma de solicitud que se le envió, y como todo lo demás depende de crear un pedido, cinco verificaciones colapsaron a la vez. Un precipicio, no un resultado ligeramente peor — y nada en la salida de la propia sesión dice que sucedió.
Dónde no ayuda
Pagos está en el tablero con sus fallas intactas. Ambos brazos enviaron una compilación que no se ejecuta: una ejecución sin ayuda nunca escribió un punto de entrada, y una ejecución con Strata fijó bullmq@5.81.3 junto a un redis@4.7.1 incompatible, que no puede instalarse. Ambos paquetes son la elección del modelo — Strata cubre el webhook y nada más en esa tarea, y la relación de costo aterriza en 0.95×, un empate.
Esa es la regla que todo el tablero obedece: la ventaja sigue cuánto de la tarea cubre la biblioteca. Donde la cobertura es alta, los números anteriores se mantienen. Donde es una capacidad de cuatro, Strata es aproximadamente gratis y aproximadamente neutral.
Strata también rechaza directamente cuando una tarea está por debajo del punto donde componer supera a escribir — alrededor de un tercio de las veces.
Método
Las verificaciones se escribieron desde el prompt de la tarea solamente y se congelaron antes de la primera ejecución. Cada verificación tiene un control negativo que demuestra que puede fallar. La calificación es una suite separada — nunca strata/verify.js, que Strata genera y que estaría marcando su propia tarea. Cada árbol de salida está archivado.
n=3, Claude Haiku 4.5, un modelo por celda. Nada aquí habla de Sonnet u Opus. Las cifras de costo y tokens se mueven con el modelo y el prompt; las cifras de consistencia no.
Método completo, puntuaciones por ejecución y cada defecto de instrumento encontrado en el camino: docs/BENCHMARK.md.
Inicio rápido
Requisitos previos: Node.js ≥ 18 y cualquier cliente MCP — Claude Code, Cursor, Windsurf, VS Code o Claude Desktop.
// .mcp.json (or claude_desktop_config.json for Claude Desktop)
{
"mcpServers": {
"strata": { "command": "npx", "args": ["-y", "stratalib"] }
}
}
Reinicia el cliente y pide una característica de backend que necesite varias partes:
Add cursor pagination, per-IP rate limiting and request logging to the products API.
Strata lee el proyecto, compone los módulos, escribe los archivos, e imprime lo que creó y lo que modificó. Luego:
npm install && node strata/verify.js
[!NOTE] Sin clave de API y sin cuenta. Los módulos se sirven desde el hub; el texto de la tarea es lo único que se envía. Tu código fuente, esquema y archivos permanecen en tu máquina.
La herramienta
Strata registra exactamente una herramienta. Cada herramienta en un esquema MCP se factura en cada turno, así que la superficie se mantiene en una que hace todo el trabajo.
strata_use
| Argumento | Propósito |
|---|---|
dir | Ruta absoluta a la raíz del proyecto — donde se leen el esquema y las convenciones |
task | Una etiqueta corta para el trabajo |
capabilities | 3–6 frases que nombran las partes del trabajo. Tu modelo las escribe; ha leído toda la tarea |
Devuelve los archivos creados y modificados, las exportaciones disponibles de cada módulo, y el comando para verificar el resultado.
Cómo funciona
1 · Lee el proyecto — localiza el ORM y extrae la entidad real: campos, tipos, enums y la columna de ID real. Determinista, en Node, antes de que el modelo vea un byte. Donde la entidad no puede identificarse con confianza, Strata deja un espacio en lugar de adivinar.
2 · Selecciona módulos — cada frase de capacidad se puntúa contra la biblioteca, y cualquier coincidencia solo por vocabulario compartido se descarta. Menos de dos módulos supervivientes desencadena un rechazo.
3 · Compone — los módulos contribuyen a la aplicación en lugar de poseerla, cada contribución lleva un rango que fija su posición en la cadena de middleware. Una solicitud malformada lanza durante el análisis del cuerpo, así que el logging se monta por encima; invierte eso y la solicitud que más vale rastrear es la que pierde su id de correlación.
4 · Escribe el verificador — strata/verify.js ejecuta la suite propia de cada módulo, arranca la aplicación en un puerto libre, y ejercita cada requisito contra ella. Construido contra tu entidad, así que las verificaciones se ejecutan en tus campos y tus rutas.
Puertas de admisión
Cada módulo pasa seis puertas verificadas por máquina antes de poder servirse. Un módulo que falla se descarta, no se repara — parchear a mano módulos generados devuelve la cobertura al oficio y detiene su escalabilidad.
| Puerta | Requisito |
|---|---|
| Exportaciones | Carga, y cada exportación que declara se resuelve en tiempo de ejecución |
| Autoprueba | Su propia suite pasa, con un recuento de aserciones estable en cinco ejecuciones |
| Adversarial | ≥ 8 aserciones, entradas hostiles, y aserciones de que algo no debe suceder |
| Composición | Fragmentos válidos con rangos, y fábricas declaradas que existen |
| Colisiones | Ningún nombre exportado colisiona con otro módulo |
| Arranque compuesto | Se compone con otros dos en una aplicación que arranca y verifica |
La puerta adversarial es la que importa. Cada módulo escrito a mano en esta biblioteca se envió con un error real que sus propias pruebas no detectaron — un 404 que reiniciaba el contador de fallas de un interruptor de circuito, una restricción de enum eliminada, un id de solicitud controlado por el atacante reflejado en un encabezado de respuesta. Una suite confirmatoria admite exactamente esos.
Diseño del repositorio
| Ruta | Contenido |
|---|---|
src/ | Servidor MCP: lectura de proyecto, selección, composición, generación de verificador |
bin/ | Punto de entrada CLI |
templates/ | Esqueleto Express usado durante la composición |
benchmark/ | Suites de verificación pre-registradas, controles negativos, registros de ejecución y árboles de salida archivados |
scripts/ | Puertas de admisión, indexación de biblioteca, pruebas de selección |
Los módulos se sirven desde el hub; el texto de la tarea es lo único que se envía. Tu código fuente, esquema y archivos permanecen en tu máquina.
Documentación
| Documento | Tema |
|---|---|
docs/BENCHMARK.md | El benchmark completo: método, puntuaciones por ejecución, y cada defecto de instrumento encontrado |
CHANGELOG.md | Qué se envió en cada versión |
Desarrollo
npm install
node --max-old-space-size=8192 node_modules/typescript/bin/tsc -p tsconfig.mcp.json # build
node scripts/admit-recall.js recalls/<domain>/<name>/v1 # run the gates
node benchmark/quality/negative-control.js # prove the checks can fail
node benchmark/run-quality-battery.js --tasks catalog --max 3 # collect runs
STRATA_MODE=local se compone contra un checkout local de recalls/ en lugar del hub — requerido al probar un módulo que no ha sido desplegado.
Agradecimientos
Construido sobre el Protocolo de Contexto de Modelos, Express, Prisma, Mongoose, Drizzle, TypeORM y Sequelize.
Licencia
AGPL-3.0-o-posterior. Ver LICENSE.