Phase 13: Tools & Protocols

एक एमसीपी क्लाइंट बनानाः डिस्कवरी, रूटिंग और ड्यूल-एरा फॉलबैक

आधुनिक MCP क्लाइंट हर अनुरोध पर अपना अनुबंध दोहराता है। इसका सबसे कठिन संगतता निर्णय यह जानना है कि पुराना सर्वर कब वास्तव में पुराना है और आधुनिक सर्वर कब एक सुधार योग्य त्रुटि की रिपोर्ट कर रहा है।

Type: Build

Languages: Python

Prerequisites: Phase 13, Lesson 07

Time: ~85 minutes

सीखने के लक्ष्य

  • प्रत्येक MCP का निर्माण करें 2026-07-28वर्तमान मेटाडेटा के साथ अनुरोध।
  • के साथ स्टूडियो सर्वर का परीक्षण करेंserver/discoverऔर एक आपसी समर्थित संस्करण चुनें।
  • केवल स्पष्ट रूप से अनुमत समकक्षों के लिए सीमित विरासत जांच को अधिकृत करें।
  • सकारात्मक के सत्यापन के बाद ही एक विरासत युग को स्वीकार करें initializeएक समर्थित संशोधन के लिए परिणाम।
  • बिना किसी टकराव को चुपचाप ओवरराइट किए निर्धारक उपकरण सूचियों को मिलाएं।
  • प्रोटोकॉल सत्रों का आविष्कार किए बिना प्रत्येक उपकरण के मालिक सहकर्मी को कॉल रूट करें।

समस्या

एक एजेंट होस्ट आमतौर पर एक से अधिक एमसीपी सर्वर से बात करता है। इसे प्रत्येक सर्वर का पता लगाना, टूल कैटलॉग को मिलाकर, डुप्लिकेट नामों को हल करना, रूट कॉल करना और परिवहन विफलता से ठीक होना चाहिए।

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किसी अन्य अनुरोध से पहले अपने पसंदीदा आधुनिक मेटाडेटा के साथ। तीन परिणाम वर्ग हैंः

  1. DiscoverResult.सर्वर आधुनिक है. आपसी समर्थन वाला संस्करण चुनें और प्रति अनुरोध मेटाडेटा के साथ जारी रखें।
  2. Recognized modern error.सर्वर आधुनिक है.-32022, चुनें data.supportedऔर एक नई अनुरोध आईडी के साथ पुनः प्रयास करें. हेडर या क्षमता त्रुटियों के लिए, अनुरोध को सुधारें. भेज नहीं initialize. .
  3. 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 एडाप्टर को केवल रिकॉर्ड करने के बजाय उस समय सीमा को लागू करना चाहिए।

प्रत्येक कॉल से पहले दोबारा जांच न करें।

विरासत एक संगतता शाखा है

जब सीमांकित जांच वैध सकारात्मक विरासत प्रमाण लौटा देती है, तो ग्राहक चयनित विरासत संस्करण का उपयोग उस संशोधन द्वारा परिभाषित रूप से करता हैः

  1. प्रतिक्रिया लिफाफा और सहसंबंध आईडी की जांच करें।
  2. सत्यापित करें कि वार्तालाप संशोधन कॉन्फ़िगर की गई विरासत सेट में है।
  3. सत्यापित क्षमताओं और सर्वर पहचान को रिकॉर्ड करें।
  4. भेजेंnotifications/initializedकेवल सभी चेक पास होने के बाद।
  5. उस परिवहन जीवनकाल के लिए विरासत अनुरोध रूपों का उपयोग करें।

यह शाखा ज्ञात समकक्षों के साथ सहकार्य के लिए मौजूद है। यह नए सर्वर या नए अनुरोधों के लिए डिफ़ॉल्ट डिज़ाइन नहीं है। यदि परिवहन फिर से शुरू होता है या इसका एंडपॉइंट बदल जाता है, तो समकक्ष युग कैश को त्याग दें और फिर से बातचीत करें।

खोज और कैशिंग उपकरण

प्रत्येक सक्रिय सहकर्मी के लिए, कॉल करें tools/list. एक आधुनिक परिणाम में शामिल है resultType,ttlMsऔर cacheScope. सही अनुमतियों के संदर्भ में ताजापन संकेत का सम्मान करें. समाप्ति या एक सदस्यता सूची परिवर्तन घटना के बाद फिर से प्राप्त करें.

ग्राहकों को एक लापता का इलाज करना चाहिए resultTypeएक विरासत सर्वर से "complete". एक पूर्व वार्ता युग से प्रतिक्रिया पर आधुनिक कैश फ़ील्ड की आवश्यकता नहीं है.

सर्वर को निर्धारक क्रम को लौटा देना चाहिए। क्लाइंट को विलय से पहले क्रमबद्ध करना चाहिए ताकि स्थानीय रजिस्ट्री क्रम प्रक्रिया स्टार्टअप समय पर निर्भर न हो।

टक्कर-सुरक्षित नामस्थान विलय

दो सर्वर दोनों को उजागर कर सकते हैंsearch. घोषित नीति चुनें:

  1. Prefix on collision.पहले कैनोनिक नाम को बनाए रखें और बाद में टकरावों को उजागर करें जैसे <server>/<tool>. .
  2. Reject on collision.डुप्लिकेट को लोड न करें और स्पष्ट कॉन्फ़िगरेशन त्रुटि को उजागर न करें।
  3. 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. यह आधुनिक अनुरोध स्टैम्पिंग, स्टूडियो युग वार्ता, निर्धारक नामस्थान विलय, रूटिंग और एक विफलता बंद विरासत संगतता शाखा को खड़ा करता है।

व्यायाम

  1. एक नकली सर्वर वापसी करें -32022आपसी समर्थित संस्करण के बिना. ग्राहक भेजने के बजाय विफलता की पुष्टि करेंinitialize. .
  2. एक नकली विरासत सर्वर अनुमति दें, इसकी सीमा बनाओ initializeसमय जांच बाहर, और साबित समकक्षों रहता है unknownऔर अनुपलब्ध है।
  3. जोड़ें cacheScope: "private"दो प्राधिकरण संदर्भों के लिए उपकरण सूची। पुष्टि करें कि क्लाइंट कभी भी एक संदर्भ के कैश किए गए परिणाम को दूसरे के साथ साझा नहीं करता है।
  4. टक्कर नीति को अस्वीकृति में बदलें और त्रुटि में दोनों समकक्ष नामों के साथ स्टार्टअप विफलता बनाएं।
  5. एक अंत जोड़ें subscriptions/listenस्ट्रीम हानि पर, एक नया अनुरोध आईडी के साथ फिर से सुनें और रीफैच उपकरण।

प्रमुख शर्तें

TermMeaning
PeerClient-side record for one server transport and its discovered data
Protocol eraModern per-request metadata or legacy initialization semantics
Discovery probeInitial server/discover used to identify the stdio era
Recognized modern errorError that proves modern behavior and forbids legacy fallback
Legacy allowlistOperator configuration permitting one bounded compatibility probe for a pinned peer
Positive legacy evidenceValid, correlated initialize result for an explicitly supported legacy revision
Merged namespaceCanonical tool names across all active peers
Collision policyPrefix or reject rule for duplicate tool names
Era cacheSelected modern or legacy behavior stored for one transport peer
Transport recoveryRestart 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.