تخطَّ إلى المحتوى

دورة حياة MCP أثناء التشغيل

يصف هذا المستند كيفية اكتشاف خوادم MCP والاتصال بها وعرضها كأدوات وتحديثها وإيقافها في بيئة تشغيل coding-agent.

نظرة عامة على دورة الحياة

Section titled “نظرة عامة على دورة الحياة”
  1. بدء تشغيل SDK يستدعي discoverAndLoadMCPTools() (ما لم يكن MCP معطلاً).
  2. الاكتشاف (loadAllMCPConfigs) يحل تكوينات خوادم MCP من مصادر القدرات، ويرشح الإدخالات المعطلة/الخاصة بالمشروع/Exa، ويحتفظ ببيانات المصدر الوصفية.
  3. مرحلة اتصال المدير (MCPManager.connectServers) تبدأ الاتصال لكل خادم + tools/list بشكل متوازٍ.
  4. بوابة البدء السريع تنتظر حتى 250 مللي ثانية، ثم قد تُرجع:
    • أدوات MCPTool محملة بالكامل،
    • حالات فشل لكل خادم،
    • أو أدوات DeferredMCPTool مخزنة مؤقتاً للخوادم التي لا تزال معلقة.
  5. ربط SDK يدمج أدوات MCP في سجل أدوات التشغيل للجلسة.
  6. الجلسة النشطة يمكنها تحديث أدوات MCP عبر تدفقات /mcp (disconnectAll + إعادة اكتشاف + session.refreshMCPTools).
  7. الإيقاف يحدث عندما يستدعي المُستدعون disconnectServer/disconnectAll؛ يقوم المدير أيضاً بمسح تسجيلات أدوات MCP للخوادم المنفصلة.

مرحلة الاكتشاف والتحميل

Section titled “مرحلة الاكتشاف والتحميل”

تقوم createAgentSession() في src/sdk.ts ببدء تشغيل MCP عندما تكون enableMCP قيمتها true (الافتراضي):

  • تستدعي discoverAndLoadMCPTools(cwd, { ... })،
  • تمرر authStorage وتخزين الذاكرة المؤقتة وإعداد mcp.enableProjectConfig،
  • تضبط دائماً filterExa: true،
  • تسجل أخطاء التحميل/الاتصال لكل خادم،
  • تخزن المدير المُرجع في toolSession.mcpManager ونتيجة الجلسة.

إذا كانت enableMCP قيمتها false، يتم تخطي اكتشاف MCP بالكامل.

اكتشاف التكوين والترشيح

Section titled “اكتشاف التكوين والترشيح”

تقوم loadAllMCPConfigs() (src/mcp/config.ts) بتحميل عناصر خادم MCP القياسية من خلال اكتشاف القدرات، ثم تحولها إلى MCPServerConfig القديم.

سلوك الترشيح:

  • enableProjectConfig: false يزيل الإدخالات على مستوى المشروع (_source.level === "project").
  • الخوادم ذات enabled: false يتم تخطيها قبل محاولات الاتصال.
  • خوادم Exa تُرشح بشكل افتراضي ويتم استخراج مفاتيح API لتكامل أداة Exa الأصلية.

تتضمن النتيجة كلاً من configs وsources (بيانات وصفية تُستخدم لاحقاً لتسمية المزود).

سلوك الفشل على مستوى الاكتشاف

Section titled “سلوك الفشل على مستوى الاكتشاف”

تميز discoverAndLoadMCPTools() بين فئتين من الفشل:

  • فشل صعب في الاكتشاف (استثناء من manager.discoverAndConnect، عادةً من اكتشاف التكوين): يُرجع مجموعة أدوات فارغة وخطأ اصطناعي واحد { path: ".mcp.json", error }.
  • فشل وقت التشغيل/الاتصال لكل خادم: يُرجع المدير نجاحاً جزئياً مع خريطة errors؛ تستمر الخوادم الأخرى.

لذا لا يفشل بدء التشغيل جلسة الوكيل بأكملها عند فشل خوادم MCP فردية.

يتتبع MCPManager دورة حياة التشغيل بسجلات منفصلة:

  • #connections: Map<string, MCPServerConnection> — الخوادم المتصلة بالكامل.
  • #pendingConnections: Map<string, Promise<MCPServerConnection>> — المصافحة قيد التقدم.
  • #pendingToolLoads: Map<string, Promise<{ connection, serverTools }>> — متصل لكن الأدوات لا تزال قيد التحميل.
  • #tools: CustomTool[] — عرض أدوات MCP الحالي المعروض للمُستدعين.
  • #sources: Map<string, SourceMeta> — بيانات المزود/المصدر الوصفية حتى قبل اكتمال الاتصال.

