Кожен репозиторій накопичує структуровані дані, які зрештою комусь потрібні у вигляді документа: зміни у випуску, учасники року, інвентар API, список відкритих ризиків. Дані вже у форматі JSON; відсутній крок — відформатований PDF або Word‑файл, який клієнт, аудитор чи менеджер фактично відкриє. За допомогою GroupDocs.Assembly.Mcp, що працює локально поруч із Claude Code (claude mcp add з dnx GroupDocs.Assembly.Mcp --yes), агент заповнює шаблон Word, що зберігається в репозиторії, даними з JSON‑файлу в репозиторії та записує PDF, без жодного форматування таблиці:

Згенерувати PDF‑примітки до випуску 4.2.0 з data/release-4.2.0.json за допомогою templates/release-notes.docx, а також сертифікат внеску для кожного учасника в data/contributors-2026.json.

Покрокова інструкція з конфігурацією та усуненням проблем знаходиться в документації: How to generate a PDF or Word report from JSON data in a repository with Claude Code.

Чому б не дозволити кодувальному агенту написати документ?

Кодувальні агенти дуже добре генерують дані, але погано — документи. Попросіть його створити «примітки до випуску у PDF», і він напише файл Markdown, потім скрипт, що його конвертує, і дебажитиме шрифти скрипту. Наступний випуск — знову трохи інакше. Результат виглядає так, як за замовчуванням працює бібліотека конвертації, а не так, як ваші компанійні документи.

Шаблон фіксує вигляд і зберігає його під контролем версій. templates/release-notes.docx — звичайний Word‑файл із логотипом, стилями заголовків і таблицею, а також кількома тегами <<…>>. Той, хто відповідає за макет, редагує його у Word; агент його не торкається. JSON генерується вашими інструментами випуску або агентом з git log, і це саме те, що кодувальний агент робить добре.

Також це робить роботу перевіряємою. Pull‑request, який змінює data/release-4.2.0.json, точно показує, які зміни з’являться в примітках, рядок за рядком, у diff, який рев’ювер може прочитати за хвилину. Pull‑request, який змінює згенерований PDF, нічого не показує. Тримання даних і макету окремо, у версіонованих файлах, і розгляд документа як результату їх рендерингу — це та сама ідея, що й розділення вихідного коду та артефактів збірки, і вона працює для документів з тих же причин.

Як виглядає репозиторій

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

Виклики

Спочатку агент перевіряє, що очікує шаблон, щоб повідомити, чи чогось не вистачає в 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" ] }

Потім один виклик його рендерить:

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

Рядок таблиці в шаблоні повторюється один раз на кожну зміну, а останній рядок підраховує кількість змін та унікальних авторів за допомогою changes.Count() та changes.Select(c => c.Author).Distinct().Count(). Ці числа беруться з даних під час рендерингу, а не від агента.

Сертифікати — це розгортка: один PDF на кожен елемент масиву contributors, названий за іменем учасника:

-> 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 вказує серверу, де знаходиться масив, коли JSON‑файл є об’єктом, що є звичним форматом реальних файлів даних.

Робіть це звичкою, а не підказкою

Агенти дотримуються інструкцій про те, коли використовувати інструмент. Кілька рядків у CLAUDE.md або AGENTS.md перетворюють це на конвенцію:

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.

Тримайте результати поза git. За замовчуванням сервер записує поруч зі своєю папкою сховища; встановіть GROUPDOCS_MCP_OUTPUT_PATH у реєстрації сервера на папку out/ репозиторію та додайте цю папку до .gitignore. JSON і шаблон — це джерело; PDF — артефакт збірки, який регенерується за секунди, і його коміт лише створює diff, який ніхто не може переглянути.

Чесні обмеження

  • Режим оцінки: кожен PDF починається з «Evaluation Only. Created with GroupDocs.Assembly 26.7…». Підходить для тестування; перед тим, як щось залишить команду, ліцензуйте сервер.
  • Шаблони — довірений вхід. Теги зображень і документів завантажують шляхи та URL, які повертають їх вирази, тому ставтеся до шаблону з pull‑request як до коду і надавайте серверу одну папку сховища.
  • Дати: записуйте їх у вигляді 2026-11-03T00:00:00 і форматте у шаблоні (<<[release.Date]:"d MMMM yyyy">>). У тесті на машині UTC+2 рядок лише з датою зміщувався на день; Docker‑образ працює в UTC.
  • Генерація per‑record читає лише JSON, а maxDocuments (за замовчуванням 100) зупиняє надто великий масив до запису.
  • get_template_fields статичний: значення, обчислені всередині проекцій Select або GroupBy, не відстежуються.

FAQ

Чи може Claude Code згенерувати PDF з JSON у моєму репозиторії без хмарного сервісу?
Так. MCP‑сервер працює локально як дочірній процес Claude Code і читає шаблон і JSON з вказаної папки.

Чи можна це запускати в CI?
Сервер — це MCP‑сервер, тому потрібен MCP‑клієнт: Claude Code у headless‑режимі або будь‑який агент‑раннер. Docker‑образ (ghcr.io/groupdocs-assembly/assembly-net-mcp) — зручна форма для конвеєра.

Word чи PDF?
Будь‑який. Якщо не вказати format, вихід буде DOCX, як шаблон; "format":"pdf" дає PDF. get_supported_formats перераховує усі цілі для кожного шаблону.

Поглибити