Guías
Agentes de código
Un agente que escribe tu app también escribe el texto que lleva dentro. Hay tres formas de darle el ciclo, y responden a preguntas distintas: correr los comandos, aprender las reglas o leer la documentación.
Tres canales, tres preguntas
| Canal | Qué resuelve | Qué necesita |
|---|---|---|
| Servidor MCP | Correr el ciclo: diagnosticar, envolver el texto que ya escribiste, extraer, traducir | Una línea en tu cliente MCP |
| Agent Skill | Escribir bien el código a la primera: las reglas que mantienen el ciclo seguro | Un archivo copiado a tu proyecto |
| llms.txt | Encontrar la página correcta: un índice de esta documentación en markdown | Nada, ya se sirve solo |
Se apilan. La skill enseña las reglas, el servidor hace el trabajo y el índice es lo que un agente lee cuando necesita más que cualquiera de los dos. Ninguno puede aprobar una traducción de máquina, y el final de esta página dice por qué.
El servidor MCP
@verbaly/mcp expone el ciclo como herramientas sobre el Model Context Protocol, así que un agente lo corre sin tocar una terminal. Funciona con cualquier cliente MCP, Claude Code y Cursor incluidos.
El servidor lee tu verbaly.config desde el directorio donde arranca. Pasa --root cuando ese no sea tu proyecto, y además cada herramienta acepta su propio root para un monorepo con más de una app.
Las herramientas
Van en el orden en que un agente se encuentra un proyecto: montarlo, averiguar qué falla, envolver el texto que ya está, y recién entonces correr el ciclo sobre él. Ese es el orden en que el servidor las entrega, no solo el de esta página.
| Herramienta | Qué hace | ¿Escribe? |
|---|---|---|
| verbaly_init | Crea tu fichero de ajustes y tus ficheros de idioma, y averigua qué bundler o framework usas para poder decirte la única línea que aún tienes que añadir. Un idioma que le das como pt_BR lo escribe pt-BR, y lo dice | Sí |
| verbaly_doctor | Revisa todo el montaje de una vez: configuración, catálogos, el plugin de tu framework, los tipos generados, los archivos que no pudo leer y cada traducción que el gate rechazaría | No |
| verbaly_wrap | Encuentra el texto escrito directamente en tu JSX y lo envuelve para que el compilador pueda tomarlo. Por defecto solo informa, y el texto que no puede tratar con seguridad lo lista en vez de reescribirlo | Sí |
| verbaly_extract | Escanea tu código, añade los mensajes nuevos a los catálogos y regenera los tipos. Una clave que poda se lleva su borrador, y la respuesta nombra, con archivo y línea, cualquier archivo que no pudo leer, cualquier clave escrita con dos textos, cualquier t que no puede leer porque tiene otro nombre, cualquier texto fuente que tu código reemplazó y cualquier valor que un traductor vería sin nombre. Cuando crea verbaly.lock, mueve a él un archivo de estado antiguo o lo reescribe entero tras un conflicto de merge, la respuesta lo dice, y el agente puede pedirte que lo incluyas en un commit | Sí |
| verbaly_status | Cobertura por idioma, y cuántas traducciones automáticas están esperando a una persona y cuántas traducciones se escribieron para un texto anterior. Un archivo de estado que no puede leer se reporta en la respuesta, nunca como un fallo | No |
| verbaly_missing | Todo lo que haría fallar la puerta de CI: traducciones que faltan, keys desconocidas, claves escritas con dos textos y traducciones que existen pero no pueden renderizar lo que renderiza el original. También lista lo que nunca la hace fallar: claves que solo tiene una traducción, un catálogo que dice algo que tu código no dice y traducciones escritas para un texto anterior. Todas sus rutas son relativas a tu proyecto | No |
| verbaly_translate | Rellena los huecos con el proveedor que tengas configurado y lo guarda todo como borrador. Un mensaje que alguien escribió mientras trabajaba se queda como estaba, y la respuesta lo nombra | Sí |
| verbaly_write_drafts | Guarda las traducciones que el agente escribió por su cuenta. Cada una se comprueba como una traducción automática contra el texto que publica tu código, se escribe solo para claves que tiene tu idioma fuente y queda marcada como borrador para que la revises, con nota del texto para el que se escribió. Conserva lo que ya está traducido salvo que se le pida reescribirlo | Sí |
| verbaly_drafts | Cada traducción máquina que sigue esperándote, junto a la frase de la que salió, para que puedas leer las dos antes de decidir | No |
Las que solo leen se lo dicen al cliente, así que un agente puede mirar el estado de tu proyecto sin permiso para cambiar nada. Las que escriben avisan antes: extract y translate aceptan un dryRun que cuenta lo que pasaría, y wrap informa salvo que le pidas aplicar.
Cada herramienta responde dos veces: una frase para quien lee la conversación, y la misma respuesta como datos. Un agente que pregunta por la cobertura recibe los números en sí, no una línea que descifrar, así que sigue funcionando aunque cambiemos cómo lo decimos.
Una tool que falla vuelve como un mensaje sobre el que el agente puede actuar, nunca como un servidor caído. Un fichero de config que falta lo dice, y un catálogo que no es JSON válido también. Un archivo de estado que un merge dejó roto solo añade una línea a las respuestas que lo leen, y las tools que escribirían borradores se detienen antes de escribir nada.
Traducir es el único paso que puede cortarse a medias, porque sale a la red. Cuando una parte no vuelve, el resto queda guardado igual y la respuesta nombra exactamente qué mensajes faltan, así que volver a pedirlo cuesta solo lo que falta.
Lo que puede leer
Todas las herramientas de arriba trabajan con claves y conteos, que basta para decirte que faltan catorce traducciones y no basta para enseñarte ninguna. Dos recursos cierran eso: un agente los lee por dirección, así que mirar tu proyecto no le gasta una de sus acciones.
| Dirección | Qué contiene |
|---|---|
| verbaly://config | En qué idioma escribes, a cuáles traduces, dónde viven tus ficheros de idioma y si el idioma se ve en tus direcciones |
| verbaly://catalog/{locale} | Todos los mensajes de un idioma, exactamente como los publica tu app: un texto que es de tu código se lee como lo tiene tu código. Un valor vacío significa que nadie lo ha traducido todavía |
Esto es lo que hace posible revisar una traducción máquina a través de un agente. Antes te daban una clave y te pedían aprobarla, que no es revisar. Ahora ves la frase de la que salió junto a lo que escribió la máquina, y la decisión sigue siendo tuya.
La Agent Skill
Un servidor le dice a un agente qué puede correr. Una skill le dice qué escribir. La Agent Skill de Verbaly vive en el repositorio y lleva el ciclo más las reglas que lo mantienen seguro, así que el agente deja de inventarse keys de catálogo a mano.
Las reglas que lleva son las que es fácil equivocar desde fuera.
- Las claves se generan, o salen del catálogo que el proyecto ya tiene. El agente nunca inventa una.
""en un catálogo quiere decir sin traducir, no vacío a propósito.- Los huecos y las etiquetas tienen que sobrevivir a una traducción palabra por palabra.
- Un enlace va por una etiqueta con nombre más un mapa de enlaces, nunca un
<a href>literal dentro de un mensaje. - Una traducción que escribe él mismo se guarda con
verbaly_write_drafts, nunca se escribe a mano en un catálogo.
llms.txt
Este sitio sirve /llms.txt, un índice en markdown de cada página de documentación con una línea sobre lo que cubre. Se genera desde el mismo menú lateral que estás viendo, así que no puede desincronizarse de la documentación real.
Es para el agente que lee antes de escribir. Apunta el tuyo ahí cuando necesite el mapa completo, y a una sola página cuando necesite una respuesta.
Por qué un agente no puede aprobar su propia traducción
Todo lo que produce verbaly_translate es un borrador, y también todo lo que un agente guarda con verbaly_write_drafts, y los borradores no se publican: con verbaly check --drafts en CI, el build sigue fallando mientras quede alguno. Aceptar uno es verbaly review --approve o el servidor de revisión local, y ninguno de los dos está expuesto a agentes: un agente aprobando su propia traducción es el salvavidas aprobándose a sí mismo.