خادم MCP لنظام نما
بروتوكول MCP (Model Context Protocol) هو المعيار المفتوح الذي تتصل به مساعدات الذكاء الاصطناعي — مثل Claude Desktop و Claude Code وغيرهما — بالأنظمة الخارجية لتقرأ بياناتها وتنفذ أوامر فيها. يحتوي نظام نما على خادم MCP مدمج: بمجرد تركيب وحدة الذكاء الاصطناعي، يستطيع أي عميل MCP الاتصال بالنظام مباشرة واستخدام الأدوات المعرفة في شاشة AI Tool Definition — يبحث في السجلات، يقرأ المستندات، يشغّل التقارير، بل ويستورد سجلات جديدة — وكل ذلك بحساب مستخدم حقيقي تسري عليه كل صلاحيات النظام.
تفضّل المشاهدة؟
فيديو الشرح في صفحة «دعم أفضل بمساعد ذكاء اصطناعي» يجهّز هذا الخادم من البداية مع Claude: تعريفات الأدوات، ومفتاح API لكل مستخدم، وملف الربط، وجلسة حيّة بصفة مدير النظام وبصفة مدير المبيعات.
المتطلبات
- وحدة الذكاء الاصطناعي (AI Module) مركبة ومرخصة — بدونها لا يعمل الخادم أصلًا.
- إن كان الترخيص يحمل تاريخ انتهاء لاشتراك MCP، فيجب ألا يكون قد مضى — بعده يُرفض كل طلب (انظر «رسائل قد تظهر لك» آخر الصفحة).
- سجل API Credentials معتمد (الأساسيات ← المستندات ← API Credentials — نفس بيانات الاعتماد المستخدمة مع الواجهة البرمجية REST).
- أداة واحدة على الأقل معرفة ومعتمدة في شاشة AI Tool Definition.
عنوان الخادم
يعمل الخادم بنقل Streamable HTTP على المسار:
http[s]://<server-ip-or-domain>/basic-services/mcpالترقية من الإصدارات الأقدم
كانت الإصدارات الأقدم تعرض الخادم بنقل SSE على المسار /basic-services/mcp/sse. استُبدلت تلك النقطة — حدّث إعدادات العملاء الحالية إلى العنوان الجديد وغيّر نوع النقل من sse إلى http.
المصادقة
يصادق الخادم كل طلب على حدة عبر بيانات اعتماد API:
| الترويسة (Header) | القيمة | إلزامية |
|---|---|---|
X-API-Key | حقل API Key (Client Secret) من سجل API Credentials | نعم |
Authorization | Bearer <client secret> — بديل عن X-API-Key | لا |
X-API-Secret | حقل API Key (Client Secret)، فقط حين يحمل X-API-Key حقل Client Id (Can Be Ignored) من السجل بدلًا منه | لا |
(تُقبل القيم أيضًا بأسماء بديلة: apiKey/clientId لمفتاح الوصول و apiSecret/clientSecret للسر — ترويسةً أو ضمن معاملات الرابط.)
المصادقة برمز Bearer — في الإصدارات الصادرة بتاريخ 20260922 فأحدث
بعض العملاء لا يستطيعون إرسال ترويسة من اختيارك، ويصادقون دائمًا بالطريقة الشائعة في الويب: Authorization: Bearer <token>. وأبرز مثال هو موصّل MCP من Anthropic — الميزة التي تجعل Claude يتصل بخادم MCP مباشرة من واجهة Claude البرمجية — فهو لا يتيح إرسال X-API-Key إطلاقًا.
ضع قيمة Client Secret في رمز Bearer وسيقبلها الخادم؛ فهو لا ينظر إلى ترويسة Authorization إلا إذا خلا الطلب من X-API-Key، فلا يتغير شيء بالنسبة للعملاء العاملين بالفعل. أما الخوادم الأقدم من إصدار 20260922 فتتجاهل الترويسة وترد برفض المصادقة.
سجل API Credentials يربط بيانات الاعتماد بمستخدم محدد عبر حقل المستخدم، ويدعم تقييد فترة الصلاحية (صالح من / صالح حتي) وإيقاف الاعتماد (منع الدخول). يظهر المفتاح مرة واحدة عند أول حفظ للسجل؛ ولرؤيته مرة أخرى علّم View API Key واحفظ. كل أداة يستدعيها العميل تُنفَّذ بهوية ذلك المستخدم: صلاحيات السجلات، والمحددات (الشركة والفرع وغيرها)، وقواعد التحقق — كلها تسري كأن المستخدم يعمل من شاشات النظام.
اختيار سياق الدخول
يعمل النداء عادةً في سياق دخول المستخدم نفسه — الشركة والقطاع والفرع والإدارة ومجموعة التحليل التي كان سيدخل عليها من شاشة الدخول. وكل أداة تقبل أيضًا خمسة مدخلات اختيارية تغيّر ذلك لنداء واحد: loginLegalEntity وloginSector وloginBranch وloginDepartment وloginAnalysisSet، كلٌّ منها بكود المحدد أو معرّفه. والمحدد الذي لا يُرسل يبقى على قيمة المستخدم.
بهذا تفحص شيئًا «كأنك على الشركة 02»: شغّل التقرير، أو اقرأ التوجيه، مع loginLegalEntity = 02، فيتصرف كل ما يعتمد على سياق الدخول — كتقرير فلتره الافتراضي شركة المستخدم — كما يتصرف لمن دخل هناك. وتسري قواعد شاشة الدخول نفسها، فالسياق الذي لا يُسمح للمستخدم بالدخول عليه يُرفض ولا تعمل الأداة؛ وكذلك الكود الذي لا يطابق أي محدد. ولا تعرّف هذه المدخلات في تعريف الأداة: كل أداة تحصل عليها تلقائيًا.
احمِ بيانات الاعتماد
عميل MCP المتصل بهذه البيانات يستطيع فعل كل ما يستطيعه المستخدم المربوط بها — بما في ذلك إنشاء سجلات إذا كانت أدوات الاستيراد مفعّلة. خصص مستخدمًا بصلاحيات محسوبة لهذا الغرض، وقيّد الأدوات الحساسة عبر جدول الصلاحيات في تعريف الأداة.
إعداد العملاء
تبويب Code في Claude Desktop أو Claude Code — الإعداد الموصى به
طريقة العمل التي نوصي بها هي الموصوفة في دعم أفضل بمساعد ذكاء اصطناعي: تبويب Code في Claude Desktop — أو Claude Code في Terminal — مفتوحًا داخل مجلد قاعدة معرفة الدعم، فيجد المساعد التوثيق ونموذج البيانات والنظام الحي جنبًا إلى جنب. وكلاهما يقرأ خوادم MCP من ملف .mcp.json في المجلد المفتوح، فأضف الخادم إلى ملف .mcp.json في مجلد قاعدة المعرفة (وأنشئ الملف إن لم يكن موجودًا):
{
"mcpServers": {
"nama-erp": {
"type": "http",
"url": "https://my-server.example.com/basic-services/mcp",
"headers": {
"X-API-Key": "<client-secret>"
}
}
}
}ابدأ جلسة جديدة بعد حفظ الملف، واسمح بالخادم حين تُسأل؛ وفي Claude Code يعرض الأمر /mcp الخوادم ويعيد الاتصال بأيٍّ منها. ويمكن أن تتجاور عدة خوادم نما في الملف نفسه، كلٌّ باسمه. ويتصل تبويب Code و Claude Code من جهازك أنت، فخادم العميل على شبكة خاصة يعمل ما دام جهازك يصل إليه — عبر VPN العميل مثلًا.
لا تضع الخادم في ملف claude_desktop_config.json الخاص بـ Claude Desktop: ذلك الملف للخوادم التي يشغّلها التطبيق على جهازك، ويتجاهل الخادم البعيد مثل خادم نما.
موصّل MCP من Claude
يستطيع Claude الاتصال بالخادم مباشرة من واجهة Claude البرمجية دون عميل MCP وسيط من عندك. وهذا الموصّل لا يصادق إلا برمز Bearer، فأعطه عنوان الخادم وضع قيمة Client Secret في حقل رمز التفويض (authorization token) الخاص به — إذ لا يوجد فيه موضع لإضافة X-API-Key. ويحتاج ذلك إلى خادم على إصدار 20260922 فأحدث.
MCP Inspector
أداة الفحص الرسمية للبروتوكول تعمل من المتصفح مباشرة (الخادم يسمح بطلبات CORS): اختر النقل Streamable HTTP، وأدخل العنوان، وأضف ترويسة المصادقة.
بعد الاتصال، استعرض قائمة الأدوات من العميل — ستجد كل الأدوات المعتمدة وغير المعطلة من شاشة AI Tool Definition التي يحق لمستخدم بيانات الاعتماد تشغيلها (الأداة التي يمنعها جدول الصلاحيات عن ذلك المستخدم لا تظهر في القائمة أصلًا)، وأي تعديل على التعريفات ينعكس تلقائيًا في الاتصال التالي.
ليست أدوات التصدير وحدها
الخادم يعرض كل أداة معتمدة ومسموح بها للمستخدم المربوط بالاعتماد — أدوات استعلام وتقارير ومسارات كيان وأدوات نظام — لا أدوات التصدير فقط. هذه الصفحة تفصّل أدوات التصدير لأهميتها مع العملاء الخارجيين، وبقية الأنواع موثقة في تعريفات أدوات الذكاء الاصطناعي.
بعض الأدوات تسألك قبل أن تنفذ
عدد قليل من الأدوات يفعل ما لا يمكن التراجع عنه — وهي اليوم ترقية الخادم، التي توقفه للجميع. هذه الأدوات لا تنفذ بناءً على طلب المساعد وحده: يعرض العميل عليك أنت نموذج تأكيد، ولا يسمح لها بالمتابعة إلا ردّك الذي يعود إلى الخادم مباشرة. وClaude Code يعرض هذه النماذج. أما العميل الذي لا يستطيع عرضها فيصله رفض ولا يحدث شيء. انظر «أدوات إدارة الخادم» في تعريفات أدوات الذكاء الاصطناعي.
أدوات تصدير واستيراد السجلات
المجموعة الأهم للاستخدام مع عملاء MCP الخارجيين هي أدوات النظام للتصدير والاستيراد — اثنتا عشرة أداة من أربعة أصناف — وتُضاف كلها دفعة واحدة بزر إضافة أدوات التصدير (Add Export Tools) في صفحة System Tool من شاشة تعريف الأداة (انظر تعريفات أدوات الذكاء الاصطناعي).
تُسمّى الأدوات ببادئة من تعريف الأداة (حقل Tool Name أو Alt Code أو الكود). في الأمثلة التالية نفترض أن البادئة import.

