Model Context Protocol स्पेसिफ़िकेशन में बदलाव: क्या नया है और क्या टूटेगा
Model Context Protocol का 2026-07-28 संशोधन MCP को स्टेटलेस बनाता है: न कोई initialize हैंडशेक, न Mcp-Session-Id, राउटिंग के नए हेडर, कैश की जा सकने वाली सूचियाँ और elicitation के लिए दोबारा कोशिश करने का पैटर्न। यहाँ हर बदलाव, उससे क्या टूटेगा और माइग्रेट करने का क्रम बताया गया है।
अगर आपका MCP सर्वर दो रिक्वेस्ट के बीच कुछ भी याद रखता है, तो प्रोटोकॉल का नया वर्ज़न उस आदत को बग में बदल चुका है। 2026-07-28 स्पेसिफ़िकेशनinitialize हैंडशेक हटाता है, Mcp-Session-Id हेडर मिटाता है, और MCP को एक सीधा रिक्वेस्ट-और-रिस्पॉन्स प्रोटोकॉल बनाता है, जहाँ हर मैसेज में वह सब होता है जो सर्वर को जवाब देने के लिए चाहिए। कुछ बदलाव छोटे हैं: यहाँ एक हेडर, वहाँ एक बदला हुआ एरर कोड। बाकी ऐसे हैं जो पिछले हफ़्ते ठीक चल रहे सर्वर को भी तोड़ सकते हैं।
यह लेख बदलावों को इस हिसाब से छाँटता है कि वे कितना नुकसान करते हैं, और आधिकारिक changelog व घोषणा पोस्ट को प्रामाणिक स्रोत मानता है। आपको सटीक फ़ील्ड नाम, SEP नंबर, उस चीज़ की तालिका जो हटाई गई है बनाम जो सिर्फ़ डेप्रिकेट हुई है, और एक माइग्रेशन क्रम मिलेगा जिसे आप एक ही स्प्रिंट में पूरा कर सकते हैं।
💡 संक्षेप में: सेशन खत्म हो गए हैं, सर्वर-इनिशिएटेड रिक्वेस्ट अब retry पैटर्न इस्तेमाल करती हैं, लिस्ट रिज़ल्ट कैश हो सकते हैं, ऑथराइज़ेशन और सख़्त हुआ है, और tasks एक एक्सटेंशन में चले गए हैं। Roots, Sampling और Logging अब भी काम करते हैं, लेकिन कम से कम बारह महीने के लिए ही।
यह संशोधन अलग क्यों है
पिछले संशोधनों ने फ़ीचर जोड़े थे। इस बार धारणाएँ हटाई गई हैं। स्टेटफ़ुल, दोतरफ़ा कनेक्शन से स्टेटलेस एक्सचेंज की ओर यह बदलाव हर ट्रांसपोर्ट, हर SDK और सर्वर के सामने लगे हर गेटवे को छूता है।
पाँच संशोधन, एक दिशा
वर्ज़न
मुख्य बदलाव
2024-11-05
क्लाइंट-सर्वर आर्किटेक्चर, JSON-RPC 2.0, टूल्स, रिसोर्सेज़, प्रॉम्प्ट, stdio और SSE के साथ HTTP
2025-03-26
OAuth 2.1 आधारित ऑथराइज़ेशन, Streamable HTTP ने HTTP+SSE की जगह ली, टूल एनोटेशन, ऑडियो कंटेंट, JSON-RPC बैचिंग
2025-06-18
स्ट्रक्चर्ड टूल आउटपुट, एलिसिटेशन, रिसोर्स लिंक, सर्वर को OAuth रिसोर्स सर्वर के रूप में वर्गीकृत किया गया, बैचिंग हटाई गई
स्टेटलेस कोर, कोई सेशन नहीं, Multi Round-Trip Requests, रूटिंग हेडर, कैश करने योग्य लिस्ट, एक्सटेंशन फ़्रेमवर्क
दाएँ कॉलम को नीचे पढ़ें तो दिशा साफ़ दिखती है। हर संशोधन MCP को एक लंबे समय तक चलने वाले, चैट जैसे सॉकेट से दूर ले जाता है और उस दिशा में ले जाता है जिसे लोड बैलेंसर, CDN और सर्वरलेस रनटाइम बिना किसी खास व्यवस्था के संभाल सकें।
रिलीज़ खुद वहाँ पहले से समर्थित है जहाँ इसकी सबसे ज़्यादा ज़रूरत है। चारों Tier 1 SDKs (TypeScript, Python, Go और C#) 2026-07-28 बोलते हैं, और Rust SDK बीटा में इसे सपोर्ट करता है। मेंटेनर मानते हैं कि "कुछ माइग्रेशन लागत होगी, खासकर उन डेवलपर्स के लिए जो session identifiers पर निर्भर थे", और जोड़ते हैं कि शुरुआती टेस्टिंग के फ़ीडबैक ने इस प्रक्रिया को आसान बनाया।
स्टेटलेस कोर
दो प्रस्ताव ही ज़्यादातर नुकसान करते हैं: SEP-2567 sessions हटाता है, और SEP-2575 handshake हटाकर नोटिफ़िकेशन कैसे भेजे जाते हैं, यह बदलता है।
कोई हैंडशेक नहीं, कोई Session ID नहीं
initialize रिक्वेस्ट और notifications/initialized खत्म हो गए हैं, और Mcp-Session-Id भी। लिस्ट एंडपॉइंट (tools/list, resources/list, prompts/list) अब हर कनेक्शन के हिसाब से अलग-अलग नहीं हो सकते, क्योंकि अब कोई कनेक्शन पहचान बची ही नहीं जिसके आधार पर बदला जा सके। जब किसी टूल को कॉल्स के बीच स्टेट चाहिए, तो सर्वर एक स्पष्ट हैंडल बनाता है, जैसे कार्ट ID या वर्कस्पेस ID, और मॉडल उसे एक सामान्य टूल आर्गुमेंट के रूप में वापस भेजता है।
हैंडशेक की जगह, हर रिक्वेस्ट अपना संदर्भ _meta में साथ लेकर चलती है। यह स्केच आकार दिखाता है, स्पेक से कॉपी नहीं किया गया:
वर्ज़न मिसमैच UnsupportedProtocolVersionError लौटाता है, और सर्वर हर रिज़ल्ट में io.modelcontextprotocol/serverInfo के ज़रिए खुद की पहचान बताते हैं।
⚠️ छिपी हुई स्टेट ही असली जोखिम है। Session ID से चिह्नित in-memory maps, प्रति-कनेक्शन लॉग लेवल और प्रति-कनेक्शन subscription lists, सब काम करना बंद कर देते हैं। कोड सर्च में ये आसानी से छूट जाते हैं, क्योंकि इनमें अक्सर शब्द "session" नहीं होता।
वर्ज़न और क्षमताओं की घोषणा। सर्वरों को अब server/ नेमस्पेस में एक नया RPC लागू करना होगा, जो उनके समर्थित प्रोटोकॉल वर्ज़न, क्षमताएँ और पहचान बताता है। क्लाइंट कुछ और करने से पहले इसे कॉल करके पहले से वर्ज़न चुन सकते हैं, और STDIO पर यह बैकवर्ड-कंपैटिबिलिटी प्रोब के रूप में काम करता है। changelog इसे सीधे handshake हटाने के बाद सूचीबद्ध करता है, इसलिए इसे जोड़ने से पहले सटीक मेथड नाम और रिस्पॉन्स का आकार schema पेज पर जाँच लें।
GET स्ट्रीम की जगह क्या आया
HTTP GET एंडपॉइंट, resources/subscribe और resources/unsubscribe की जगह अब एक ही कॉल है: subscriptions/listen। यह एक लंबे समय तक चलने वाली POST-response स्ट्रीम खोलती है, और क्लाइंट उन change types को चुनते हैं जिनकी उन्हें परवाह है:
toolsListChanged
promptsListChanged
resourcesListChanged
resourceSubscriptions
सर्वर हर नोटिफ़िकेशन को स्वीकार करता है और io.modelcontextprotocol/subscriptionId से टैग करता है। notifications/progress और notifications/message जैसे रिक्वेस्ट-स्कोप्ड मैसेज उसी रिक्वेस्ट की response स्ट्रीम पर रहते हैं, जिससे वे संबंधित हैं।
तीन और हटाव साथ आते हैं: ping, logging/setLevel और notifications/roots/list_changed। लॉग लेवल अब io.modelcontextprotocol/logLevel के ज़रिए हर रिक्वेस्ट के लिए सेट होता है, और सर्वर को ऐसी रिक्वेस्ट के लिए notifications/messageनहीं भेजना चाहिए जिसमें वह सेट न हो।
SSE का resumability भी खत्म हो गया है। अब Last-Event-ID हेडर नहीं है और न event IDs, इसलिए टूटी हुई response स्ट्रीम चल रही रिक्वेस्ट को खो देती है, और क्लाइंट को उसे नए रिक्वेस्ट ID के साथ फिर से भेजना पड़ता है। खराब लिंक पर नब्बे सेकंड चलने वाली टूल कॉल अब भाग्य पर नहीं, tasks एक्सटेंशन पर निर्भर है।
Multi Round-Trip Requests को समझें
सर्वर रिक्वेस्ट क्यों हटानी पड़ीं
इस संशोधन से पहले, सर्वर खुली स्ट्रीम पर कॉल के बीच में elicitation/create, sampling/createMessage या roots/list भेज सकता था। इससे क्लाइंट एक ही सर्वर इंस्टेंस से बंध जाता था, और sticky load balancing या साझा स्टोरेज की ज़रूरत पड़ती थी।
Multi Round-Trip Requests (SEP-2322) उस डिज़ाइन की जगह लेते हैं। स्पेक इस पर साफ़ है: सर्वरों को ये रिक्वेस्ट ज़रूर MRTR पैटर्न से भेजनी होंगी, पुराना पैटर्न अब समर्थित नहीं है, और यह एक breaking change है। अब हर रिज़ल्ट में एक ज़रूरी resultType फ़ील्ड भी होता है। एक वैल्यू input_required है, दूसरी सामान्य पूरे हुए रिज़ल्ट को दर्शाती है, और पुराने सर्वर से फ़ील्ड गायब हो तो क्लाइंट उसे सामान्य प्रकार मानते हैं।
Retry लूप कैसे काम करता है
प्रवाह चार चरणों का है:
क्लाइंट एक सामान्य रिक्वेस्ट भेजता है, उदाहरण के लिए tools/call।
सर्वर पूरा नहीं कर सकता, इसलिए वह InputRequiredResult लौटाता है जिसमें लिखा होता है कि उसे क्या चाहिए।
क्लाइंट यूज़र या किसी और स्रोत से जवाब इकट्ठा करता है।
क्लाइंट मूल रिक्वेस्ट को inputResponses के साथ, एक नए JSON-RPC ID से फिर भेजता है।
सिर्फ़ तीन क्लाइंट रिक्वेस्ट को यह रिज़ल्ट मिल सकता है: prompts/get, resources/read और tools/call। हर InputRequiredResult को inputRequests या requestState में से कम से कम एक चाहिए, और सर्वर को ऐसी क्षमता नहीं माँगनी चाहिए जिसे क्लाइंट ने घोषित न किया हो। चूँकि retry से क्लाइंट को पता चल जाता है कि मामला कैसे खत्म हुआ, इसलिए elicitation completion नोटिफ़िकेशन और 2025-11-25 का elicitationId फ़ील्ड हटा दिए गए हैं।
requestState को यूज़र इनपुट की तरह सँभालें
requestState स्ट्रिंग क्लाइंट से होकर गुज़रती है, इसलिए स्पेक कहता है कि उसे attacker-controlled मानें। अगर वह ऑथराइज़ेशन, रिसोर्स एक्सेस या बिज़नेस लॉजिक को प्रभावित करती है, तो उसकी अखंडता HMAC या AEAD से सुरक्षित करें और जो भी verification में फ़ेल हो उसे अस्वीकार करें।
Replay सुरक्षा के लिए, तीन चीज़ें protected payload के अंदर रखें और हर एक को मिलने पर जाँचें:
प्रमाणित प्रिंसिपल
एक छोटी एक्सपायरी
उत्पत्ति वाली रिक्वेस्ट की पहचान, जैसे मेथड नाम और उसके मुख्य पैरामीटर्स का डाइजेस्ट
ये उपाय replay को सीमित करते हैं, लेकिन एक बार ही इस्तेमाल होने की गारंटी नहीं देते। एक-बार-रिडीम होने वाला नियम सर्वर पर लागू करना होगा।
हेडर, कैशिंग और एरर कोड
गेटवे के लिए Routing Headers
SEP-2243 हर Streamable HTTP POST रिक्वेस्ट पर Mcp-Method और Mcp-Name माँगता है। मकसद परिचालन (operational) है: गेटवे और WAF अब JSON बॉडी पार्स किए बिना MCP ट्रैफ़िक को रूट, मीटर और रेट-लिमिट कर सकते हैं। कस्टम हेडर x-mcp-header के ज़रिए टूल पैरामीटर्स से भी निकाले जा सकते हैं, और हेडर व बॉडी के बीच का मिसमैच HeaderMismatch एरर के रूप में दिखता है, जो अब स्कीमा में मौजूद है।
💡 अगर आपके MCP सर्वर के सामने API गेटवे है, तो यही वह बदलाव है जो सबसे पहले फ़ायदा देता है। बॉडी पर regex लिखने की बजाय दो हेडर पर नियम लिखें।
कैश हिंट और एरर कोड
SEP-2549 एक CacheableResult इंटरफ़ेस जोड़ता है। tools/list, prompts/list, resources/list, resources/read और resources/templates/list के रिज़ल्ट में अब ये होना ज़रूरी है:
ttlMs: मिलीसेकंड में एक freshness हिंट, ताकि क्लाइंट पोलिंग की बजाय कैश कर सकें
cacheScope: "public" या "private", जो बताता है कि शेयर्ड इंटरमीडियरी उस response को स्टोर कर सकते हैं या नहीं
ये दोनों मौजूदा listChanged नोटिफ़िकेशन के पूरक हैं। सर्वर को टूल्स को डिटरमिनिस्टिक क्रम में भी लौटाना चाहिए, जिससे क्लाइंट कैश को मदद मिलती है और मॉडल की ओर प्रॉम्प्ट कैश हिट रेट बढ़ते हैं।
एरर कोड भी एक नई आवंटन नीति के तहत बदले गए हैं: -32000 से -32019 तक के कोड implementation-defined ही रहते हैं, और -32020 से -32099 तक के कोड विनिर्देश के लिए आरक्षित हैं।
एरर
पुराना कोड
नया कोड
रिसोर्स नहीं मिला
-32002
-32602 (Invalid Params)
HeaderMismatch
-32001
-32020
MissingRequiredClientCapability
-32003
-32021
UnsupportedProtocolVersion
-32004
-32022
अगर कोई क्लाइंट पुराने नंबरों के आधार पर अलग-अलग तर्क चलाता है, तो वह नई एरर को गलत समझेगा।
ऑथराइज़ेशन और सख़्त हुआ है
Issuer जाँच और बाउंड क्रेडेंशियल
तीन बदलाव OAuth फ़्लो को कसते हैं:
SEP-2468: ऑथराइज़ेशन सर्वर को RFC 9207 का iss पैरामीटर शामिल करना चाहिए, और क्लाइंट्स को ऑथराइज़ेशन कोड रिडीम करने से पहले मौजूद iss को दर्ज किए गए issuer से मिलाना चाहिए।
SEP-2352: क्लाइंट क्रेडेंशियल्स उस ऑथराइज़ेशन सर्वर से बंधे होते हैं जिसने उन्हें जारी किया। उन्हें issuer identifier के आधार पर सहेजें, किसी दूसरे सर्वर के साथ कभी दोबारा इस्तेमाल न करें, और सर्वर बदलने पर फिर से रजिस्टर करें।
SEP-837: Dynamic Client Registration के दौरान क्लाइंट्स को एक उपयुक्त application_type भेजना ज़रूरी है, जिससे localhost पर OpenID Connect redirect URI के टकराव को रोका जा सके।
Dynamic Registration अब जाने की राह पर है
OAuth 2.0 Dynamic Client Registration प्रोटोकॉल (RFC 7591) को Client ID Metadata Documents के पक्ष में डेप्रिकेट किया गया है। यह उन authorization servers के लिए काम करता रहेगा जिनमें नया विकल्प नहीं है, लेकिन घोषणा के अनुसार स्पेक के किसी बाद के वर्ज़न में इसे हटा दिया जाएगा। स्विच की योजना अभी बना लें, किसी incident के दौरान नहीं।
Tasks, Schemas और Extensions
Tasks एक Extension में जाते हैं
प्रयोगात्मक tasks कोर प्रोटोकॉल से निकलकर आधिकारिक io.modelcontextprotocol/tasks एक्सटेंशन बन गए हैं (SEP-2663)। इस री-डिज़ाइन में ब्लॉकिंग tasks/result मेथड की जगह tasks/get के ज़रिए पोलिंग होती है, tasks/update जुड़ता है ताकि क्लाइंट चल रहे task को इनपुट भेज सके, और tasks/list हटा दिया गया है। अब सर्वर क्लाइंट के माँगे बिना भी task handle लौटा सकते हैं।
यह आखिरी बात लंबे जॉब्स के लिए मायने रखती है। धीमा रिपोर्ट जेनरेटर अब response स्ट्रीम खुली नहीं रखता; वह एक handle लौटाता है, क्लाइंट पोल करता है, और कनेक्शन टूटने से कुछ नहीं बिगड़ता।
ढीले स्कीमा और नए एक्सटेंशन स्लॉट
छोटे जोड़ जिनका एक-एक पंक्ति में ज़िक्र करना ज़रूरी है:
inputSchema और outputSchema में JSON Schema 2020-12 का कोई भी कंस्ट्रक्ट इस्तेमाल हो सकता है, और structuredContent कोई भी JSON वैल्यू हो सकती है (SEP-2106)। इसके साथ $ref के रिज़ॉल्यूशन के नए नियम आए हैं, और कंपोज़िशन कंस्ट्रक्ट्स पर संसाधन सीमाएँ (resource bounds) तय की गई हैं।
ClientCapabilities और ServerCapabilities में extensions फ़ील्ड जुड़ता है, जो कोर से आगे के वैकल्पिक फ़ीचर्स के लिए है।
OpenTelemetry ट्रेस कॉन्टेक्स्ट _meta में traceparent, tracestate और baggage के ज़रिए आगे जाता है (SEP-414)।
Cloudflare के लेख में बताया गया है कि उसका /mcp एंडपॉइंट नए stateless रिक्वेस्ट और 2025 के दौर के क्लाइंट, दोनों स्वीकार करता है। किसी सार्वजनिक सर्वर को चलाने वाले के लिए यह एक समझदार पैटर्न है।
क्या टूटता है और उसे कैसे ठीक करें
हटाए गए फ़ीचर
ये 2026-07-28 के peer के सामने सीधे फ़ेल होंगे:
हटाया गया
विकल्प
initialize और notifications/initialized
प्रति-रिक्वेस्ट _meta फ़ील्ड
Mcp-Session-Id हेडर
टूल आर्गुमेंट्स में सर्वर-जनित हैंडल
HTTP GET एंडपॉइंट, resources/subscribe, resources/unsubscribe
डेप्रिकेट होना हटना नहीं है। ये कम से कम बारह महीनों तक नई feature lifecycle policy (SEP-2596) के तहत काम करते रहेंगे, जो Active, Deprecated और Removed स्टेट्स और एक पब्लिक रजिस्ट्री तय करती है:
डेप्रिकेटेड
सुझाया गया विकल्प
Roots (SEP-2577)
टूल पैरामीटर्स, रिसोर्स URIs, या सर्वर कॉन्फ़िगरेशन
Sampling (SEP-2577)
LLM प्रोवाइडर API को सीधे कॉल करें
Logging (SEP-2577)
stderr पर लिखें, या OpenTelemetry इस्तेमाल करें
HTTP+SSE transport
Streamable HTTP
includeContext values "thisServer" और "allServers"
"none" या फ़ील्ड हटाएँ
Dynamic Client Registration
Client ID Metadata Documents
कुछ लेख Roots, Sampling और Logging को हटाए गए फ़ीचर्स के साथ गिन लेते हैं। स्पेक का पाठ इन्हें डेप्रिकेटेड कहता है, इसलिए इन्हें आउटेज नहीं, कैलेंडर की एक तारीख मानें। असल में सिर्फ़ ping और logging/setLevel गए हैं।
एक काम करने वाला माइग्रेशन क्रम
पहले SDK अपग्रेड करें। 2026-07-28 सपोर्ट करने वाला Tier 1 रिलीज़ लें और अपने कोड को छूने से पहले उसके माइग्रेशन नोट्स पढ़ें।
सेशन स्टेट खोजें।Mcp-Session-Id और connection के आधार पर बने किसी भी map को खोजें। हर एक की जगह टूल आर्गुमेंट के रूप में पास होने वाला स्पष्ट हैंडल रखें।
दोनों पीढ़ियाँ स्वीकार करें। ट्रांज़िशन के दौरान पुराने और नए क्लाइंट को एक ही एंडपॉइंट से सर्व करें, जैसा Cloudflare करता है।
सर्वर-इनिशिएटेड कॉल्स दोबारा लिखें। हर elicitation, sampling और roots कॉल को एक InputRequiredResult में बदलें जिसमें साइन किया हुआ requestState हो।
कैश फ़ील्ड जोड़ें। list और read रिज़ल्ट पर ttlMs और cacheScope लौटाएँ, और tool lists को डिटरमिनिस्टिक क्रम में लगाएँ।
गेटवे नियम अपडेट करें।Mcp-Method और Mcp-Name पर रूट करें, फिर बॉडी-पार्सिंग नियम हटा दें।
ऑथराइज़ेशन ठीक करें।iss को वैलिडेट करें, क्रेडेंशियल्स issuer के हिसाब से सहेजें, और Client ID Metadata Documents पर जाने की योजना बनाएँ।
फिर मुश्किल केस टेस्ट करें: किसी रिक्वेस्ट के बीच response स्ट्रीम बंद करें, पुराना requestState दोबारा चलाएँ, और बिना sticky routing के दो सर्वर इंस्टेंस चलाएँ। अगर तीनों ठीक व्यवहार करें, तो माइग्रेशन सही है।
💡 स्पीड टिप: अपने सर्वर का session-handling कोड और ऊपर का changelog सेक्शन Picasso IA पर Claude Sonnet 5 में पेस्ट करें और हर उस जगह की सूची माँगें जहाँ स्टेट रिक्वेस्ट्स के बीच लीक होती है। आउटपुट खुद जाँचें, क्योंकि मॉडल किसी helper function के पीछे छिपा map छोड़ सकता है।
अपने खुद के विज़ुअल बनाएँ
इस जैसे तकनीकी पोस्ट अपने डायग्राम और हेडर इमेज पर टिके होते हैं, और इनके लिए डिज़ाइन टीम की ज़रूरत नहीं। Picasso IA एक जगह दर्जनों इमेज मॉडल देता है, इसलिए आप एक ही प्रॉम्प्ट को कई पर आज़माकर सबसे अच्छा नतीजा रख सकते हैं।
फ़ोटोरियलिस्टिक दृश्यों के लिए Seedream 5 Pro आज़माएँ, सटीक प्रॉम्प्ट फ़ॉलो करने के लिए GPT Image 2, या जब इमेज में पढ़ने लायक टेक्स्ट चाहिए तब Ideogram v4 Quality। दृश्य का वर्णन करें, 16:9 आस्पेक्ट रेशियो चुनें, और कोई भी पक्का करने से पहले कुछ वैरिएशन जनरेट करें।
Picasso IA खोलें, एक मॉडल चुनें, और अपने अगले MCP लेख के लिए आज ही पहली इमेज बनाएँ।