كل مستودع يجمع بيانات مُهيكلة يحتاجها شخص ما في النهاية كوثيقة: التغييرات في إصدار، المساهمين خلال السنة، جرد واجهة برمجة التطبيقات، قائمة بالمخاطر المفتوحة. البيانات بالفعل بصيغة 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.

الإصدار خطوة بخطوة مع الإعداد واستكشاف الأخطاء موجود في الوثائق: كيفية إنشاء تقرير PDF أو Word من بيانات JSON في مستودع باستخدام Claude Code.

لماذا لا نجعل وكيل البرمجة يكتب الوثيقة؟

وكلاء البرمجة جيدون جدًا في إنتاج البيانات ولكنهم سيئون إلى حد ما في إنتاج الوثائق. إذا طلبت منهم “ملاحظات الإصدار كملف PDF” فسيكتبون ملف Markdown، ثم سكريبت يحوله، ثم يصحح أخطاء خطوط السكريبت. في الإصدار التالي، يفعل ذلك مرة أخرى بطريقة مختلفة قليلاً. النتيجة تبدو كما يحددها الإعداد الافتراضي لمكتبة التحويل، وليس كوثائق شركتك.

القالب يثبت المظهر ويضعه تحت التحكم في الإصدارات. templates/release-notes.docx هو ملف Word عادي يحتوي على الشعار، أنماط العناوين وجدول، بالإضافة إلى بعض العلامات <<…>>. من يملك التصميم يحرره في Word؛ الوكيل لا يلمسه أبدًا. يتم إنتاج JSON بواسطة أدوات الإصدار الخاصة بك، أو بواسطة الوكيل من git log، وهذا هو الجزء الذي يبرع فيه وكيل البرمجة.

كما يجعل العمل قابلًا للمراجعة. طلب سحب يغيّر data/release-4.2.0.json يُظهر بالضبط أي التغييرات ستظهر في ملاحظات الإصدار، سطرًا بسطر، في اختلاف يمكن للمراجع قراءته في دقيقة. طلب سحب يغيّر ملف 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 هو ناتج بناء، يُعاد إنشاؤه في ثوانٍ، والالتزام به ينتج فقط اختلافات لا يمكن لأحد مراجعتها.

حدود صريحة

  • وضع التقييم: كل ملف PDF يبدأ بـ “Evaluation Only. Created with GroupDocs.Assembly 26.7…”. مناسب للتجربة؛ رخص الخادم قبل أن يخرج أي شيء من الفريق.
  • القوالب هي مدخلات موثوقة. علامات الصورة والوثيقة تحمل المسارات وعناوين URL التي تُرجعها تعبيراتها، لذا عالج قالبًا من طلب سحب ككود، وامنح الخادم مجلد تخزين واحد.
  • التواريخ: اكتبها كـ 2026-11-03T00:00:00 وقم بتنسيقها في القالب (<<[release.Date]:"d MMMM yyyy">>). تم إزاحة سلسلة تاريخية فقط بيوم واحد على جهاز UTC+2 في اختبارنا؛ صورة Docker تعمل بتوقيت UTC.
  • إنشاء لكل سجل يقرأ JSON فقط، وmaxDocuments (الافتراضي 100) يوقف مصفوفة كبيرة غير متوقعة قبل كتابة أي شيء.
  • get_template_fields ثابت: القيم المحسوبة داخل إسقاطات Select أو GroupBy لا يتم تتبعها.

الأسئلة المتكررة

هل يمكن لـ Claude Code إنشاء ملف PDF من JSON في مستودعي دون خدمة سحابية؟
نعم. يعمل خادم MCP محليًا كعملية فرعية لـ Claude Code ويقرأ القالب والـ JSON من المجلد الذي تشير إليه.

هل يمكن تشغيل هذا في CI؟
الخادم هو خادم MCP، لذا يحتاج إلى عميل MCP: Claude Code في وضع بدون واجهة، أو أي مشغل وكيل. صورة Docker (ghcr.io/groupdocs-assembly/assembly-net-mcp) هي الشكل المناسب لخط أنابيب.

Word أم PDF؟
كلاهما. إذا تركت format فارغًا يكون الناتج DOCX مثل القالب؛ "format":"pdf" ينتج PDF. get_supported_formats يسرد كل هدف لكل قالب.

تعمق أكثر