Cada repositorio acumula datos estructurados que alguien eventualmente necesita como documento: los cambios en una versión, los colaboradores del año, un inventario de API, una lista de riesgos abiertos. Los datos ya están en JSON; el paso que falta es un PDF o archivo Word formateado que un cliente, auditor o gerente abrirá realmente. Con GroupDocs.Assembly.Mcp ejecutándose localmente junto a Claude Code (claude mcp add con dnx GroupDocs.Assembly.Mcp --yes), el agente rellena una plantilla de Word guardada en el repositorio a partir de un archivo JSON del mismo, y escribe el PDF, sin que nadie tenga que formatear una tabla:
Generar el PDF de notas de la versión 4.2.0 a partir de
data/release-4.2.0.jsoncontemplates/release-notes.docx, y un certificado de contribución para cada colaborador endata/contributors-2026.json.
La versión paso a paso con configuración y solución de problemas está en la documentación: How to generate a PDF or Word report from JSON data in a repository with Claude Code.
¿Por qué no dejar que el agente de codificación escriba el documento?
Los agentes de codificación son muy buenos produciendo datos y bastante malos produciendo documentos. Pídele “notas de la versión como PDF” y generará un archivo Markdown, luego un script que lo convierta, y depurará las fuentes del script. En la siguiente versión lo hará de nuevo, ligeramente diferente. La salida se ve como lo que la biblioteca de conversión tenga por defecto, no como los documentos que tu empresa envía.
Una plantilla fija el aspecto y lo mantiene bajo control de versiones. templates/release-notes.docx es un archivo Word normal con el logotipo, los estilos de encabezado y una tabla, más algunas etiquetas <<…>>. Quien sea responsable del diseño lo edita en Word; el agente nunca lo toca. El JSON lo produce tu herramienta de lanzamiento, o el agente a partir de git log, y esa es la parte que un agente de codificación hace bien.
También hace que el trabajo sea revisable. Un pull request que cambia data/release-4.2.0.json muestra exactamente qué cambios aparecerán en las notas de la versión, línea por línea, en un diff que un revisor puede leer en un minuto. Un pull request que cambia un PDF generado no muestra nada. Mantener los datos y el diseño como archivos separados y versionados, y tratar el documento como algo que se genera a partir de ellos, es la misma idea que separar el código fuente del resultado de la compilación, y se aplica a los documentos por las mismas razones.
Cómo se ve el repositorio
repo/
data/
release-4.2.0.json {"release":{...}, "changes":[...4 items]}
contributors-2026.json {"contributors":[...3 items]}
templates/
release-notes.docx <<[release.Version]>>, <<foreach [c in
changes]>> table row, counts
certificate.docx <<[contributor.Name]>> ...
out/ GROUPDOCS_MCP_OUTPUT_PATH, in .gitignore
|
| Claude Code -> GroupDocs.Assembly MCP server (local, stdio)
v
release-notes-4.2.0.pdf pnair.pdf tvarga.pdf mrossi.pdf
Las llamadas
Primero el agente verifica qué espera la plantilla, para poder decirte si falta algo en el JSON:
-> get_template_fields {"template":{"filePath":
"repo/templates/release-notes.docx"}}
<- { "dataSourceNames": [ "release", "changes" ],
"fields": [ "release.Product", "release.Version", "release.Date",
"changes[].Type", "changes[].Title",
"changes[].PullRequest", "changes[].Author" ] }
Luego una llamada la renderiza:
-> assemble_document {"template":{"filePath":
"repo/templates/release-notes.docx"},
"data":{"filePath":"repo/data/release-4.2.0.json"},
"format":"pdf","outputName":"release-notes-4.2.0.pdf"}
<- Assembled 'release-notes.docx' with 'release-4.2.0.json' (JSON
object) as PDF
Saved to: .../release-notes-4.2.0.pdf
La fila de tabla de la plantilla se repite una vez por cada cambio, y su última línea cuenta los cambios y los autores distintos con changes.Count() y changes.Select(c => c.Author).Distinct().Count(). Esos números provienen de los datos en tiempo de renderizado, no del agente.
Los certificados son una distribución tipo fan‑out: un PDF por cada elemento del arreglo contributors, nombrado según el identificador del colaborador:
-> assemble_per_record {"template":{"filePath":
"repo/templates/certificate.docx"},
"data":{"filePath":"repo/data/contributors-2026.json"},
"recordsPath":"contributors","fileNameField":"Handle",
"format":"pdf"}
<- Assembled 3 of 3 document(s) from 'certificate.docx' with
'contributors-2026.json', one per record (each record as
'contributor'), as PDF.
Saved to:
.../pnair.pdf
.../tvarga.pdf
.../mrossi.pdf
recordsPath indica al servidor dónde está el arreglo cuando el archivo JSON es un objeto, que es la forma habitual de los archivos de datos reales.
Hazlo un hábito, no un prompt
Los agentes siguen las instrucciones del proyecto sobre cuándo usar una herramienta. Unas cuantas líneas en CLAUDE.md o AGENTS.md convierten esto en una convención:
Documents for people (release notes, reports, certificates) are generated
with the groupdocs-assembly MCP server from templates/*.docx and data/*.json.
Call get_template_fields first; never edit a template. Generated files land
in out/, which is in .gitignore. Dates in JSON as yyyy-MM-ddTHH:mm:ss.
Mantén los resultados fuera de git. Por defecto el servidor escribe junto a su carpeta de almacenamiento; establece GROUPDOCS_MCP_OUTPUT_PATH en el registro del servidor apuntando a la carpeta out/ del repositorio y añádela a .gitignore. El JSON y la plantilla son la fuente; el PDF es un artefacto de compilación, regenerado en segundos, y comprometerlo solo produce diffs que nadie puede revisar.
Límites honestos
- Modo de evaluación: cada PDF comienza con “Evaluation Only. Created with GroupDocs.Assembly 26.7…”. Está bien para probar; licencia el servidor antes de que cualquier documento salga del equipo.
- Las plantillas son entrada confiable. Las etiquetas de imagen y documento cargan las rutas y URLs que devuelven sus expresiones, así que trata una plantilla de un pull request como código y proporciona al servidor una única carpeta de almacenamiento.
- Fechas: escríbelas como
2026-11-03T00:00:00y formateálas en la plantilla (<<[release.Date]:"d MMMM yyyy">>). Una cadena solo de fecha se desplazó un día en una máquina UTC+2 en nuestra prueba; la imagen Docker se ejecuta en UTC. - La generación por registro solo lee JSON, y
maxDocuments(por defecto 100) detiene un arreglo inesperadamente grande antes de que se escriba algo. get_template_fieldses estático: los valores calculados dentro de proyeccionesSelectoGroupByno se siguen.
Preguntas frecuentes
¿Puede Claude Code generar un PDF a partir de JSON en mi repositorio sin un servicio en la nube?
Sí. El servidor MCP se ejecuta localmente como proceso hijo de Claude Code y lee la plantilla y el JSON de la carpeta que le indiques.
¿Puede ejecutarse en CI?
El servidor es un servidor MCP, por lo que necesita un cliente MCP: Claude Code en modo headless, o cualquier ejecutor de agentes. La imagen Docker (ghcr.io/groupdocs-assembly/assembly-net-mcp) es la forma cómoda para una canalización.
¿Word o PDF?
Ambos. Omite format y la salida será un DOCX como la plantilla; "format":"pdf" produce un PDF. get_supported_formats enumera cada objetivo por plantilla.
Profundiza
- Documentación, guía canónica: How to generate a PDF or Word report from JSON data in a repository with Claude Code
- Centro de documentación: GroupDocs.Assembly MCP Server
- Empieza aquí: Let the model fill in the data, not write the document
- Relacionado: A hundred personalised PDFs from one prompt: mail merge with an AI agent
- Relacionado: What does this template need? Ask it.
- Relacionado: The chart comes from the template, the numbers come from the data
- Modelo on‑premise y de seguridad: 3 architectures for AI document processing, and the one that keeps files inside your network
- Preguntas: GroupDocs Assembly forum
- Fuente: GroupDocs.Assembly.Mcp on GitHub