Phase 13: Tools & Protocols

بوابات و سجلات المشاريع المختصة بدون جنسية

يجب أن يضع بوابة كل طريق صريح. بروتوكول 2026-07-28 يعطيه طريقة، اسم، نسخة، قدرة، هوية، مخزن، ومحافظات التتبع دون جلسة نقل.

Type: Learn

Languages: Python

Prerequisites: Phase 13 · 15 (security), Phase 13 · 16 (authorization)

Time: ~75 minutes

أهداف التعلم

  • جمع العديد من خوادم MCP خلف نقطة نهاية واحدة 2026-07-28 دون علاقة جلسة.
  • التحقق من الموافقة على البيانات المعدنية وتصنيفات التوجيهات حسب الطلب قبل الإرسال أو الإرسال.
  • دمج الأدوات مع مساحات الأسماء المستقرة، والترتيب التحديدي، ورقائق وصف، RBAC، والخزن الاحتياطي الخاص.
  • تعامل سجلات السجل كدليل على الاكتشافات التي لا تزال تتطلب سياسة القبول.
  • SSE المطلوب على الطرقsubscriptions/listen, محاولات MRTR مرة أخرى , و مكالمات تمديد المهام صحيحة
  • عزل اليد المقدمة والدعم الجلساتي من المسار الحديث.

المشكلة

إن ربط عميل واحد مباشرة بخادم واحد بسيط. تحتاج تنفيذ أكبر إلى إجابة متسقة على أسئلة أكثر صعوبة:

  • أي خوادم مسموح بها؟
  • أي مدير يمكنه رؤية كل أداة ودعوة كل أداة؟
  • ماذا يحدث عندما يظهر اثنان من خلفيات نفس الاسم؟
  • كيف يتم مراجعة التغييرات في المصطلحات؟
  • أين يتم تطبيق حدود أسعار ومشاكل مراجعة؟
  • هل يمكن لأي من الحالات التعامل مع الطلب التالي؟

يقع بوابة بين العملاء وخادمات MCP الخلفية. يقدم نقطة نهاية واحدة من MCP، ويطبق سياسة عبر القطاعات، ويرسل الطلبات المعتمدة.

تصميمات البوابة القديمة غالبا ما تعدد جلسة عميل واحدة إلى عدة جلسات خلفية وتعيد كتابتها Mcp-Session-Idهذا تصميم متوافق سابق، و الجوهر 2026-07-28 لا يحتوي على جلسات بروتوكول

المفهوم

الطريق الحديث

لكل طلب:

  1. تحديد مصداقية رئيس الطلب من تصريح النقل.
  2. تأكيديMCP-Protocol-Version،Mcp-Method،Mcp-Nameوparams._meta. . .
  3. أذن بالرئيسي والموارد والطريقة والوسيلة والحجج.
  4. تطبيق وصف، سجل، سعر، والبيانات السياسة.
  5. إعداد طلب جديد مستقل للخلفية المختارة.
  6. تأكيد نتيجة الخلفية وعودة نتيجة البوابة.
  7. سجل حدث مراجعة بدون تسجيل الأسرار

لا تحتاج أي خطوة إلى جلسة بروتوكول مخفية. يمكن أن توجد حالة التطبيق في قواعد البيانات أو المفاكسات الصريحة أو المهام أو حالة MRTR المحمية من النزاهة.

سياسة وقت التشغيل هي القرار الرئيسي

يقرر الإدخال إصدار الخلفية الذي يمكن أن يدخل البوابة. لا يسمح بمكالمة مباشرة. لكل طلب، يقوم البوابة بإعادة حساب السياسة من الرئيسي الموثق، والمصدر والموارد، المستأجر، والطريقة والاسم المماثلين، والحجج المعايضة، ورقمة المصفاة المعتمدة، والصحة الحالية للخلفية، وتقاطع القدرات، وتصنيف البيانات، وحالة السعر، وأي موافقة مرتبطة بالعمل.

