نقلات MCP: stdio و HTTP غير رسمية
2026-07-28، الاستديو المحلي والاتصالات المباشرة عن بعد HTTP تحمل كل من طلبات وصف الذات.Type: Learn
Languages: Python
Prerequisites: Phase 13, Lessons 07 and 08
Time: ~65 minutes
أهداف التعلم
- اختر ستديو لعمليات الطفل المحلية و HTTP المباشر لخدمات الشبكة.
- تنفيذ عقد HTTP المتداول مع نقطة نهاية واحدة حديثة، POST فقط.
- مرآة وتؤكيد نسخة MCP، والطريقة، والأسماء الاسم ضد جسم JSON-RPC.
- تقديم SSE حسب الطلب وعمر طويل
subscriptions/listenالتيارات بشكل صحيح. - تحويل عمليات تنفيذ HTTP+SSE القائمة على جلسات وتتراثها دون عرض سلوك التراث على أنه حديث.
المشكلة
الإصدارات السابقة من HTTP المباشرة مزجت من مفاوضات البروتوكول مع اتصال وسلوك الجلسة. يمكن للخادم أن يختمMcp-Session-Id، تعرض تدفق GET مستقل ، تقبل DELETE لإنهاء الجلسة ، واستئناف SSE مع Last-Event-ID. . .
المفوضية2026-07-28يزيل هذه الآليات من السلك الحديث. كل طلب يمكن أن يصل على أي عامل صحي لأن نسخة بروتوكولها وقدرات العميل تتحرك في جسم الطلب. الرؤوس HTTP مرآة الحقول المحددة للتوجيه والسياسة، ولكن الخادم يؤكد تلك الرؤوس ضد الجسم قبل التنفيذ.
النتيجة أسهل في الحجم وأسهل في التفكير حول. وهذا يعني أيضا أن خادم يعلّم النقل 2025 كما الحالية يعلّم النموذج الخاطئ والأمن.
المفهوم
الاستديو
التماس الاستديو هو لعملية فرعية تم إطلاقها من قبل العميل:
- يكتب العميل رسالة UTF-8 JSON-RPC لكل سطر إلى stdin.
- يكتب الخادم رسالة UTF-8 JSON-RPC واحدة لكل سطر إلى stdout.
- الخادم يكتب التشخيصات إلى ستدر
- الخادم يغادر فوراً على ستدين EOF
- كل طلب حديث يحمل إصدار و قدرات العميل في
params._meta. . .
قد تكون العملية صالحة للعديد من المكالمات، ولكنها ليست جلسة بروتوكول حديثة. إذا خرجت بشكل غير متوقع، فإن الطلبات أثناء الرحلة تضيع. إعادة تشغيل العملية وإعادة اكتشافها وإعادة إدراجها وإعادة فتح الاشتراكات، وإعادة محاولة العمليات الآمنة مع هويات الطلبات الجديدة.
HTTP قابل للتسجيل في 2026-07-28
خادم حديث يعرض نقطة نهاية واحدة من MCP، مثل /mcp، الذي يقبل POST.
كل طلب أو إشعار JSON-RPC هو POST HTTP جديد. يحتوي الجسم على رسالة JSON-RPC واحدة. لا يرسل العملاء استجابات JSON-RPC إلى الخادم.
لطلب، يعيد الخادم إما:
Content-Type: application/jsonمع استجابة JSON-RPC واحدة؛ أوContent-Type: text/event-streamمع الإخطارات المتعلقة بهذا الطلب، تليها الإجابة النهائية JSON-RPC.
لإعلام مقبول، يعود الخادم 202 Acceptedبدون جثة
يعلن العملاء عن كلا النوعين من الاستجابة:
httpAccept: application/json, text/event-stream"POST فقط" يعني "POST فقط"
لا يوجد في HTTP الحديثة المباشرة سلسلة GET مستقلة ولا يوجد نقطة نهاية للانتقال.
GET /mcpالعائدات405 Method Not Allowed. . .DELETE /mcpالعائدات405 Method Not Allowed. . .Mcp-Session-Idيتم تجاهلها ولا يتم إختراعها أو التردد عليهاLast-Event-IDيتم تجاهلها لأن التيارات الحديثة لا يمكن إعادة تشغيلها
إذا تم كسر سلسلة استقصائية قبل استجابتها النهائية ، فقد العميل طلب أثناء الرحلة. قد يصدر طلبًا جديدًا مع هوية JSON-RPC الجديدة عندما يكون محاولة إعادة آمنة. يجب ألا يحاول استئناف التدفق.
التحقق من المصدر
الخوادم تؤكدOriginعلى الاتصالات الموصلة لمنع إعادة ربط DNS. إذا كان العنوان موجوداً وليس مسموحاً صراحةً به، أعد 403 Forbidden. العميل غير المتصفح قد ينسفOrigin، كما تسمح بها قواعد النقل الرسمية.
يجب أن يربط الخوادم المحلية127.0.0.1لا توجد كل واجهة. خدمات الشبكة لا تزال تحتاج إلى التوثيق والتصريح على كل طلب. التحقق من المصدر ليس التوثيق.
استخدم مطابقة المنشأ الدقيقة بعد التكوين القنوني.origin.startswith("https://trusted.example")غير آمنة لأنها تستطيع قبول الإضافات التي يسيطر عليها المهاجم
العناوين المطلوبة لميتات البيانات HTTP
كل طلب POST الحديث يتضمن:
httpMCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: notes_searchقواعد العنوان:
MCP-Protocol-Versionمطلوب ويجب أن يكون متساوياparams._meta.io.modelcontextprotocol/protocolVersion. . .Mcp-Methodمطلوب ويجب أن يكون مساوياً لـ JSON-RPCmethod. . .Mcp-Nameمطلوبة لـtools/call،resources/readوprompts/get. . .Mcp-Nameمتساويةparams.nameأوparams.uriلـresources/read. . .- قيم العناوين حساسة للقضية على الرغم من أن أسماء العناوين غير حساسة للقضية.
غير آمن أو غير ASCII Mcp-Nameتستخدم القيم UTF-8 Base64 المراقبة بالضبط:
text=?base64?{Base64EncodedValue}?=الخادم يقرر هذه القيمة قبل مقارنتها مع الجسم
المراجع المرايا المفقودة أو غير المنسقة أو غير المنسقة تعود HTTP 400مع رمز JSON-RPC -32020. إذا كان الرأس والجسم يوافقون على نسخة لا يدعمها الخادم ، ارجع HTTP 400مع-32022و بيانات الخطأ الدقيقة مثل{"supported":["2026-07-28"],"requested":"2027-01-01"}. . .
طريقة حديثة غير معروفة تعيد HTTP 404مع JSON-RPC -32601. جسم JSON-RPC مهم لأن عميل عصر مزدوج يستخدمها لتمييز خطأ حديث من خطأ نهاية إرث.
المعدل المحدد للطلب
يمكن للخادم اختيار SSE لطلب واحد طويل الأمد:
textPOST tools/call id=41
<- notifications/progress related to id=41
<- notifications/progress related to id=41
<- JSON-RPC response id=41
stream closesيجب أن لا يرسل الخادم طلبات JSON-RPC المستقلة على هذا التدفق. تستخدم نتائج طلبات الجولة المتعددة في تجميع العينات والتحقيق والتفاعلات الجذرية. إغلاق سلسلة الاستجابة يلغي ذلك الطلب.
لا تضيف أرقام إشارة الحدث SSE للعب مرة أخرى. Last-Event-IDلا يُعتبر إعادة الإجراء جزءاً من الإصلاح الحديث.
تغييرات طويلة الأمد تستخدم الاشتراكات/ الاستماع
استخدام إشعارات التغيير طلب مفتوح من قبل العميل ، وليس GET منفصل:
json{
"jsonrpc": "2.0",
"id": "listen-1",
"method": "subscriptions/listen",
"params": {
"notifications": {
"toolsListChanged": true,
"resourceSubscriptions": ["notes: TOK0
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": {
"name": "course-client",
"version": "1.0.0"
}
}
}
}استجابة POST هي سلسلة SSE طويلة الأمد.notifications/subscriptions/acknowledged. الإقرار، كل إشعار عن التغيير، والنتيجة النهائية تحملio.modelcontextprotocol/subscriptionIdفي_meta، يساوي اسم طلب الاستماع. قد ينشر الخادم تعليقات SSE كحافظ. عندما ينخفض التدفق ، يقوم العميل بإعادة إصدار subscriptions/listenمع هوية طلب جديدة وإعادة تصحيح البيانات المتأثرة.
resources/subscribeوresources/unsubscribeلا تستخدمها في اتصال حديث
حالة الطلب الصريحة
إزالة جلسات البروتوكول لا يمنع تدفقات العمل مع حالة. قد يقوم الخادم بتصوير مسدس حالة غير شفافة ويرجع إليه كنتيجة أداة طبيعية. يمر العميل بهذه المسدس كحجة صريحة في مكالمات لاحقة.
ربط الجهازات المقبلة بالصيغة الرئيسية الموثقة، وجعلها غير قابلة للاختبار، وتجاوز صلاحيتها، وافعل كل استخدام مرخصًا. وهذا يجعل الحالة مرئية في طبقة التطبيق بدلاً من إخفائها في صلة النقل.
الفشل الناجم عن حالة النسخة الخفية هو ميكانيكي:
- الطلب A يصل إلى النسخة 1 و يخلق مسودة في ذاكرة تلك العملية.
- لا يعود الرد على مسودة التعامل لأن التنفيذ يفترض أن الاتصال يحدد المسودة.
- الطلب ب هو POST جديد و يصل إلى النسخة 2.
- النسخة 2 لديها بيانات بروتوكول صالحة ولكن لا طريقة لإسم أو تحميل المسودة، لذلك تتعطل سير العمل أو تقرأ الكائن المحلي الخطأ.
- يبدو أن التوجيهات اللصقية تصحيح الأعراض حتى إعادة البدء أو التنفيذ أو إعادة التوقيع أو فشل التنفيذ يقل الطلب التالي.
الحدود الصحيحة لها جزءان يظل السياق البروتوكول في كل طلب. حالة التطبيق الدائم يعيش في متجر مشترك تحت المقبض المعدل الخادم أعيد إلى العميل. المكالمة التالية توفر المعاملة، أي نسخة تحميل نفس السجل، والإذن يربط السجل إلى المدير الموثق والمستأجر. قد تكون ذاكرة النسخة مخزنة لسجل، ولكنها لا يمكن أن تكون النسخة الوحيدة المطلوبة للصواب.
اختر آلية الحالة حسب عمر. المتغيرات المحلية الطلب يمكن أن تعمل على اتصال واحد. استمرار MRTR القصير يمكن استخدام حماية النزاهة requestState. تحتاج مسودة أو مهمة دائمة إلى مسدس صريح بالإضافة إلى الاستمرارية المشتركة، والانتهاء من الصلاحية، والتحكم في التزامن، والفائدة. لا أحد من هذه الأشياء هو جلسة بروتوكول MCP.
متوافقة HTTP في عصرين
يقوم العميل الذي يدعم الخوادم الحديثة والقديمة بمحاولة POST الحديثة أولاً. إذا تلقى HTTP 400،404أو405، فهي تفتيش الجثة:
- خطأ JSON-RPC الحديث المعترف به يثبت أن الخادم حديث. تصحيح الطلب أو حاول إعادة إصدار إعلان. لا تخفض الترتيب.
- قد تشير الجسم الفارغ أو استجابة غير معروفة إلى خادم HTTP + SSE سابق. فقط بعد ذلك حاول نقطة نهاية GET القديمة وتتوقع إرثها
endpointالحدث
يمكن للخادم دعم كلا العصورين أثناء الهجرة عن طريق توجيه البيانات المعدنية الحديثة إلى تنفيذ POST الحديث فقط والاحتفاظ بنقاط نهاية سابقة منفصلة لعملاء قديمين. لا تصف أبداً التراث GET ، DELETE ، ID الجلسة ، أو سلوك التراجع كجزء من 2026-07-28. . .
استخدمها
code/main.pyيطبق خادم HTTP محطم حديث مع مكتبة Python القياسية. يصدق الأصليات والرؤوس المرئية، يتجاهل رؤوس جلسات المزولة، يعيد JSON للاتصالات العادية، ويعرض محطمة subscriptions/listen-تيار "إس إي إس"
bashcd code
python3 main.py --probe
python3 -m unittest discover tests -v-تحققات الصوت:
- يتم رفض المصل غير صالح؛
- الاكتشاف الناجح دون معرف جلسة
Mcp-Session-IdوLast-Event-IDيتم تجاهلها.- عودة عدم مطابقة الرأس
-32020(إنه) - إرجاع الإصدار غير المدعوم
-32022مع دقةsupportedوrequestedالبيانات - إشعار غير معرف مقبول يعود إلى HTTP
202بدون جثة - إرجاع المعلومات و إزالةها
405(إنه) subscriptions/listenهو سلسلة استجابة POST التي تحمل إقرارها وإخطاراتها والنتيجة النهائية هويته الاشتراكية.
أرسله
هذه الدروس تُسافرoutputs/skill-mcp-transport-migrator.md. إنه يزيل جلسات البروتوكول الحديثة، يضيف التحقق من الصورة في الرأس، ويستبدل GET مستقلة بـ subscriptions/listenويحافظ على أي جسر متكرر منفصلة بشكل مرئي
التمارين
- إزالة
Mcp-Methodمن POST. تأكيد HTTP400وخطأ-32020. . . - أرسل نسخة متطابقة من الرأس والجسم
2027-01-01تأكيد HTTP400، خطأ-32022و البيانات الدقيقة{"supported":["2026-07-28"],"requested":"2027-01-01"}. . . - أرسلوا أفراد قاعدة 64
Mcp-Nameلـ URI الموارد غير ASCII. تأكد من مقارنة القيمة المفكورة معparams.uri. . . - كسر سلسلة الاستماع المحدودة قبل استجابتها النهائية وإعادة إصدارها مع معرف JSON-RPC الجديد وأدوات إعادة التأثير.
- إضافة مسدس سير العمل صريح إلى أداة النقاش. ربطها بموضوع الإذن دون استخدام صلة الاتصال.
الشروط الرئيسية
| Term | Meaning |
|---|---|
| stdio | Newline-delimited JSON-RPC over a client-launched subprocess |
| Streamable HTTP | Single endpoint where each modern message is a new POST |
| Request-scoped SSE | POST response stream containing related notifications and final response |
subscriptions/listen | Long-lived POST request for opted-in change notifications |
| Header mismatch | HTTP 400 and JSON-RPC -32020 when mirrored headers disagree with body |
| Origin validation | DNS-rebinding defense for incoming connections, not authentication |
| Explicit state handle | Application token passed as an ordinary argument instead of hidden session state |
| Legacy bridge | Separate earlier-era behavior kept only for compatibility |
المزيد من القراءة
- MCP Transport Overview
- MCP stdio Transport
- MCP Streamable HTTP
- MCP Subscriptions
- MCP 2026-07-28 Changelog
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.