import_ResolveEntityType — تحويل مصطلح إلى نوع كيان
نقطة البداية لأي عميل لا يعرف أسماء الكيانات الداخلية. أرسل مصطلحًا بالعربية أو الإنجليزية، واستلم أنواع الكيانات المطابقة بأسمائها المترجمة.
| المدخل | إلزامي | الوصف |
|---|---|---|
query | لا | المصطلح المراد البحث عنه، مثل فاتورة مبيعات أو sales invoice. اتركه، أو أرسل *، لتصفّح القائمة كاملةً بدل البحث |
page | لا | رقم الصفحة (يبدأ من 1) في وضع التصفّح |
pageSize | لا | حجم الصفحة في وضع التصفّح — 50 افتراضيًا و200 كحد أقصى |
تعيد الأداة حتى 25 نتيجة، كل نتيجة تحمل entityType (الاسم الداخلي مثل SalesInvoice) والاسمين العربي والإنجليزي. وفي وضع التصفّح تعيد totalEntityTypes والصفحة المطلوبة منها. وقيمة entityType التي تعيدها هي القيمة المعتمدة، تُمرَّر كما هي — وهي حساسة لحالة الأحرف — إلى كل أداة أخرى.
import_DescribeFields — الحقول التي تستطيع البحث بها
تسرد حقول الكيان الصالحة للاستخدام كمعايير في FindRecords، كل حقل بنوعه، وهل هو إلزامي، والقيم المسموحة إن كان قائمة، والكيان المستهدف إن كان مرجعًا، والجدول التفصيلي الذي ينتمي إليه.
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان المراد وصفه، مثل SalesInvoice |
collections | لا | جداول تفصيلية تُضاف إلى الإجابة (أسماء مفصولة بفواصل، مثل details، وهي بنود فاتورة المبيعات) — وحقول الرأس تُعاد دائمًا |
وهي ليست القائمة نفسها التي يعيدها GetImportSchema: فهي تحمل أيضًا حقول النظام مثل creationDate التي يمكن البحث بها ولا يمكن استيرادها أبدًا، وتُعلِّم الحقول المحسوبة التي قد لا يصلح البحث بها أصلًا.
import_SearchByTranslation — البحث عن كيان أو حقل أو خيار بالاسم
أوسع أدوات الاستكشاف: مصطلح واحد بالعربية أو الإنجليزية يدخل، فيخرج كل ما قد يعنيه — أنواع الكيانات، وحقول أي كيان، وثوابت القوائم، كلٌّ باسميه.
| المدخل | إلزامي | الوصف |
|---|---|---|
query | نعم | المصطلح المراد البحث عنه بالعربية أو الإنجليزية |
limit | لا | أقصى عدد نتائج — 25 افتراضيًا و100 كحد أقصى |
كل نتيجة تحمل kind: إما entity (ومعها entityType)، أو field (ومعها entityType و fieldId)، أو enum (ومعها enumType و value). استخدمها حين تعرف ما سمّاه المستخدم ولا تعرف أيًّا من الثلاثة يقصد.
import_FindRecords — البحث عن سجلات
بحث مرقّم الصفحات عن سجلات نوع كيان، يمر عبر بوابة العرض القياسية فتسري عليه صلاحيات القوائم والمحددات.
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان، مثل SalesInvoice |
criteria | لا | فلتر معايير نصي بصيغة نما — كل شرط على هيئة fieldId,operator,value,logic;، مثل code,Equal,INV-1,AND; أو valueDate,GreaterThanOrEqual,01-01-2024,AND; (التواريخ بصيغة dd-MM-yyyy) |
fields | لا | معرفات حقول إضافية تُعاد في كل صف (مفصولة بفواصل) — يُعاد دائمًا id و code |
orderBy | لا | معرف حقل للترتيب |
page | لا | رقم الصفحة (يبدأ من 1) |
pageSize | لا | حجم الصفحة — الافتراضي 25 والحد الأقصى 200 |
تعيد الأداة totalRecordsCount ورقم الصفحة وحجمها ومصفوفة records. وحقل المرفق المطلوب في fields يعود على شكل {"id", "fileName", "size"} — وصف الملف لا محتواه أبدًا — كما يقبل fields حقلًا في جدول تفصيلي (collection.field)، فيسرد نداء واحد مرفق كل بند؛ والمعرّف id هو ما تأخذه PrepareAttachmentDownloadById.
import_GetRecord — قراءة سجل
يقرأ سجلًا واحدًا بصيغة JSON عبر بوابة القراءة القياسية. الناتج بنفس صيغة الاستيراد، فيمكن قراءة سجل وتعديله وإعادة استيراده.
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان |
idOrCode | نعم | كود السجل أو معرفه |
mode | لا | visible (الافتراضي): الحقول الظاهرة على الشاشة فقط — أو all: كل الحقول |
fields | لا | معرفات حقول محددة تُعاد وحدها (تتجاوز mode) |
يُعاد حقل المرفق على شكل {"id": "...", "fileName": "...", "size": 123} (الحجم بالبايت)، ولا يُدرج محتوى الملف أبدًا. وإعادة إرسال هذا الكائن كما هو في ImportRecord تُبقي المرفق على حاله.
import_GetEnumValues — القيم المسموحة لحقل قائمة
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان صاحب الحقل |
fieldId | لا | معرف الحقل، مثل details.transItemType (نوع السطر في بند فاتورة المبيعات). ويقبل أكثر من معرف مفصولة بفواصل؛ واتركه لتحصل على كل حقول القوائم في الكيان |
تعيد قائمة القيم مع عنوان كل قيمة بالعربية والإنجليزية — مفيدة قبل الاستيراد لضمان إرسال الثوابت الصحيحة.
import_GetEntitySchema — الجداول والأعمدة خلف الكيان
بينما تتحدث بقية الأدوات بمعرفات الحقول، تجيب هذه بلغة SQL: اسم جدول الكيان، وأعمدته بأنواعها ومع الكيان الذي يشير إليه العمود المرجعي، وأعمدة المفاتيح الأجنبية، والتفاصيل نفسها لكل جدول تفصيلي بما فيها اسم الجدول الابن والعمود الذي يربطه بالرأس.
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان، مثل SalesInvoice |
وتحتاجها حين تكتب شيئًا يستعلم من قاعدة البيانات مباشرة بدل المرور عبر بوابات الكيانات — أداة SQL للقراءة فقط، أو تقريرًا.
import_GetImportSchema — مخطط الاستيراد
يصف كيفية بناء سجل لنوع كيان: كل حقل ونوعه وهل هو إلزامي، والقيم المسموحة لحقول القوائم، ونوع الكيان المستهدف للحقول المرجعية (المراجع تُكتب بالكود)، وبنية الجداول التفصيلية (مثل بنود الفاتورة).
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع الكيان |
mode | لا | visible (الافتراضي): الحقول الظاهرة على الشاشة — وهي ما يملؤه المستخدم عادة — أو all: كل الحقول القابلة للاستيراد |
collections | لا | حصر الجداول التفصيلية المعادة (أسماء مفصولة بفواصل، مثل details) — حقول الرأس تُعاد دائمًا |
تعيد الأداة أيضًا example: سجلًا هيكليًا بقيم بديلة بالشكل الذي تتوقعه ImportRecord تمامًا. المبالغ والكميات تحتفظ بتداخلها الحقيقي ولا تُكتب بمفاتيح منقّطة — فمثلًا الجانب المدين في سند القيد يُكتب "debit": { "value": { "amount": 1500, "currency": "EGP" }, "rate": 1, "localAmount": 1500 }. وحقول التاريخ تحمل تلميح format: التاريخ يُكتب باليوم أولًا dd-MM-yyyy أو بصيغة ISO yyyy-MM-dd، والتاريخ مع الوقت yyyy-MM-dd'T'HH:mm (والتاريخ وحده يُعامل على أنه منتصف الليل).
import_ImportRecord — استيراد سجلات
يستورد سجلًا أو أكثر بصيغة JSON الخاصة بنما: كائن مفاتيحه أنواع الكيانات وقيمه مصفوفات سجلات.
| المدخل | إلزامي | الوصف |
|---|---|---|
recordsJson | نعم | السجلات المراد استيرادها |
importMode | نعم | CreateOnly: إضافة فقط — الكود الموجود مسبقًا خطأ؛ UpdateOnly: تعديل الموجود فقط — الكود غير المعروف خطأ؛ CreateOrUpdate: السماح بالاثنين. تُطابَق السجلات بالكود، لذا CreateOnly هو الخيار الآمن كلما كان القصد الإضافة |
saveAsDraft | لا | true: حفظ كمسودة غير معتمدة — false (الافتراضي): حفظ واعتماد |
appendDetailLines | لا | يؤثر فقط عند تعديل سجل موجود: true يُبقي بنوده الحالية ويضيف المرسلة بعدها — false (الافتراضي) يستبدلها، فأي بند لم يُرسل يُفقد |
الأكواد. المستند الذي يرقّمه دفتره تلقائيًا (أو الملف الرئيسي الذي تُرقّمه مجموعته) لا يحتاج code: اتركه والرقم الحقيقي يُخصَّص عند الاعتماد. ويُقبل أيضًا كود مؤقت يبدأ ببادئة الدفتر وينتهي بـ @draft — مثل JE1000@draft — ويُستبدل بالطريقة نفسها. اللاحقة @draft تعني فقط أن الكود مؤقت؛ أما اعتماد السجل من عدمه فيقرره saveAsDraft وحده. وقد يعود سجل معتمد بحالة بانتظار الاعتماد حين ينطبق عليه تعريف اعتماد — وهذا من ميزة الاعتمادات لا من الاستيراد.
الشكل العام:
{"SalesInvoice": [
{
"book": "SalesInvoice$#SINV",
"valueDate": "01-02-2024",
"customer": "10011",
"details": [
{ "item": { "itemCode": "9999", "item": "9999" },
"quantity": { "quantity": { "primeQty": { "value": 1, "uom": "SRV" } } },
"price": { "unitPrice": 100 } }
]
}
]}بنود فاتورة المبيعات هي جدولها التفصيلي details. والمراجع — كالعميل والصنف — تُكتب بالكود. ويُكتب الدفتر أو التوجيه بالشكل <نوع الكيان>$#<الكود>، كما في "book": "SalesInvoice$#SINV": نوع الكيان الذي يتبعه ثم كوده. وهذا الشكل نفسه مشروح حقلًا حقلًا في صفحة تشريح ملف التصدير. والبنية الدقيقة لكل كيان هي ما تعيده أداة GetImportSchema؛ والأسلوب الأضمن أن يقرأ العميل سجلًا موجودًا بأداة GetRecord ويحاكي شكله.
يبدأ السجل الجديد من السجل الفارغ نفسه الذي تعرضه الشاشة عند الإضافة، فيملؤه قالب القيم الافتراضية الخاص بالمستخدم أولًا ثم تُوضع الحقول المستوردة فوقه — والحقل الذي لا يرسله الاستيراد يبقى على قيمة القالب.
تُحفظ السجلات عبر بوابة الكيانات القياسية، فتعمل كل قواعد التحقق والتأثيرات (القيود، الحركات المخزنية، ...) كما لو أُدخل السجل من الشاشة. وإذا فشل سجل، تُعاد تفاصيل الخطأ للنموذج ليصححه ويعيد المحاولة.
المرفقات. لا يستطيع حقل المرفق أن يحمل الملف نفسه، لذا يأخذ بدلًا منه كائنًا صغيرًا: {"uploadId":"<token>"} — وهو بالضبط قيمة importValue التي أعادتها PrepareAttachmentUpload بعد إرسال الملف إلى رابطها — أو {"url":"<http or https address>"} الذي يجعل الخادم ينزّل الملف بنفسه. ويمكن لأي منهما أن يضيف "fileName" ليُحفظ الملف باسم آخر. وتخضع صيغة url للقواعد نفسها المتبعة في واجهة REST: لا عناوين على الخادم ذاته ولا على شبكة خاصة، و50 ميجابايت حدًا أقصى افتراضيًا — انظر قسم «رفع الملفات وإرفاقها» في صفحة واجهة برمجية REST لنظام نما. وإعطاء uploadId وurl معًا يُفشل السجل؛ أما الكائن الخالي منهما — مثل كائن {"id", "fileName", "size"} الذي تعيده GetRecord — فيُتجاهل ويبقى المرفق على حاله. والنص المجرّد، ومنه مسار الملف، لا يُقبل أبدًا: فهو يُفشل السجل برسالة بالإنجليزية تشرح صيغتي الكائن.
import_PrepareAttachmentUpload — رابط لرفع ملف
الخطوة الأولى لإرفاق ملف بسجل. تعيد رابطًا يُستخدم مرة واحدة يرسل إليه المساعد الملف، والقيمة التي توضع بعد ذلك في حقل المرفق.
| المدخل | إلزامي | الوصف |
|---|---|---|
fileName | لا | الاسم الذي يُحفظ به المرفق مع امتداده، مثل invoice-1001.pdf. إن تُرك فارغًا يُستخدم الاسم الذي يحمله الملف المرفوع |
تحمل الإجابة uploadUrl، وimportValue (جاهزة على شكل الكائن {"uploadId":"<token>"})، وأكبر حجم مقبول بالبايت، ومدة صلاحية الرابط والملف المرفوع. بعدها يرسل المساعد الملف إلى الرابط بطلب HTTP من نوع POST (أو PUT)، إما كجسم الطلب الخام أو كملف ضمن نموذج multipart:
curl --data-binary @"invoice-1001.pdf" "<uploadUrl>"
curl -F file=@"invoice-1001.pdf" "<uploadUrl>"لا يُرسل معه مفتاح API — فالرابط نفسه هو التفويض. وأخيرًا يستدعي ImportRecord واضعًا قيمة importValue في حقل المرفق.
- يقبل الرابط ملفًا واحدًا، وتنتهي صلاحيته بعد 15 دقيقة إن لم يُرسل إليه شيء.
- بعد الرفع يبقى الملف قابلًا للإرفاق 60 دقيقة، فإن رُفض الاستيراد بسبب قاعدة تحقق أمكن تصحيحه وإعادة إرساله بقيمة
importValueنفسها. - لا يستطيع إرفاق الملف إلا مستخدم نما نفسه الذي جهّز الرفع.
- أكبر حجم مقبول 50 ميجابايت افتراضيًا، ويمكن تغييره بالخاصية
ai-upload-max-file-size-mbفيnama.properties.
import_PrepareAttachmentDownload — رابط لتنزيل مرفق
الاتجاه المعاكس: جلب ملف مرفق بسجل حتى يحفظه المساعد محليًا ويقرأه.
| المدخل | إلزامي | الوصف |
|---|---|---|
entityType | نعم | نوع كيان السجل |
idOrCode | نعم | كود السجل أو معرّفه |
fieldId | نعم | معرّف حقل المرفق كما يظهر في مخطط الاستيراد. ولحقل في جدول تفصيلي أعطِ المعرّف الكامل collection.field |
lineNumber | لا | رقم البند بدءًا من 1 — إلزامي لحقل في جدول تفصيلي |
يُقرأ السجل عبر فحوص الصلاحيات المعتادة، فيجب أن يكون المستخدم مسموحًا له برؤيته. وحقل الرأس يُقرأ وحده — عمود واحد — فتبقى كلفته واحدة مهما كثرت بنود السجل. أما الحقل في جدول تفصيلي فيقرأ السجل كاملًا؛ وفي سجل كثير البنود استخدم أداة التنزيل بالمعرّف أدناه بدلًا منه. وتحمل الإجابة اسم الملف وحجمه، ورابط downloadUrl يُستخدم مرة واحدة، وأمرًا جاهزًا:
curl -o "<file name>" "<downloadUrl>"يعمل الرابط مرة واحدة ولمدة 10 دقائق؛ وإن فشل التنزيل فجهّزه من جديد.
import_PrepareAttachmentDownloadById — رابط تنزيل من معرّف المرفق
الرابط نفسه ذو الاستخدام الواحد، لكنه يُجهَّز من معرّف المرفق نفسه بدلًا من سجل وحقل.
| المدخل | إلزامي | الوصف |
|---|---|---|
attachmentId | نعم | قيمة id من كائن {"id", "fileName", "size"} الذي أعادته GetRecord أو FindRecords لحقل مرفق |
لا تقرأ هذه الأداة إلا الملف، ولهذا فهي الطريقة الرخيصة لجلب مرفق بند واحد من سجل كبير: تسرد FindRecords مرفقات البنود، وتحوّل هذه الأداة المعرّف id المختار إلى رابط — انظر قسم «نقل ملفات المرفقات» أدناه. والرابط كسابقه: يعمل مرة واحدة، ولمدة 10 دقائق، دون مفتاح API.
ولا تتحقق الأداة من أن المستخدم مسموح له برؤية السجل الذي ينتمي إليه المرفق: فأي مستخدم مسجَّل الدخول يملك المعرّف يستطيع جلب الملف، تمامًا كروابط المرفقات في شاشات نما نفسها. أما PrepareAttachmentDownload فتتحقق من صلاحية الوصول إلى السجل.
سيناريو عمل متكامل
النمط المعتاد الذي يتبعه عميل MCP لاستيراد بيانات:
- import_ResolveEntityType: «فاتورة مبيعات» ←
SalesInvoice. - import_GetImportSchema: معرفة الحقول الإلزامية وبنية بنود الفاتورة.
- import_GetEnumValues: القيم الصحيحة لحقول القوائم (نوع الخصم مثلًا).
- import_FindRecords: إيجاد أكواد المراجع (العميل، الصنف) قبل استخدامها.
- import_ImportRecord: الاستيراد كمسودة أولًا للمراجعة، أو حفظ واعتماد مباشرة.
- import_GetRecord: قراءة السجل المستورد للتحقق من النتيجة.
نقل ملفات المرفقات
نداء أداة MCP يحمل نصًا فقط، لذا لا تمرّر أدوات المرفقات أي ملف داخل المحادثة، بل تعطي المساعد رابطًا ينقل عبره الملف بأمر curl. ولهذا لا تفيد إلا المساعدين القادرين على تشغيل الأوامر — مثل Claude Code أو تبويب Code في Claude Desktop. هذا مثال معتاد لطلب «أرفق العقد الموقَّع بالعميل CUST001»:
- import_PrepareAttachmentUpload مع
fileName=contract-cust001.pdf←uploadUrlوimportValue={"uploadId":"<token>"}. curl --data-binary @"contract-cust001.pdf" "<uploadUrl>"— يشغّله المساعد على جهازك.- import_ImportRecord مع
importMode=UpdateOnlyو{"Customer":[{"code":"CUST001","attachment":{"uploadId":"<token>"}}]}. - import_PrepareAttachmentDownload على الحقل نفسه، إن أردت التحقق مما حُفظ.
أما جلب مرفق من بند تفصيلي في سجل كبير — ملف بند واحد في مستند فيه آلاف البنود مثلًا — فيسير في الاتجاه المعاكس، فلا يُقرأ السجل كاملًا أبدًا:
- import_FindRecords مع
fields=<collection>.<field>وcriteria=code,Equal,<code>,AND;← كائن{"id", "fileName", "size"}لكل بند. - import_PrepareAttachmentDownloadById مع
idالبند المطلوب ← رابطdownloadUrlيُستخدم مرة واحدة. curl -o "<file name>" "<downloadUrl>".
تشير الروابط إلى نقطتين في تطبيق الخدمات بجوار نقطة MCP:
http[s]://<server-ip-or-domain>/basic-services/ai-upload
http[s]://<server-ip-or-domain>/basic-services/ai-downloadوالثانية هي النقطة نفسها التي تخدم روابط التقارير المولَّدة ذات الاستخدام الواحد. الرابطان كاملان (absolute)، ويُبنيان من العنوان الذي استخدمه عميل MCP للوصول إلى الخادم، مع مراعاة ترويستي X-Forwarded-Proto و X-Forwarded-Host. وإن لم يكن هذا العنوان هو ما يستطيع جهاز المساعد الوصول إليه — خلف reverse proxy عادةً — فاضبط ai-file-download-base-url في nama.properties على العنوان العام للخادم، فتُبنى كل الروابط عليه.
تتطلب إصدار 20261007 فأحدث
أدوات المرفقات، وقيم المرفقات في ImportRecord، لا توجد إلا في الخوادم من إصدار 20261007 فصاعدًا.
رسائل قد تظهر لك
حين يرفض الخادم الاتصال يرد على كل طلب بـ HTTP 401 ونص يبدأ بـ MCP authentication failed:. وتعرضه العملاء عادةً كاتصال فاشل، والنص موجود في تفاصيل الاتصال أو سجله. هذه الرسائل بالإنجليزية فقط، فتظهر كما هي حتى على التركيبات العربية.
| الرسالة | السبب | ما العمل |
|---|---|---|
| MCP authentication failed: Missing API key | لم يحمل الطلب ترويسة X-API-Key (ولا المعامل apiKey / clientId) ولا رمز Bearer. | أضف ترويسة X-API-Key إلى إعداد العميل بالتهجئة نفسها. |
| MCP authentication failed: Invalid API key | المفتاح لا يطابق أي سجل API Credentials معتمد — خطأ في النسخ، أو من خادم آخر، أو حُذف السجل. | انسخ API Key (Client Secret) من السجل على هذا الخادم من جديد (علّم View API Key واحفظ). |
| MCP authentication failed: Invalid API secret | حمل X-API-Key حقل Client Id (Can Be Ignored) من السجل، وX-API-Secret مفقود أو خاطئ. | أرسل API Key (Client Secret) في X-API-Key واستغنِ عن X-API-Secret. |
| MCP authentication failed: Your API key expired on {0} | مضى تاريخ صالح حتي في السجل. | مدّد صالح حتي في السجل، أو أنشئ سجلًا جديدًا. |
| MCP authentication failed: Your API key can be used only after {0} | تاريخ صالح من في السجل ما زال في المستقبل. | انتظر، أو قدّم تاريخ صالح من. |
| MCP authentication failed: The provided API key is prevented from login | منع الدخول معلَّم في السجل. | ألغِ تعليمه إن كان يجب أن يعمل الاتصال. |
| MCP authentication failed: MCP subscription expired on {0} | انتهى اشتراك MCP في ترخيص الخادم في ذلك التاريخ (مكتوبًا yyyy-MM-dd). وقد يكون كل ما عداه سليمًا — فالمفتاح نفسه كان يعمل في اليوم السابق. | جدّد اشتراك MCP مع نما؛ ولا حاجة لتغيير المفتاح. |
أما HTTP 404 على المسار /basic-services/mcp فأمر مختلف: وحدة الذكاء الاصطناعي غير مركبة على ذلك الخادم، فلا يوجد خادم MCP ليرد.