هذا الأمر مهم. يمكن أن يبقى سجل السجل نشطًا بينما يتم إلغاء دور المستخدم. يمكن أن يبقى وصف محصومًا بينما يتجاوز حجج الوجهة حدود المستأجر. يمكن أن يبقى الخلفية المعتمدة بينما تقوم سياسة الحجر الحالي بتغيير الدعوات. وبالتالي فإن سياسة الوقت التشغيلي هي القرار الأساسي للسماح أو رفض ، مع إدراج دليل وصف كمدخول.

لا تخفي قرار الإذن تحت اتصال أو إزالة معرف الجلسة. إذا لم تكن السياسة متاحة، اتبع سياسة الفشل المعلنة حسب فئة العمليات. إن الاختلالات الآمنة هي عدم إغلاقها لتغييرات الحالة والقراءات الحساسة، في حين أن مسارات القراءة العامة المعتمدة صراحة لا يمكن استخدام سياسة الأخيرة المعروفة قصيرة الأمد إلا عندما يسمح نموذج المخاطر بها. سجل نسخة السياسة ومسار الفشل الذي اتخذ القرار، ثم تأكيد نتيجة الخلفية قبل إعادتها.

نقطة نهاية واحدة POST

يرسل HTTP المباشر الحديث كل رسالة JSON-RPC عبر POST:

textPOST /mcp
Authorization: Bearer <gateway-token>
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: notes.search
Accept: application/json, text/event-stream

يمكن للبوابة إرجاع JSON أو طلب-سكوب SSE لهذا POST. GET و DELETE إرجاع 405 للطلبات الحديثة. Mcp-Session-IdوLast-Event-IDلا تخلق السلطة أو التواصل أو التكرار في السلوك.

يجب أن تتوافق قيم العنوان والجسم.-32020قبل البحث عن نهاية الخلفية. هذا يسمح للموازين الحمولة، البوابات، ومحددات السرعة الطريق دون تحليل الجسم بأكمله مع الحفاظ على سلامة نهاية إلى نهاية.

التحقق من التحقق من التحقق من النظام المحدد: JSON-RPC وأنواع البيانات المعدنية، والرأس والجسم المساواة، ثم دعم النسخة المقابلة. يعود عدم التوافق HTTP 400 مع -32020. إذا كان الرأس والجسم يوافقون على نسخة غير مدعومة، أعيد HTTP 400 مع -32022وdataبالضبط{"supported":["2026-07-28"],"requested":"<actual>"}. طريقة غير معروفة تعيد HTTP 404 مع -32601. . .

ProtocolErrorيحمل اختياري data، و يقوم البوابة بتسلسلها إلى كائن خطأ JSON- RPC .id، لذلك لا يتلقى أبدا نجاح أو خطأ JSON-RPC. إشعار HTTP المقبول يعود 202 مع جسم فارغ.

تنفيذ اكتشاف في كل طبقة

البوابة تنفيذ server/discoverكما أنه يكتشف كل خلفية حتى يعرف إصدارات بروتوكول، والقدرات، والإضافات.

مثال على نتيجة البوابة:

json{
  "resultType": "complete",
  "supportedVersions": ["2026-07-28"],
  "capabilities": {
    "tools": {"listChanged": true}
  },
  "ttlMs": 30000,
  "cacheScope": "private",
  "_meta": {
    "io.modelcontextprotocol/serverInfo": {
      "name": "enterprise-gateway",
      "version": "2.0.0"
    }
  }
}

الإعلان عن التقاطع فقط من القدرات يمكن للبوابة أن تكرم من نهاية إلى نهاية. ميزة الخلفية ليست آمنة تلقائيًا للتعريض. ميزة البوابة بدون مسار الخلفية ليست مفيدة للإعلان.

serverInfoهو بيانات عرض وتشخيصية تم الإبلاغ عنها ذاتياً. لا تستخدمها كدليل للسجل أو الناشر.

