Elke repository verzamelt gestructureerde gegevens die iemand uiteindelijk nodig heeft als document: de wijzigingen in een release, de bijdragers van het jaar, een API‑inventaris, een lijst met open risico’s. De gegevens zijn al JSON; de ontbrekende stap is een opgemaakte PDF‑ of Word‑bestand dat een klant, een auditor of een manager daadwerkelijk opent. Met GroupDocs.Assembly.Mcp die lokaal naast Claude Code draait (claude mcp add met dnx GroupDocs.Assembly.Mcp --yes), vult de agent een Word‑sjabloon dat in de repo is bewaard vanuit een JSON‑bestand in de repo, en schrijft de PDF, zonder dat iemand een tabel opmaakt:
Genereer de release‑notes PDF voor 4.2.0 vanuit data/release-4.2.0.json met templates/release-notes.docx, en een bijdragecertificaat voor elke bijdrager in data/contributors-2026.json.
De stap‑voor‑stap versie met configuratie en probleemoplossing staat in de documentatie: Hoe een PDF‑ of Word‑rapport te genereren vanuit JSON‑gegevens in een repository met Claude Code.
Waarom de code‑agent niet het document laten schrijven?
Code‑agents zijn zeer goed in het produceren van gegevens en redelijk slecht in het produceren van documenten. Vraag er één om “release‑notes als PDF” en hij zal een Markdown‑bestand schrijven, vervolgens een script dat het converteert, en daarna de lettertypen van het script debuggen. Bij de volgende release doet hij het weer, maar iets anders. De output ziet eruit als wat de conversiebibliotheek standaard levert, niet als de documenten die uw bedrijf verstuurt.
Een sjabloon bepaalt het uiterlijk en plaatst het onder versiebeheer. templates/release-notes.docx is een normaal Word‑bestand met het logo, de kop‑stijlen en een tabel, plus een paar <<…>>‑tags. Degene die de lay‑out bezit bewerkt het in Word; de agent raakt het nooit aan. De JSON wordt geproduceerd door uw release‑tools, of door de agent vanuit git log, en dat is het deel waarin een code‑agent goed is.
Het maakt het werk ook controleerbaar. Een pull‑request die data/release-4.2.0.json wijzigt, toont precies welke wijzigingen in de release‑notes zullen verschijnen, regel voor regel, in een diff die een reviewer in een minuut kan lezen. Een pull‑request die een gegenereerde PDF wijzigt, toont helemaal niets. Het scheiden van data en lay‑out als afzonderlijke, versie‑beheerde bestanden, en het behandelen van het document als iets dat je ervan rendert, is hetzelfde idee als broncode en build‑output gescheiden houden, en dat geldt om dezelfde redenen ook voor documenten.
Hoe de repository eruitziet
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
De oproepen
Eerst controleert de agent wat het sjabloon verwacht, zodat hij je kan vertellen of er iets ontbreekt in de 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" ] }
Vervolgens rendert één oproep het:
-> 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
De tabelrij van het sjabloon wordt herhaald voor elke wijziging, en de laatste regel telt de wijzigingen en de verschillende auteurs met changes.Count() en changes.Select(c => c.Author).Distinct().Count(). Die getallen komen uit de data op het moment van renderen, niet van de agent.
De certificaten zijn een fan‑out: één PDF per element van de contributors‑array, benoemd naar de gebruikersnaam van de bijdrager:
-> 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 vertelt de server waar de array zich bevindt wanneer het JSON‑bestand een object is, wat de gebruikelijke vorm is van echte data‑bestanden.
Maak er een gewoonte van, niet een prompt
Agents volgen projectinstructies over wanneer een tool te gebruiken. Een paar regels in CLAUDE.md of AGENTS.md maken hiervan een conventie:
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.
Houd de output buiten git. Standaard schrijft de server naast zijn opslagmap; stel GROUPDOCS_MCP_OUTPUT_PATH in de serverregistratie in op de out/‑map van de repo en voeg die map toe aan .gitignore. De JSON en het sjabloon zijn de bron; de PDF is een build‑artefact, binnen enkele seconden opnieuw gegenereerd, en het committen ervan levert alleen diffs op die niemand kan beoordelen.
Eerlijke beperkingen
- Evaluatiemodus: elke PDF begint met “Evaluation Only. Created with GroupDocs.Assembly 26.7…”. Geschikt om het uit te proberen; licentieer de server voordat iets het team verlaat.
- Sjablonen zijn vertrouwde invoer. Afbeeldings‑ en document‑tags laden de paden en URL’s die hun expressies teruggeven, dus behandel een sjabloon uit een pull‑request als code, en geef de server één opslagmap.
- Datums: schrijf ze als
2026-11-03T00:00:00en formatteer ze in het sjabloon (<<[release.Date]:"d MMMM yyyy">>). Een datum‑enkel‑string werd een dag verschoven op een UTC+2‑machine in onze test; de Docker‑image draait in UTC. - Per‑record generatie leest alleen JSON, en
maxDocuments(standaard 100) stopt een onverwacht grote array voordat er iets wordt geschreven. get_template_fieldsis statisch: waarden die binnenSelect‑ ofGroupBy‑projecties worden berekend, worden niet gevolgd.
Veelgestelde vragen
Kan Claude Code een PDF genereren vanuit JSON in mijn repository zonder een cloudservice?
Ja. De MCP‑server draait lokaal als een child‑process van Claude Code en leest het sjabloon en de JSON uit de map die u aanwijst.
Kan dit draaien in CI?
De server is een MCP‑server, dus hij heeft een MCP‑client nodig: Claude Code in headless‑modus, of een willekeurige agent‑runner. De Docker‑image (ghcr.io/groupdocs-assembly/assembly-net-mcp) is de handige vorm voor een pipeline.
Word of PDF?
Beide. Laat format weg en de output is een DOCX zoals het sjabloon; "format":"pdf" levert een PDF op. get_supported_formats geeft elk doel per sjabloon weer.
Ga dieper
- Documentatie, canonieke handleiding: Hoe een PDF‑ of Word‑rapport te genereren vanuit JSON‑gegevens in een repository met Claude Code
- Documentatie‑hub: GroupDocs.Assembly MCP Server
- Begin hier: Laat het model de gegevens invullen, niet het document schrijven
- Gerelateerd: Een honderd gepersonaliseerde PDF’s uit één prompt: mail‑merge met een AI‑agent
- Gerelateerd: Wat heeft dit sjabloon nodig? Vraag het.
- Gerelateerd: De grafiek komt uit het sjabloon, de cijfers komen uit de data
- On‑premise en beveiligingsmodel: 3 architecturen voor AI‑documentverwerking, en degene die bestanden binnen uw netwerk houdt
- Vragen: GroupDocs Assembly forum
- Bron: GroupDocs.Assembly.Mcp op GitHub