في هذه الصفحة
في 21 سبتمبر 2026، عند الساعة 00:33 بالتوقيت العالمي المنسق، نشر Tobi Lütke ما يلي: «نقاش MCP مقابل CLI لنماذج اللغة الكبيرة نقاش خاطئ. الناس يتجادلون في الطبقة الخاطئة». ثم، في 23 أكتوبر، أشار إلى مستودع جديد اسمه dquickts. إنه نسخة متفرعة من QuickJS تستطيع إيقاف برنامج مؤقتًا في منتصف حلقة for، وكتابة ذاكرته الكاملة على هيئة بايتات، واستئنافه في عملية أخرى. وكتب: «بيئة ممتازة لوضع الكود».
إنه محق بشأن الطبقة. أريد أن أتفق معه أولًا، بكلماته هو، ثم أضيّق الادعاء حتى يقول شيئًا تستطيع المزامنة الاستفادة منه.
الطبقة التي يقصدها
إليك الحجة كما صاغها، فهذه هي الطريقة العادلة الوحيدة لاقتباس حجة تنوي ثنيها:
كلاهما يعمل بشكل مذهل ما دام يُشغَّل عبر بيئة شبيهة بـ REPL قادرة على حفظ الحالة. الطريف في CLI أن أدواته تُستخدم عادةً عبر BASH، الذي يصادف أنه REPL ذو حالة دائمة (نظام الملفات)، ولذلك يعمل CLI أفضل بكثير من MCP. لكن هذا ليس قريبًا حتى من أن يكون خاصية جوهرية في MCP. كل ما يعنيه أننا نحتاج إلى بيئات تشغيل أفضل.
هذا صحيح، وهو يفسّر ملاحظة أبداها كثيرون دون تفسير. الوكيل الذي يُعطى CLI يكتب ملفًا، ثم يقرؤه بعد ثلاث خطوات، ويبحث فيه بـ grep، ويمرّره عبر أنبوب. أما الوكيل الذي يُعطى خادم MCP مجردًا فيحصل على نتيجة واحدة لكل استدعاء، وعليه أن يحمل كل ما سواها في نافذة السياق. لم يفز CLI بسبب البروتوكول. فاز لأن bash جاء ومعه مكان توضع فيه الأشياء.
ومن هنا يأتي رهانه. سيبني أحدهم محركًا قابلًا للتضمين على طراز SQLite يحوّل bash أو TypeScript أو استدعاءات الأدوات إلى خطة واحدة، تُفحص قبل تشغيلها وتُبنى للتنفيذ الدائم. وdquickts خطوة نحو ذلك. يصف ملف README الخاص به بيئة REPL «تبقى دوالها ومتغيراتها بعد إعادة التشغيل». ويصف أيضًا استدعاء مضيف دائمًا: «يستدعي نص برمجي دالة مضيف تصل إجابتها بعد ساعات. تحفظ العملية النص البرمجي وتخرج».
حتى الآن، اتفاق تام. والآن إلى التضييق.
أي حالة، لأي مهمة
عبارة «حفظ الحالة» تخفي سؤالًا: حالة من، وبأي شكل؟ بالنسبة إلى وكيل برمجة، الحالة هي المستودع والصدفة، وREPL يبقى بعد إعادة التشغيل إجابة جيدة. أما بالنسبة إلى وكيل يبني مزامنة بين نظامين من أنظمة SaaS، فالحالة التي يحتاجها بين الخطوات تحددها المهمة نفسها مسبقًا. تحملها أربعة سجلات، وليس أيٌّ منها متغيرًا في نص برمجي.
المؤشر. تقرأ المزامنة المصدر على شكل نوافذ، وعليها أن تعرف أين انتهت النافذة الأخيرة. في محرك المزامنة لدى Tajo، هذا مؤشر مخزّن لكل مزامنة ونطاق، يُكتب بعد كل دفعة لا يفشل فيها أي سجل، ويكمل التشغيل التالي منه. يخزّن التشغيل المجدول نقطة بدايته قبل أن يفعل أي شيء آخر، فإذا فشل التشغيل الأول قرأ التشغيل التالي من النقطة نفسها. المبدأ الكامن وراء ذلك، أي إرسال الفرق وعدم إرسال الجدول أبدًا، موجود في شرح Reverse ETL. سأترك المؤشر هناك.
المقترح المعلّق. في أدوات MCP الخاصة بموصلات Tajo، تتكون الكتابة من استدعاءين. يتحقق brevo_propose من المدخلات مقابل الإجراء المعلَن ويسجّل مقترحًا. لا يُرسَل شيء. تحمل النتيجة معرّف المقترح، وعندما يتعين على شخص أن يقرر، الصفحة التي يوافق فيها عليه. ينفّذ brevo_apply الكتابات المعتمدة لذلك الاتصال بالترتيب، ويتوقف عند أول كتابة ما زالت تنتظر شخصًا. السجل الذي بينهما هو الحالة. يحتفظ بالمدخلات وبملخص لها، فلا يمكن تعديل كتابة معتمدة بين القرار والتطبيق. ولا يحتفظ بقيم استجابة المزوّد، لأن سجل موافقات لا يقبل إلا الإضافة يجب ألا يتحول إلى مخزن للبيانات الشخصية.
عقد الإيجار. يمسك كل تشغيل للمزامنة بعقد إيجار حصري واحد طوال عمره، مع رمز مالك، ومهلة زمنية مدتها خمس عشرة دقيقة افتراضيًا، وإمكانية التجديد. لا يستطيع مالك قديم أن يحرر عقد إيجار أحدث. وإذا تعذّر الوصول إلى مخزن عقود الإيجار، يرفض التشغيل أن يبدأ بدلًا من التخمين. أي عامل يمسك بالتشغيل حقيقةٌ مسجلة في عقد الإيجار، لا في ذاكرة أي عملية.
الخطة. يقرأ syncs.dryRun النافذة التالية من المؤشر، ويحدد لكل سجل إن كان إدراجًا أو تحديثًا أو حذفًا أو دون تغيير، ويكتب صفًا واحدًا بالضبط: الخطة، وتُحفظ لمدة ساعة. لا يحرّك أي مؤشر ولا يكتب شيئًا في أيٍّ من النظامين. يكتب syncs.apply تلك الخطة مرة واحدة. ويرفض إذا تحرك المؤشر، أو إذا تغيرت حصة من السجلات تتجاوز الحد المسموح به في هذه الأثناء. والتكرار يعيد النتيجة الأولى بدلًا من الكتابة مجددًا.
هذه هي الحالة بين الخطوات: أربعة سجلات لها معرّفات، يستطيع قراءتها أي وكيل مسموح له برؤيتها.
لماذا لا يحتفظ جانب MCP بأي شيء داخل الجلسة
ما إن تصبح الحالة في السجلات حتى لا يبقى للجلسة ما تحتفظ به. لذلك لا تحتفظ نقاط نهاية MCP في Tajo بجلسة. يحصل كل طلب على خادم جديد وطبقة نقل بلا معرّف جلسة. القراءات طلب واحد لكل استدعاء، مع حد أقصى للنتائج حتى لا تُغرق إجابة واحدة دورة كاملة. والكتابات اقتراح ثم تطبيق، وما تحمله معك هو معرّف المقترح.
وتحرّك البروتوكول في الاتجاه نفسه. فقد أزالت مراجعة 2026-07-28 لمواصفة MCP الجلسات على مستوى البروتوكول وترويسة Mcp-Session-Id من طبقة النقل Streamable HTTP. الخادم الذي يحتاج إلى الاستمرارية يصدر الآن مقبضه الخاص ويستعيده كوسيط عادي. وهذا بالضبط ما هو معرّف المقترح. يتناول مقال ما هو خادم MCP تلك المراجعة وكيف يختلف استدعاء أداة عن مزامنة دائمة؛ أما هذا المقال فيتناول فقط أين تذهب الحالة.
والنتيجة هي ما يهم في عمل التكامل. لنفترض أن وكيلًا في Claude Code اقترح كتابة ثم انتهت جلسته. يوافق الشخص عليها بعد ساعة. يستدعي وكيل في عميل مختلف، أو الوكيل نفسه في اليوم التالي، التطبيق باستخدام المعرّف، فتُنفَّذ الكتابة مرة واحدة. الوكيل الذي تعطّل يخسر نافذة السياق ولا شيء غيرها. لم يُعلَّق شيء، فلم يكن هناك ما يلزم استئنافه.
ما ليس لدينا، وكم يكلّف
الاعتراض الصادق يأتي من جهة REPL، ويقول ما يلي: «حسنًا، سجلاتك تبقى. لكن كل استدعاء يعيد قراءة ما كان لدى الاستدعاء السابق أصلًا. كان النص البرمجي سيجلب جهات الاتصال مرة واحدة، ويدمجها، ويصفّيها، ويعيد رقمًا. أما وكيلك فيجري خمسة استدعاءات ويدفع ثمن كل واحد منها». هذا الاعتراض محق بشأن الآلية، ونحن لم نقِس الثمن. التقييم الذي يعدّ الاستدعاءات لكل مهمة مع حالة محمولة ودونها لم يُبنَ بعد. وإلى أن يُبنى، يبقى الادعاء بأن وضع الاستدعاءات يستهلك رموزًا أكثر بلا إجابة.
ثلاثة أمور أخرى يجب أن تُقال بوضوح، لأن القارئ الذي ينهي هذا المقال يجب ألا يتخيلها:
- لا يُشغَّل اليوم أي كود يكتبه العملاء. قراءات الموصلات طلب واحد لكل استدعاء، بلا بيئة معزولة في المسار. يوجد مشغّل كود ضمن منظومتنا، وهو أداة داخلية. في بيئة الإنتاج يكون معطّلًا ما لم يُضبط علمان منفصلان، ولا يستجيب إلا للمسؤولين. يحصل كل استدعاء على سياق جديد، وروابط لا تسمح إلا بالقراءة، وميزانية مدتها ثانيتان للكود المتزامن. وتقول ترويسته نفسها بأحرف كبيرة إنه حدّ للصحة، لا حدّ أمني.
- لا يوجد REPL. لا شيء يحسبه الوكيل في استدعاء يكون متاحًا للاستدعاء التالي، ما لم يُكتب كسجل له معرّف.
- لا توجد جلسة وكيل دائمة. يحتفظ العميل بمحادثته. ويحتفظ Tajo بالمقترحات والخطط والمؤشرات وعقود الإيجار. لا يوجد شيء ثالث.
ما فائدة المحرك الدائم
لا شيء من هذا حجة ضد dquickts. يسرد ملف README الخاص به ما تصلح له اللقطات، والقائمة جيدة. إسبات نص برمجي خامل وتحرير ذاكرته. تشغيل عملية حسابية طويلة على شرائح في أي عامل يكون متاحًا. البدء السريع لكل نسخة من لقطة بدلًا من تكرار الإعداد. إيقاف نص برمجي عند استدعاء مضيف تصل إجابته لاحقًا. وبالنسبة إلى مساحة عمل وكيل برمجة، أو دفتر ملاحظات يجب أن يبقى بعد إعادة التشغيل، فهذه هي الأداة المناسبة.
ومع ذلك يجب ألا تعتمد المزامنة عليه، لثلاثة أسباب يقدّمها لي ملف README نفسه. أولًا: «لا يُحمَّل ملف الجلسة إلا في إصدار qjs الذي كتبه». الذاكرة التي كتبها إصدار من المحرك تصبح ملفًا ميتًا بعد الترقية؛ أما المؤشر فمجرد سلسلة نصية. ثانيًا: «اللقطات مدخلات موثوقة، مثل الكود الثنائي»، و«اللقطات الخبيثة لا تُكتشف». الذاكرة المخزّنة شيء يجب أن تحميه، لا شيء تستطيع مراجعته؛ أما المقترح فصف يقرؤه شخص قبل أن يوافق عليه. ثالثًا، تحمل اللقطة كل ما قرأه النص البرمجي، بما في ذلك سجلات العملاء. أما السجلات المذكورة أعلاه فمبنية على العكس: تخزّن الخطة ملخصات لا قيمًا، ولا يخزّن سجل المقترح استجابة المزوّد أبدًا.
من القواعد التي نبني وفقها أن الحتمي يتفوق على الذكي. الذاكرة التي تُستأنف من منتصف حلقة ذكية. أما المؤشر والمقترح وعقد الإيجار والخطة فمملة، وقابلة للفحص، ومتطابقة على كل محرك، وفي كل عميل، وبعد كل تعطّل.
طرح Lütke السؤال الصحيح. أين تعيش الحالة؟ في المزامنة، لم تكن الإجابة لتكون داخل العملية أبدًا. كانت دائمًا ستكون في السجلات، لأن هناك يجب أن يتمكن الشخص الذي يوافق على الكتابة من قراءتها.
الأسئلة المتكررة
أيهما أفضل لوكلاء الذكاء الاصطناعي: MCP أم CLI؟
لا هذا ولا ذاك بمفرده. تبقى فكرة Tobi Lütke التي طرحها في 21 سبتمبر 2026 صحيحة: كلاهما يعمل متى مرّت الاستدعاءات عبر شيء يحفظ الحالة بين الخطوات. يبدو CLI أفضل اليوم لأن bash يحفظ الحالة في نظام الملفات. الفرق ليس في البروتوكول، بل في بيئة التشغيل.
ما الحالة التي يحتاجها الوكيل بين خطوات المزامنة؟
سجلات التكامل نفسه: مؤشر يحدد أين توقف التشغيل الأخير، ومقترح ينتظر موافقة شخص ما، وعقد إيجار يحدد أي عامل يمسك بالتشغيل، وخطة تشغيل تجريبي يجب أن يطابقها التطبيق. لا شيء من ذلك متغير في نص برمجي. كلها صفوف لها معرّفات.
لماذا لا يحتفظ خادم MCP في Tajo بأي شيء داخل الجلسة؟
يحصل كل طلب على خادم جديد وطبقة نقل بلا معرّف جلسة. كل ما يحتاجه الاستدعاء التالي هو سجل: معرّف مقترح، أو معرّف خطة، أو مؤشر. لذلك يستطيع وكيل ثانٍ، في عميل مختلف، أن يكمل من حيث توقف الأول، ولا يخسر الوكيل الذي تعطّل شيئًا سوى نافذة السياق الخاصة به.
هل يشغّل Tajo كودًا يكتبه الوكلاء؟
ليس للعملاء. القراءات على أدوات الموصلات طلب واحد لكل استدعاء، بلا بيئة معزولة. مشغّل الكود الموجود أداة داخلية خلف علمين، لا يصل إليها إلا المسؤولون، بروابط للقراءة فقط وسياق جديد لكل استدعاء. وهو يقول عن نفسه إنه ليس حدًّا أمنيًّا. لا يوجد REPL ولا جلسة دائمة.
ما فائدة محرك JavaScript دائم مثل dquickts؟
يذكر ملف README الخاص به الاستخدامات: إسبات نص برمجي خامل، وتقسيم عملية حسابية طويلة على عدة عمّال، والبدء السريع من لقطة، وإيقاف نص برمجي عند استدعاء مضيف تصل إجابته بعد ساعات. كلها حقيقية. ومع ذلك يجب ألا تعتمد المزامنة على محرك كهذا: فاللقطة لا تُحمَّل إلا في إصدار المحرك الذي كتبها، وهي معتمة بالنسبة إلى المراجع، وتحمل أي بيانات عملاء قرأها النص البرمجي.