Jedes Repository sammelt strukturierte Daten, die irgendwann jemand als Dokument benötigt: die Änderungen in einem Release, die Mitwirkenden des Jahres, ein API‑Inventar, eine Liste offener Risiken. Die Daten liegen bereits als JSON vor; der fehlende Schritt ist ein formatiertes PDF‑ oder Word‑Dokument, das ein Kunde, ein Prüfer oder ein Manager tatsächlich öffnet. Mit GroupDocs.Assembly.Mcp, das lokal neben Claude Code läuft (claude mcp add mit dnx GroupDocs.Assembly.Mcp --yes), füllt der Agent eine im Repository gespeicherte Word‑Vorlage aus einer JSON‑Datei im Repository und schreibt das PDF, ohne dass jemand eine Tabelle formatiert:

Erstelle das Release‑Notes‑PDF für 4.2.0 aus data/release-4.2.0.json mit templates/release-notes.docx und ein Beitragszertifikat für jeden Mitwirkenden in data/contributors-2026.json.

Die schrittweise Version mit Konfiguration und Fehlersuche befindet sich in der Dokumentation: Wie man einen PDF‑ oder Word‑Bericht aus JSON‑Daten in einem Repository mit Claude Code erzeugt.

Warum nicht den Coding‑Agent das Dokument schreiben lassen?

Coding‑Agenten sind sehr gut darin, Daten zu erzeugen, und ziemlich schlecht darin, Dokumente zu erzeugen. Fragt man sie nach „Release‑Notes als PDF“, schreiben sie eine Markdown‑Datei, dann ein Skript, das diese konvertiert, und debuggen anschließend die Schriftarten des Skripts. Beim nächsten Release machen sie es wieder, jedoch leicht anders. Das Ergebnis sieht aus wie das, was die Konvertierungsbibliothek standardmäßig liefert, nicht wie die Dokumente, die Ihr Unternehmen verschickt.

Eine Vorlage fixiert das Aussehen und legt es unter Versionskontrolle. templates/release-notes.docx ist eine normale Word‑Datei mit dem Logo, den Überschrifts‑Stilen und einer Tabelle, plus ein paar <<…>>‑Tags. Wer das Layout besitzt, bearbeitet es in Word; der Agent berührt es nie. Das JSON wird von Ihrem Release‑Tooling erzeugt oder vom Agenten aus git log, und das ist der Teil, den ein Coding‑Agent gut macht.

Es macht die Arbeit zudem prüfbar. Ein Pull‑Request, der data/release-4.2.0.json ändert, zeigt genau, welche Änderungen in den Release‑Notes erscheinen werden, Zeile für Zeile, in einem Diff, den ein Reviewer in einer Minute lesen kann. Ein Pull‑Request, der ein generiertes PDF ändert, zeigt überhaupt nichts. Daten und Layout als separate, versionierte Dateien zu halten und das Dokument als etwas zu behandeln, das daraus gerendert wird, ist dieselbe Idee wie das Trennen von Quellcode und Build‑Ausgabe, und das gilt aus denselben Gründen auch für Dokumente.

Wie das Repository aussieht

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

Die Aufrufe

Zuerst prüft der Agent, was die Vorlage erwartet, damit er Ihnen sagen kann, ob im JSON etwas fehlt:

-> 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" ] }

Dann rendert ein Aufruf das Dokument:

-> 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

Die Tabellenzeile der Vorlage wiederholt sich einmal pro Änderung, und ihre letzte Zeile zählt die Änderungen und die eindeutigen Autoren mit changes.Count() und changes.Select(c => c.Author).Distinct().Count(). Diese Zahlen stammen zur Renderzeit aus den Daten, nicht vom Agenten.

Die Zertifikate werden fan‑out erzeugt: ein PDF pro Element des contributors‑Arrays, benannt nach dem Handle des Mitwirkenden:

-> 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 teilt dem Server mit, wo das Array liegt, wenn die JSON‑Datei ein Objekt ist, was die übliche Struktur realer Datendateien ist.

Mach es zur Gewohnheit, nicht zur Eingabeaufforderung

Agenten folgen Projektanweisungen, wann ein Werkzeug zu verwenden ist. Ein paar Zeilen in CLAUDE.md oder AGENTS.md machen daraus eine Konvention:

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.

Halten Sie die Ausgaben außerhalb von Git. Standardmäßig schreibt der Server neben seinen Speicherordner; setzen Sie GROUPDOCS_MCP_OUTPUT_PATH in der Server‑Registrierung auf den out/‑Ordner des Repos und fügen Sie diesen Ordner zu .gitignore hinzu. Das JSON und die Vorlage sind die Quelle; das PDF ist ein Build‑Artefakt, das in Sekunden neu erzeugt wird, und das Committen davon erzeugt nur Diffs, die niemand prüfen kann.

Ehrliche Grenzen

  • Evaluierungsmodus: jedes PDF beginnt mit “Evaluation Only. Created with GroupDocs.Assembly 26.7…”. In Ordnung zum Ausprobieren; lizenzieren Sie den Server, bevor etwas das Team verlässt.
  • Vorlagen sind vertrauenswürdige Eingaben. Bild‑ und Dokument‑Tags laden die Pfade und URLs, die ihre Ausdrücke zurückgeben, behandeln Sie also eine Vorlage aus einem Pull‑Request wie Code und geben Sie dem Server einen Speicherordner.
  • Daten: schreiben Sie sie als 2026-11-03T00:00:00 und formatieren Sie sie in der Vorlage (<<[release.Date]:"d MMMM yyyy">>). Ein reines Datums‑String wurde in unserem Test auf einer UTC+2‑Maschine um einen Tag verschoben; das Docker‑Image läuft in UTC.
  • Die per‑Record‑Generierung liest nur JSON, und maxDocuments (Standard 100) stoppt ein unerwartet großes Array, bevor etwas geschrieben wird.
  • get_template_fields ist statisch: Werte, die innerhalb von Select‑ oder GroupBy‑Projektionen berechnet werden, werden nicht verfolgt.

FAQ

Kann Claude Code ein PDF aus JSON in meinem Repository ohne Cloud‑Dienst erzeugen?
Ja. Der MCP‑Server läuft lokal als Kindprozess von Claude Code und liest die Vorlage und das JSON aus dem Ordner, den Sie angeben.

Kann das in CI laufen?
Der Server ist ein MCP‑Server, daher benötigt er einen MCP‑Client: Claude Code im Headless‑Modus oder irgendeinen Agent‑Runner. Das Docker‑Image (ghcr.io/groupdocs-assembly/assembly-net-mcp) ist die praktische Form für eine Pipeline.

Word oder PDF?
Beides. Lassen Sie format weg und die Ausgabe ist ein DOCX wie die Vorlage; "format":"pdf" erzeugt ein PDF. get_supported_formats listet jedes Ziel pro Vorlage auf.

Tiefer einsteigen