إمكانات العميل حسب الطلب

كل طلب يتم إرساله يحتاج إلى تحديث_metaالملف:

json{
  "io.modelcontextprotocol/protocolVersion": "2026-07-28",
  "io.modelcontextprotocol/clientCapabilities": {},
  "io.modelcontextprotocol/clientInfo": {
    "name": "enterprise-gateway",
    "version": "1.0.0"
  }
}

لا تنسخ بصورة عمياء قدرات العميل الخارجي إلى نهاية الخلفية. البوابة هي العميل الخلفية. الإعلان فقط ميزات البوابة سوف تتوسط بشكل صحيح.

التسجيلات المحددة

دمج أدوات الخلفية تحت أسماء عامة مستقرة:

textnotes.search
notes.create
issues.list
issues.open

حافظ على خريطة من اسم عام إلى اسم الدوات الأصلية. لا تختار أبداً التصادم الأول أو الأخير. اسم عام هو جزء من عقد الموافقة والتحقق، لذلك تغييرها هو هجرة.

tools/listيجب أن تكون محددة. عندما تختلف المرئية عن الرئيسي، العائد cacheScope: private- مقيدةttlMsيقلل من عبء اكتشاف الخلفية دون السماح للفصل المحدد للمستخدم لتسريب عبر سياقات الائتمان.

كل وصف أداة عرضة يتضمن اسمًا مستقراً وصفًا وجذر كائن inputSchema. لا يمكن للفضاء الاسمية إزالة الحقول المطلوبة للمصفوف.resultType، بيانات الهوية الخادم، وتلميحات التخزين

مصطلحات تصريح المعتمدة على الحزمة

في وقت القبول، قم بتحديد المصطلح الكامل وتخزين مادة التوصيف تحت الاسم العام المؤهل. في وقت القائمة والكالم، قم بمقارنة المادة المباشرة مع المادة المعتمدة.

إذا تغيرت:

  • إزالتها منtools/list. . .
  • رفض المكالمات المباشرة
  • أصدري حلقة مراجعة
  • تطلب إعادة الموافقة على السياسة أو الإنسان قبل تحديث الرقاقة.

البوابة هي نقطة إنفاذ مركزية مفيدة، لكنها لا تحول وصف أول نظرة إلى واحد آمن. لا يزال من الضروري مراجعة أولية.

السجلات تساعد على اكتشاف وليس القرار

سجلserver.jsonيقدم البيانات المعدنية للنشر. سجل مدعوم بالحزمة يمكن أن يبدو على هذا النحو:

json{
  "$schema": "https:TOK0
  "name": "com.example/notes",
  "description": "Example notes MCP server.",
  "version": "1.0.0",
  "packages": [
    {
      "registryType": "npm",
      "identifier": "@example/notes-mcp",
      "version": "1.0.0",
      "transport": {"type": "stdio"}
    }
  ]
}

لا تحمل البيانات المعدنية للنشر قرار أمن البوابة. احتفظ بالدليل المحقق من الناشر والذات في حالة القبول منفصلة:

json{
  "registryName": "com.example/notes",
  "registryVersion": "1.0.0",
  "publisher": {"namespace": "com.example", "status": "verified"},
  "provenance": {
    "source": "registry.modelcontextprotocol.io",
    "recordId": "com.example/notes@1.0.0"
  },
  "admission": {"status": "approved", "reviewedBy": "gateway-policy"}
}

البوابة تفتيشserver.jsonو يربطها تلك الدولة الخارجية.

لكل مؤخرة مسموح بها، سجل:

  • سجل و رقم التعرف الدقيق
  • مساحة أسماء الناشر المحققة أو دليل النطاق.
  • الموافقة على النقل والنقطة النهائية
  • الإصدار المضبط أو سياسة التحديث المعتمدة.
  • تحميل القطع الأثرية أو المصطلحات
  • المصدر والموارد
  • المراجعة، وقت الموافقة، والانتهاء من الصلاحية.