تستمد getConnectionStatus(name) الحالة من هذه الخرائط:

  • connected إذا كان في #connections،
  • connecting إذا كان في انتظار الاتصال أو انتظار تحميل الأدوات،
  • disconnected بخلاف ذلك.

إنشاء الاتصال وتوقيت البدء

Section titled “إنشاء الاتصال وتوقيت البدء”

خط أنابيب الاتصال لكل خادم

Section titled “خط أنابيب الاتصال لكل خادم”

لكل خادم مُكتشف في connectServers():

  1. تخزين/تحديث بيانات المصدر الوصفية،
  2. التخطي إذا كان متصلاً/معلقاً بالفعل،
  3. التحقق من حقول النقل (validateServerConfig
  4. حل استبدالات المصادقة/الصَدَفة (#resolveAuthConfig
  5. استدعاء connectToServer(name, resolvedConfig)،
  6. استدعاء listTools(connection)،
  7. تخزين تعريفات الأدوات مؤقتاً (MCPToolCache.set) بأفضل جهد.

سلوك connectToServer() (src/mcp/client.ts):

  • ينشئ نقل stdio أو HTTP/SSE،
  • ينفذ initialize + notifications/initialized لـ MCP،
  • يستخدم مهلة زمنية (config.timeout أو 30 ثانية افتراضياً)،
  • يغلق النقل عند فشل التهيئة.

بوابة البدء السريع + الرجوع المؤجل

Section titled “بوابة البدء السريع + الرجوع المؤجل”

تنتظر connectServers() على سباق بين:

  • تسوية جميع مهام الاتصال/تحميل الأدوات، و
  • STARTUP_TIMEOUT_MS = 250.

بعد 250 مللي ثانية:

  • المهام المكتملة تصبح أدوات MCPTool نشطة،
  • المهام المرفوضة تنتج أخطاء لكل خادم،
  • المهام المعلقة:
    • تستخدم تعريفات الأدوات المخزنة مؤقتاً إن توفرت (MCPToolCache.get) لإنشاء DeferredMCPTool،
    • وإلا تنتظر حتى تتم تسوية تلك المهام المعلقة.

هذا نموذج بدء تشغيل هجين: إرجاع سريع عندما تتوفر الذاكرة المؤقتة، وانتظار صحيح عندما لا تتوفر.

سلوك الإكمال في الخلفية

Section titled “سلوك الإكمال في الخلفية”

كل toolsPromise معلقة لها أيضاً استمرار في الخلفية يقوم في النهاية بـ:

  • استبدال شريحة أدوات ذلك الخادم في حالة المدير عبر #replaceServerTools،
  • كتابة الذاكرة المؤقتة،
  • تسجيل حالات الفشل المتأخرة فقط بعد بدء التشغيل (allowBackgroundLogging).

عرض الأدوات وتوفرها أثناء الجلسة النشطة

Section titled “عرض الأدوات وتوفرها أثناء الجلسة النشطة”

تحول discoverAndLoadMCPTools() أدوات المدير إلى LoadedCustomTool[] وتزين المسارات (mcp:<server> via <providerName> عند معرفته).

ثم تدفع createAgentSession() هذه الأدوات إلى customTools، التي تُغلف وتُضاف إلى سجل أدوات التشغيل بأسماء مثل mcp_<server>_<tool>.

  • MCPTool تستدعي الأدوات من خلال MCPServerConnection متصل بالفعل.
  • DeferredMCPTool تنتظر waitForConnection(server) قبل الاستدعاء؛ هذا يسمح للأدوات المخزنة مؤقتاً بالوجود قبل أن يكون الاتصال جاهزاً.

كلاهما يُرجع مخرجات أدوات منظمة ويحول أخطاء النقل/الأدوات إلى محتوى أداة MCP error: ... (الإحباط يبقى إحباطاً).

مسارات التحديث/إعادة التحميل (البدء مقابل إعادة التحميل المباشر)

Section titled “مسارات التحديث/إعادة التحميل (البدء مقابل إعادة التحميل المباشر)”
  • اكتشاف/تحميل لمرة واحدة في sdk.ts،
  • يتم تسجيل الأدوات في سجل أدوات الجلسة الأولي.

مسار إعادة التحميل التفاعلي

Section titled “مسار إعادة التحميل التفاعلي”

مسار /mcp reload (src/modes/controllers/mcp-command-controller.ts) يقوم بـ:

  1. mcpManager.disconnectAll()،
  2. mcpManager.discoverAndConnect()،
  3. session.refreshMCPTools(mcpManager.getTools()).

تقوم session.refreshMCPTools() (src/session/agent-session.ts) بإزالة جميع أدوات mcp_، وإعادة تغليف أحدث أدوات MCP، وإعادة تفعيل مجموعة الأدوات بحيث تُطبق تغييرات MCP دون إعادة تشغيل الجلسة.

يوجد أيضاً مسار متابعة للاتصالات المتأخرة: بعد انتظار خادم محدد، إذا أصبحت الحالة connected، يُعاد تشغيل session.refreshMCPTools(...) بحيث يتم إعادة ربط الأدوات المتاحة حديثاً في الجلسة.

الصحة وإعادة الاتصال وسلوك الفشل الجزئي

Section titled “الصحة وإعادة الاتصال وسلوك الفشل الجزئي”

سلوك التشغيل الحالي بسيط عمداً:

  • لا يوجد مراقب صحة مستقل في المدير/العميل.
  • لا توجد حلقة إعادة اتصال تلقائية عند انقطاع النقل.
  • المدير لا يشترك في أحداث onClose/onError للنقل؛ الحالة مدفوعة بالسجل.
  • إعادة الاتصال صريحة: تدفق إعادة التحميل أو استدعاء connectServers() المباشر.

من الناحية التشغيلية:

  • فشل خادم واحد لا يزيل الأدوات من الخوادم السليمة،
  • حالات فشل الاتصال/القائمة معزولة لكل خادم،
  • ذاكرة الأدوات المؤقتة والتحديثات في الخلفية تتم بأفضل جهد (يتم تسجيل التحذيرات/الأخطاء، بدون توقف صعب).

disconnectServer(name):

  • يزيل الإدخالات المعلقة/بيانات المصدر الوصفية،
  • يغلق النقل إذا كان متصلاً،
  • يزيل أدوات mcp_ الخاصة بذلك الخادم من حالة المدير.

disconnectAll():

  • يغلق جميع وسائل النقل النشطة باستخدام Promise.allSettled،
  • يمسح الخرائط المعلقة والمصادر والاتصالات وقائمة أدوات المدير.

في الربط الحالي، يُستخدم الإيقاف الصريح في تدفقات أوامر MCP (لإعادة التحميل/الإزالة/التعطيل). لا يوجد خطاف تخلص تلقائي منفصل للمدير في مسار البدء نفسه؛ المُستدعون مسؤولون عن استدعاء طرق فصل المدير عندما يحتاجون إلى إيقاف MCP محدد.

السيناريوالسلوكفشل صعب مقابل أفضل جهد
فشل الاكتشاف (مسار تحميل القدرات/التكوين)يُرجع المُحمّل أدوات فارغة + خطأ .mcp.json اصطناعيبدء تشغيل الجلسة بأفضل جهد
تكوين خادم غير صالحيتم تخطي الخادم مع إدخال خطأ تحققأفضل جهد لكل خادم
مهلة اتصال/فشل تهيئةيتم تسجيل خطأ الخادم؛ تستمر الخوادم الأخرىأفضل جهد لكل خادم
tools/list لا يزال معلقاً عند البدء مع وجود ذاكرة مؤقتةيتم إرجاع أدوات مؤجلة فوراًبدء تشغيل سريع بأفضل جهد
tools/list لا يزال معلقاً عند البدء بدون ذاكرة مؤقتةينتظر البدء حتى تتم تسوية المعلقاتانتظار صعب للصحة
فشل تحميل أدوات متأخر في الخلفيةيتم التسجيل بعد بوابة البدءتسجيل بأفضل جهد
انقطاع النقل أثناء التشغيللا إعادة اتصال تلقائية؛ تفشل الاستدعاءات المستقبلية حتى إعادة الاتصال/التحميلاستعادة بأفضل جهد عبر إجراء يدوي

يُعيد src/mcp/index.ts تصدير واجهات المُحمّل/المدير/العميل للمُستدعين الخارجيين. يعرض src/sdk.ts دالة discoverMCPServers() كغلاف ملائم يُرجع نفس شكل نتيجة المُحمّل.

  • src/mcp/loader.ts — واجهة المُحمّل، تطبيع أخطاء الاكتشاف، تحويل LoadedCustomTool.
  • src/mcp/manager.ts — سجلات حالة دورة الحياة، تدفق الاتصال/القائمة المتوازي، التحديث/الفصل.
  • src/mcp/client.ts — إعداد النقل، مصافحة التهيئة، القائمة/الاستدعاء/الفصل.
  • src/mcp/index.ts — صادرات واجهة وحدة MCP.
  • src/sdk.ts — ربط البدء في سجل الجلسة/الأدوات.
  • src/mcp/config.ts — اكتشاف/ترشيح/تحقق التكوين المُستخدم من المدير.
  • src/mcp/tool-bridge.ts — سلوك MCPTool وDeferredMCPTool أثناء التشغيل.
  • src/session/agent-session.ts — إعادة ربط refreshMCPTools المباشرة.
  • src/modes/controllers/mcp-command-controller.ts — تدفقات إعادة التحميل/إعادة الاتصال التفاعلية.
  • src/task/executor.ts — توكيل MCP للوكيل الفرعي عبر اتصالات المدير الأب.