بناء عميل MCP: اكتشاف، توجيه، والعودة إلى العصر المزدوج
Type: Build
Languages: Python
Prerequisites: Phase 13, Lesson 07
Time: ~85 minutes
أهداف التعلم
- بناء كل MCP
2026-07-28الطلب مع البيانات المعدنية الحالية. - استكشاف الخوادم الاستوديو مع
server/discoverو اختر نسخة تدعمها بعضها البعض - أذن بمسح التراث المحدود فقط لأقران مسموحين صراحة.
- تقبل عصر التراث فقط بعد التحقق من إيجابية
initializeالنتيجة لإعادة النظر المدعومة. - دمج قائمة أدوات تحديدية دون تغطية الصدامات بصمت.
- اتصالات طريق إلى الزميل الذي يمتلك كل أداة دون اختراع جلسات بروتوكول.
المشكلة
عادة ما يتحدث وكيل المضيف إلى أكثر من خادم MCP واحد. يجب أن يكتشف كل خادم ، ودمج كتالوجات الأدوات ، وحل الأسماء المكررة ، ومكالمات الطريق ، والعلاج من فشل النقل.
- نعم
2026-07-28يسهل مراجعة حالة الاستقرار لأن كل طلب مستقل. يجعلها التوافق أكثر دقة. قد يواجه العميل:
- خادم حديث يدعم الإصدار المفضل
- خادم حديث يعيد نسخة معترف بها أو خطأ رأس؛
- خادم سابق لم يسمع به من قبل
server/discover(إنه) - خادم سابق يبقى صامتًا حتى يتلقى
initialize. . .
يعتبر التعامل مع كل خطأ في المراقبة كإرث خطير. الطلب الحديث المخطئ، الخادم المفرط، العملية الميتة، وخادم قديم يمكن أن ينتج جميعًا نفس الوقت أو إغلاق الاتصال. هذه الإشارات غير واضحة. يجب على العميل الجمع بين نية المشغل الصريحة مع دليل بروتوكول إيجابي قبل اختيار عصر الإرث.
المفهوم
زميل، وليس جلسة بروتوكول
الحفاظ على سجل نقل واحد لجميع عمليات الخادم أو نقاط النهاية:
- وظيفة التحويل أو إرسال؛
- عصر و نسخة البروتوكول المختارة
- آخر قدرات الخادم التي اكتشفتها؛
- قائمة أدوات تحديد الأخيرة
- بطلبات الهوية المعلقة للتصديق؛
- الصحة النقلية
هذا هو الحسابات العميل. انها ليست حالة جلسة بروتوكول. على MCP الحديثة، الخادم لا يزال يتلقى النسخة الحالية والقدرات على كل طلب.
بناء كل طلب حديث من الصفر
pythondef modern_request(request_id, method, params, version, capabilities):
return {
"jsonrpc": "2.0",
"id": request_id,
"method": method,
"params": {
**params,
"_meta": {
"io.modelcontextprotocol/protocolVersion": version,
"io.modelcontextprotocol/clientCapabilities": capabilities,
"io.modelcontextprotocol/clientInfo": CLIENT_INFO,
},
},
}لا تضع البيانات المعدنية مرة واحدة على كائن الاتصال وتفترض أنها وصلت إلى الأسلاك.
اكتشاف حديث
server/discoverيعود الإصدارات المدعومة، وقدرات الخادم، والتعليمات، وتلميحات التخزين الآلي، و هوية الخادم الموصى بها. يختار العميل أعلى إصدار جديد مدعوم بشكل متبادل.
اكتشاف هو اختياري لعميل حديث فقط، ولكن يوصى به على الاستوديوه. بعض الخوادم القديمة تقبل عملية قبل البدء، لذلك إرسال tools/listيمكن أن يؤدي ذلك إلى نجاح غير واضحserver/discoverيخلق حدود عصرا نظيفة
صنعة التوافق مع الاستديو
موكيل استديو من عصر مزدوج يرسلserver/discoverمع البيانات المعدنية الحديثة المفضلة قبل أي طلب آخر. هناك ثلاث فئات النتيجة:
- DiscoverResult.الخادم حديث، اختر نسخة مدعومة بشكل متبادل واستمر في إعداد البيانات المعدنية حسب الطلب.
- Recognized modern error.الخادم حديث
-32022، اختر من بينdata.supportedو حاول مرة أخرى باستخدام معرف طلب جديد. لخطأ الرأس أو القدرة، تصحيح الطلب. لا ترسلinitialize. . . - Ambiguous signal.خطأ JSON-RPC غير معروف ، أو وقت انتهاء، أو إغلاق الاتصال ، أو استجابة فارغة لا تعريف عصر. يتم إغلاق الفشل ما لم يتم تكوين هذا النظير الدقيق للتوافق القديم.
تشمل الأخطاء المعترف بها في بروتوكول الحديث:
-32020الرأس غير متطابق-32021المطلوب (المستقبل)-32022غير مدعوم بروتوكول الإصدار
تبقى الأخطاء الحديثة المعترف بها حديثة حتى عندما يكون الزميل على قائمة الإذن القديمة. بمجرد أن يثبت الخادم أنه يفهم مخزون الكلمات الحديثة للخطأ ، فإنه يرسل initializeسيكون ذلك تخفيضًا
لا تعالج-32601كدليل إيجابي على التراث. يجعل فقط من المسموح به صراحة أن يكون مؤهلاً لمسح واحد إرث. نفس القاعدة تنطبق على وقت وقف، إغلاق الاتصال، أو رد الفراغ.
الإذن هو نية المشغل، وليس دليل
يجب أن تكون التوافق التراثية خاصية صريحة لتنسيق واحد من الأقران:
pythonclient.add_server("archive", archive_transport, allow_legacy=True)ربط هذا الخيار بالقيادة أو نقطة النهاية الموضحة. لا تستخدم بطاقة برية تسمح لخادم تعسفي بتخيار نفسه في التعريفات الأساسية الأضعف.allow_legacy=Trueيفشل بعد نتائج اكتشاف غامضة ولا يحصل أبداًinitialize. . .
المُسجل يمنح الإذن بالتحقيق، لا يختار العصر، يرسله العميلinitializeفي غضون موعد محدد فرض النقل، ثم يتطلب كل ما يلي:
- JSON-RPC
2.0الإجابة بتصريح الطلب المماثل - بالضبط واحد
resultو لاerror(إنه) - أ
protocolVersionفي مجموعة مراجعات القديمة المكوّنة للعميل؛ - قيمة كائن
capabilitiesالحقل - أ
serverInfoكائن مع سلسلة غير فارغةnameوversionالحقول
فشل إغلاق وقت وقف، إغلاق الاتصال، استجابة الخطأ، نتيجة غير مصممة، معرف غير متطابق، أو مراجعة غير مدعومة. لا يتم إغلاق النتيجة الإيجابية القائمة على الهيكل فقط تحدد العصر القديم. يمر الرمز legacy_probe_timeout_msإلى جهاز نقل المعدل؛ يجب على جهاز استوديو حقيقي أو جهاز تعديل HTTP أن يطبق هذا الموعد النهائي بدلاً من مجرد تسجيله.
حفظ العصر المحدد لزميل النقل لا تُسائل مرة أخرى قبل كل مكالمة
التراث هو فرع التوافق
بمجرد أن يعود المسح المحدود إلى دليل إيجابي صحيح على التراث، يستخدم العميل النسخة المختارة للتراث بالضبط كما هو محدد في تلك المراجعة:
- التحقق من غلاف الاستجابة و رقم العلاقة.
- التحقق من أن الإصلاح المفاوض عليه موجود في مجموعة التراث المثبتة.
- سجل القدرات الموثقة و هوية الخادم.
- أرسل
notifications/initializedفقط بعد مرور كل الشيكات - استخدم أشكال طلبات سابقة لهذا عمر النقل.
هذا الفرع موجود للتفاعل مع الأقران المعروفة. ليس التصميم الافتراضي للخوادم الجديدة أو الطلبات الجديدة. إذا أعيد تشغيل النقل أو تغير نقطة نهايتها، فاستلق الاحتفاظ بحفظ الأقران والتفاوض مرة أخرى.
أدوات اكتشاف وتخزين الاحتفاظ بالملف
لكل زميل نشط، اتصلtools/listالنتيجة الحديثة تشملresultType،ttlMsوcacheScope. احترم إشارة الطفولة في سياق الترخيص الصحيح . إعادة التسجيل بعد انتهاء الصلاحية أو حدث تغيير القائمة المشترك
العملاء يجب أن يعالجوا المفقودينresultTypeمن خادم سابق مثل "complete"لا تتطلب حقل التخزين الحديثة على استجابة من عصر سابق من التفاوض.
يجب على الخادم إرجاع التنظيمات الحتمية. يجب على العميل أيضًا فرز قبل الاندماج بحيث لا يعتمد ترتيب السجل المحلي على توقيت بدء العملية.
دمج مساحة الأسماء الآمنة من الاصطدام
خادمين قد يكتشفون كل منهماsearchاختر السياسة المعلنة:
- Prefix on collision.احتفظ بالاسم القنوني الأول واكشف التصادمات اللاحقة
<server>/<tool>. . . - Reject on collision.لا تحميل المكرر وتظهر خطأ واضح في التكوين.
- Silent overwrite.لا تستخدم هذه أبداً إنها تخفي أي خادم يتلقى إجراءً تم اختياره من النموذج
تخزين كل من الاسماء القنونية والمقلية. النموذج يرى الاسم القنوني. الخروج tools/callيستخدم الاسم المحلي الذي أعلن عنه الخادم المالك.
توجيه مكالمة
التوجيه هو البحث البسيط:
textcanonical tool name
-> peer name + local tool name
-> new JSON-RPC request id
-> modern request metadata or explicit legacy shape
-> matching response idلا ترسل مكالمة عندما لا تكون النقل المالك متاحة. اعيد ربط النقل أو إعادة تشغيله، ثم إعادة تشغيل اكتشاف و tools/listيمكن إعادة محاولة طلبات الطيران الحديثة المفقودة في عملية النقل المكسورة باستخدام هوية JSON-RPC الجديدة عندما تسمح سياسة السلامة العملية بذلك.
الإخطارات والتسجيلات
تغييرات القائمة والموارد الحديثة تأتي فقط على العميل المفتوح subscriptions/listenالعميل يرسل مرشح الإخطار، ينتظرnotifications/subscriptions/acknowledged، وترتبط الأحداث مع اسم طلب الاستماع في بيانات البيانات المعلوماتية.
عند إيقاف الاتصال، افتح طلب الاستماع الجديد وإعادة إعادة إعادة إعادة القوائم أو الموارد ذات الصلة.Last-Event-ID. . .
لا يوجد طلبات من الخادم
الخوادم الحديثة لا تدعو العميل مع طلبات JSON-RPC المستقلة لنظرية العينات أو الإجراءات أو الجذور.input_required، والعميل يحاول مرة أخرى الطلب الأصلي بعد استيفاء طلبات المدخلات المضمنة.
لا تمنع قراءة استجابة الزملاء أثناء إكمال المدخلات. الحفاظ على التواصل وإنشاء هوية JSON-RPC الجديدة للمحاولة المُجددة.
استخدمها
code/main.pyيستخدم وظائف النظير في العملية بحيث تبقى قرارات البروتوكول مرئية. يربط مع اثنين من النظيرين الحديثين ونظير واحد من النظيرين المترافقين المُسَمَح به عمداً، ثم يدمج ويرسل أدواتهم. يتلقى جهاز الاتصال النقل ميزانية فترة فترة حتى لا يمكن لقعة التوافق إخفاء صفقة غير محدودة.
bashcd code
python3 main.py
python3 -m unittest discover tests -vالاختبارات تثبت حدود التي تفوت الديمو العادية:
- الطلبات الحديثة تكرر البيانات المعدنية.
-32022إعادة الاكتشاف الحديث دون تشغيل؛- الأخطاء الحديثة المعترف بها لا تخفض أبداً، حتى بالنسبة لزميل مسموح به؛
- التوقفات الزمنية، إغلاق الاتصال، الاستجابات الفارغة، والخطأ غير المعترف به لا يؤدي إلى
initializeبدون مسجلة - يصبح النسيق المُسجل في القائمة إرثًا فقط بعد وجود مؤلف معتمد
initializeالنتيجة - النتائج المتبقية غير المثبتة والتي لم يتم دعمها تجعل النسخة غير متوفرة.
- يتم حفظ عصر مختار بنجاح على طول عمر النقل.
أرسله
هذه الدروس تُسافرoutputs/skill-mcp-client-harness.md. يضمن طوابع الطلبات الحديثة ، وتفاوض عصر الاستديو ، وتدمير مساحة الأسماء المحددة ، والتوجه ، وفرع التوافق القديم المغلق.
التمارين
- إرجاع الخادم المزيف
-32022لا يوجد نسخة مدعومة بشكل متبادل. تأكد فشل العميل بدلاً من إرسالinitialize. . . - السماح بخادم سابق مزيف، وجعل حدوده
initializeأُسَفِقُ وقتَ، وَأثبتُ أنْ يَبْقىُ أقرانهunknownو غير متوفر - إضافة
cacheScope: "private"قائمة الأدوات لـ"إتفاقيّة تصريحين" تأكّد أن العميل لا يشارك أبداً النتيجة المحفوظة في مخزن واحد مع الآخر. - تغيير سياسة الصدام إلى رفض وجعل البدء يفشل مع كلتا الأسماء في الخطأ.
- إضافة مقياس محدود
subscriptions/listenعند فقدان التدفق، إستمع مرة أخرى مع معرف طلب جديد وأدوات إعادة التدفق.
الشروط الرئيسية
| Term | Meaning |
|---|---|
| Peer | Client-side record for one server transport and its discovered data |
| Protocol era | Modern per-request metadata or legacy initialization semantics |
| Discovery probe | Initial server/discover used to identify the stdio era |
| Recognized modern error | Error that proves modern behavior and forbids legacy fallback |
| Legacy allowlist | Operator configuration permitting one bounded compatibility probe for a pinned peer |
| Positive legacy evidence | Valid, correlated initialize result for an explicitly supported legacy revision |
| Merged namespace | Canonical tool names across all active peers |
| Collision policy | Prefix or reject rule for duplicate tool names |
| Era cache | Selected modern or legacy behavior stored for one transport peer |
| Transport recovery | Restart or reconnect, rediscover, relist, and retry safely with a new id |
المزيد من القراءة
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.