لا تقبل خادمًا لأن اسم عرضه يشبه منتجًا مألوفًا. لا تعامل بوجود السجل باعتباره مراجعة أمنية تشغيلية. يمكن قبول الخوادم الخاصة من خلال نفس مخطط الدليل حتى لو لم تظهر في السجل العام أبدًا.

هذا الدروس يطبق خطة البوابة: إضافة أدلة النشر إلى القبول المحلي قبل أن يصبح الخلفي قابلًا للجوال. Lesson 30: MCP Registry Supply Chain, Admission, Drift, and Rollbackيقوم بتصميم طائرة التحكم الكاملة لإثبات مساحة الأسماء الدقيقة ، ومصدر الأثاث ، والحلقات غير المتحولة ، وتحرك الموصف الحي ، وموافقة حالة السجل ، ومجلة القبول الواضحة ، والعودة المدعومة بالأدلة. أبقي حالة سلسلة التوريد منفصلة عن قرار الوقت التشغيلي حسب الطلب أعلاه.

الوساطة المؤكدة

يُصادق البوابة مكالماته ويعدّق بشكل منفصل إلى الخلفيات.

إبقوا هذه الالتزامات صريحة:

textouter principal -> gateway role and policy
backend issuer + resource -> backend registration and token

لا تمرّط أبداً رمز البوابة الخارجية إلى مؤشر خلفي. لا تستخدم أبداً رمز خلفي في أحد المصدرين أو الموارد الأخرى. إذا كانت الأداة تعمل نيابةً عن المستخدم النهائي، فحافظ على هذه التفويض مع نموذج تبادل مصممة أو مطالبات بدلاً من التمثيل بالمستخدم مع إثبات خدمة مشتركة.

حدود السعر بدون جلسات

الحدود الرئيسية حسب المصل المصدر والمصدر والموارد والأداة العامة ودرجة التكلفة والفترة. لا يوجد هوية جلسة وسيكون من السهل تدويرها حتى لو كانت موجودة.

قم بتطبيق التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحقق من التحققق من التحققق من التحققق من التحققق من التحقققق.

مراجعة سلسلة القرار

سجل كاف لإعادة بناء مكالمة:

  • طلبات و تحديدات تتبع
  • المؤسس الرئيسي والمصدر الموثوق.
  • أداة عامة و طريق الخلفي
  • نسخة من محركات تصفية
  • قرار السياسة والسبب
  • درجة التأخير والنتيجة
  • تحديد دورة MRTR أو تحديد المهمة عند الاقتضاء.

رموز حامل الرسائل، رموز التأمين، رموز التجديد، أسرار خام، والحجج الحساسة غير الضرورية.

المعدل المحدد للطلب

يمكن أن يعيد POST العادي SSE المقصود بالطلب عندما تنشأ عمليات العمل خلال هذا الطلب الواحد. إغلاق تيار الاستجابة يلغي الطلب HTTP الحديث في الطيران.

لا تخلق تدفق GET منفصل ولا تعد بإعادة تشغيل آخر حدث. هذه افتراضات نقل قديمة.

إشعارات التغييرات طويلة الأمد

لإخطارات تغيير القائمة والموارد، يقوم العميل الحالي بإرسال subscriptions/listenعبر POST ويتلقى استجابة SSE. فلترات الإخطار تستخدم الحقول المسطحة بالضبط toolsListChanged،promptsListChanged،resourcesListChangedوresourceSubscriptions:

json{
  "jsonrpc": "2.0",
  "id": "listen-tools",
  "method": "subscriptions/listen",
  "params": {
    "notifications": {
      "toolsListChanged": true
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

الحدث الأول يقر بمجموعة فرعية مدعومة. هو معرف الاشتراك هو ID JSON-RPC لطلب فتح التدفق:

json{
  "jsonrpc": "2.0",
  "method": "notifications/subscriptions/acknowledged",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/subscriptionId": "listen-tools"
    },
    "notifications": {
      "toolsListChanged": true
    }
  }
}

ثم يقوم البوابة بإرسال أنواع التغييرات المعترف بها فقط. كل إشعار على هذا التدفق يحمل نفس io.modelcontextprotocol/subscriptionIdفيparams._metaلا يوجد إعادة تشغيل تلقائي أو إعادة الاستماع تلقائي. عند إعادة الاتصال، يقوم العميل بإعادة فتح الاشتراك وتحديث القوائم التي يعتمد عليها. يقدم الخادم إغلاقًا لطيفًا نتيجة كاملة نهائية مع علامة على نفس الهوية الاشتراكية.

الطريق الحديث يحل محلresources/subscribe،resources/unsubscribeو تدوينات GET مستقلة غير مرغوبة، و تبقيهم في مسار قديم

(مـرتر) عبر بوابة

عندما يعود أحد الخلفياتresultType: input_required، يمكن للبوابة إرسال هذه النتيجة فقط إذا كان العميل الخارجي يدعم طلب المدخل المطلوب. الحفاظ requestStateبايت بـ بايت ما لم تنهي البوابة العمدة وتعيد إصدار التفاعل.

يقوم العميل بإعادة تجربة الأداة العامة الأصلية مع معرف JSON-RPC جديد و inputResponses. يسمح البوابة بإعادة تجربة، ويتحقق من نفس الطريق العام، ثم يرسل طلبًا جديدًا. لا يجب أن تتخذ دورة سابقة منحت موافقة غير محدودة.

مهام توجيه الإطالة

المهام هي تمديد رسمي تم تحديده من قبلio.modelcontextprotocol/tasksإنهم ليسوا محلات للجلسة الأساسية

يعلن العميل عن التوسع داخل قدرات العميل حسب الطلب ، ويعلن البوابة عنه في الاكتشاف فقط عندما يمكن الحفاظ على دورة الحياة من نهاية إلى نهاية.tools/call، يقرر الخلفي وحده ما إذا كان يجب إرجاع النتيجة العادية أوresultType: taskنتيجة المهمة تحملtaskId،status، طوابع زمنية ،ttlMs، و اختياريpollIntervalMsيجب أن تكون المهمة قابلة للقراءة بشكل دائم قبل إرسال النتيجة.

سجل البوابة المسار الرئيسي والخلفي الموثق لتحديد المهام الغامض.tasks/get،tasks/updateوtasks/cancelاستخدام المكالماتparams.taskIdكـMcp-Name، مما يعطي الوسطاء مفتاح توجيهtasks/getالعائداتresultType: completeمع حالة المهمة الحالية ويقوم بتحديد النتيجة النهائية أو خطأ البروتوكول في حالة نهاية. tasks/updateيرسلها مفتاحاًinputResponsesإدخال مهمة غير متوفرة و يعود إقرار كامل فارغ. tasks/cancelهو نية تعاونية مع اعتراف كامل فارغ، وليس ضمان أن العمل يتوقف.

لا تنفيذ جديدة tasks/listأوtasks/resultالمنهج: أسلوب التطبيقات المستخدمة في التطبيقات.tasks/getالعميل يجيب عليهم من خلالtasks/updateلا تحاول إعادة محاولة المكالمة الأصلية. لا يزال العميل يختار في الفصل المقترح؛ يظل إنشاء المهام موجهة إلى الخادم.

حالة مسار المهمة الدائمة هي بيانات التطبيق المفتاحية من قبل عتبة المهمة ، وليس جلسة بروتوكول.

حدود التوافق

إذا كان البوابة يجب أن تخدم عميلًا مسنًا أو آخر آخر:

  • اكتشاف العصر صراحة.
  • حافظ على البدء في المهام، جلسات النقل، وتدفقات GET، واشتراكات الموارد، ومفردات المهام القديمة داخل المعدل القديم.
  • لا تسرب أبداً هوية جلسة سابقة في التوجيه الحديث أو التفويض.
  • تفضل قنبلة اكتشاف محدودة وسياسة إرجاع صريحة على التخفيض الصامت

بناءها

code/main.pyينفذ بوابة بروتوكول في العملية وخادمين خلفيين. كل خلفي يتلقى طلبًا جديدًا بروتوكولًا الحالي. يقدم البوابة اكتشافًا ومصفاة من قبل المستخدمtools/list, مسار المسار , سجلserver.jsonبالإضافة إلى حالة القبول الخارجية، ورقوم وصف، RBAC، حدود أسعار الرئيسي الرئيسي، قرارات المراجعة، ونموذج subscriptions/listenإقرار "إس إي إس"

يتلقى النموذج أجسام الطلبات المتحسّسة، و رؤوس التوجيه، و هوية المحمول الموثقة. ليس مُعدّل HTTP كاملًا ولا يحلل Content-Typeأو الكاملAcceptالعقد. ربطها مع مُعدّل HTTP المُباشر للدروس 09، الذي يتطلب Content-Type: application/jsonوAcceptقيمة تحتوي على كلتا application/jsonوtext/event-stream. . .

إشغله

bashcd phases/13-tools-and-protocols/17-mcp-gateways-and-registries
python3 code/main.py
python3 -m unittest discover code/tests -v

الظهور يطبع هوية الطلب الخارجي و هوية الطلب الخلفي الجديد حتى يكون الهوب بدون ولاية مرئيًا.

استخدمها

استبدل الأشياء الخلفية في العملية بعملاء بروتوكول التيار الحقيقي. حافظ على نفس التماس:

  • سجل القبول قبل الاتصال
  • اكتشاف الخلفي قبل تعرض القدرة
  • اسم عام مؤهل قبل التسمية.
  • إدراج الموصف قبل القائمة أو الاتصال.
  • بيانات جديدة لكل طلب قبل إرسالها.
  • التحقق من نتائجها قبل العودة

أرسله

هذه الدروس تُسافرoutputs/skill-gateway-bootstrap.md. إنّه ينتج تصميمًا حديثًا للمبادرة يغطي الدخول، والاكتشاف، والإدخال، ومساحات الأسماء، والإذن، والاحتفاظ بالتخزين، والتشغيل، والإشتراكات، والمسؤوليات، واللاحظية، والعزل المتعزل.

التمارين

  1. إضافة سياق تتبع إلى البيانات المعدنية الخارجية والمتقدمة لطلب وتسجيل التواصل في حدث التحقيق.
  2. إضافة مساعدة خلفية قادرة على المهام والمسار tasks/getحسب المهام في Mcp-Name. . .
  3. تغيير واحد وصف الخلفية وإثبات كل من اكتشاف ودعوة مباشرة محظورة.
  4. أضف قدرة خادم خاصة بالرئيس وشرح لماذا يجب أن يبقى الاكتشاف في الاحتفاظ بحفظ سرية.
  5. اكتب واجهة المعدل القديمة دون إضافة أي حالة قديمة إلى الحالة الحديثة Gatewayدرجة.

الشروط الرئيسية

TermMeaning
MCP gatewayPolicy and routing server between clients and backend MCP servers
Admission recordEvidence and policy decision allowing one backend into the gateway
Qualified tool nameStable public route such as notes.search
Descriptor pinApproved digest checked during discovery and dispatch
Private cache scopeCached result restricted to one authorization context
Request-scoped SSEStreaming response attached to one POST request
subscriptions/listenClient-opened SSE stream for selected long-lived change notifications
Task routeApplication mapping from an opaque task id to its backend
Legacy adapterExplicit version-gated boundary for old handshake and session behavior

المزيد من القراءة

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.