28 जुलाई 2026 को Model Context Protocol ने अपने स्पेसिफ़िकेशन का एक नया संस्करण प्रकाशित किया। चेंजलॉग दो ऐसी बातों से शुरू होता है जो हर रिमोट सर्वर के काम करने का तरीक़ा बदल देती हैं: प्रोटोकॉल स्तर के सेशन हटा दिए गए हैं, और initialize हैंडशेक भी। अब हर रिक्वेस्ट अपने साथ वह सब कुछ लाती है जिसकी सर्वर को जवाब देने के लिए ज़रूरत है।
कई सर्वरों के लिए यह एक माइग्रेशन है। पहचान दस्तावेज़ पढ़ने वाले सर्वर के लिए यह ज़्यादा एक पुष्टि जैसा है, क्योंकि ऐसे सर्वर के पास पहले से ही स्टेटलेस होने की अच्छी वजहें थीं। यह पोस्ट इस संस्करण को एक टूल सर्वर की नज़र से देखती है: किन बदलावों को वह अनदेखा कर सकता है, किन्हें उसे बनाना ही होगा, और किन्हें जल्दी अपनाना फ़ायदेमंद है। उदाहरण हमारे अपने चलाए सर्वर से हैं, इसलिए नीचे बताई गई कमियाँ हमारी भी हैं।
यह doc.cheap का ब्लॉग है, जो एक पासपोर्ट और आईडी OCR API है और उसके आगे एक MCP सर्वर है। प्रोडक्ट वाले हिस्सों को इसी बात को ध्यान में रखकर पढ़ें।
संक्षेप में
| 2026-07-28 में बदलाव | एक स्टेटलेस टूल सर्वर क्या करता है |
|---|---|
न Mcp-Session-Id, न सेशन |
कुछ नहीं, अगर उसने कभी सेशन रखा ही नहीं |
initialize हैंडशेक नहीं; वर्ज़न और क्षमताएँ हर रिक्वेस्ट के _meta में |
इन्हें हर रिक्वेस्ट में पढ़ें, MCP-Protocol-Version हेडर से मिलाएँ |
server/discover |
इसे लागू करें: यह MUST है |
Mcp-Method और Mcp-Name हेडर अनिवार्य |
जाँचें कि वे बॉडी से मेल खाते हैं |
हर नतीजे पर resultType |
"complete" भेजें |
लिस्ट और रीड नतीजों पर ttlMs और cacheScope |
कैश की अवधि और स्कोप चुनें |
| टूल एक निर्धारित क्रम में | रजिस्ट्रेशन का क्रम स्थिर रखें |
| HTTP GET स्ट्रीम और रिज़्यूम करने की सुविधा हटाई गई | GET और DELETE का जवाब 405 से दें |
| Roots, Sampling और Logging डिप्रिकेटेड | फ़ाइलें टूल आर्ग्युमेंट के रूप में लें, लॉग stderr या OpenTelemetry में लिखें |
बाक़ी पोस्ट हर पंक्ति को समझाती है, और यह भी कि दस्तावेज़ संभालने वाले सर्वर के लिए वह ज़्यादा मायने क्यों रखती है।
सेशन ख़त्म, और यह दस्तावेज़ सर्वरों को सूट करता है
चेंजलॉग की पहली बात "protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport" हटाती है, यानी Streamable HTTP ट्रांसपोर्ट से प्रोटोकॉल स्तर के सेशन और यह हेडर। tools/list जैसे लिस्ट एंडपॉइंट "no longer vary per-connection", यानी अब हर कनेक्शन के हिसाब से नहीं बदलते, और जिन सर्वरों को कॉल के बीच स्टेट चाहिए वे "use explicit, server-minted handles passed as ordinary tool arguments": सर्वर के बनाए स्पष्ट हैंडल इस्तेमाल करते हैं, जो सामान्य टूल आर्ग्युमेंट की तरह भेजे जाते हैं।
दस्तावेज़ सर्वर को आम तौर पर सेशन की ज़रूरत ही नहीं होती। सोचिए कि एक सेशन में क्या रहता: एक API की, शायद पढ़े जाने का इंतज़ार करती एक इमेज, शायद आख़िरी नतीजा। यह सब ऐसा डेटा है जिसे आप कॉल के बीच किसी प्रोसेस की मेमोरी में नहीं रखना चाहेंगे, जहाँ एक बग उसे अगले कॉलर को थमा सकता है।
https://mcp.doc.cheap/mcp पर हमारा होस्टेड सर्वर इस संस्करण से पहले ही इसी तरह बना था। कोड कहता है कि यह "stateless on purpose" है, यानी जान-बूझकर स्टेटलेस: हर POST को एक नया सर्वर और नया ट्रांसपोर्ट मिलता है, वह जवाब देता है और फिर फेंक दिया जाता है, ताकि "no session lives in memory, a restart loses nothing, and one caller's key can never be seen by another caller's request": मेमोरी में कोई सेशन नहीं रहता, रीस्टार्ट से कुछ नहीं खोता, और एक कॉलर की की कभी दूसरे कॉलर की रिक्वेस्ट को नहीं दिख सकती। ट्रांसपोर्ट सेशन आईडी जनरेटर के बिना बनाया जाता है, और TypeScript SDK में यही उसे स्टेटलेस बनाता है; जवाब स्ट्रीम के बजाय सादे JSON में आता है।
संस्करण जिस हैंडल पैटर्न का वर्णन करता है, वह भी पहले से मौजूद है। जब कोई agent सहेजा हुआ नतीजा वापस चाहता है, तो वह उसे याद रखने के लिए सेशन पर निर्भर नहीं करता। scan_document एक स्कैन आईडी लौटाता है, और get_scan और delete_scan टूल उस आईडी को सामान्य scan_id आर्ग्युमेंट की तरह लेते हैं। आईडी ही हैंडल है। सर्वर का कोई भी इंस्टेंस उसका जवाब दे सकता है, और कल दोबारा कनेक्ट होने वाला क्लाइंट भी उसे इस्तेमाल कर सकता है।
अगर आपका सर्वर हर सेशन के लिए कुछ रखता है, तो पूछने लायक़ सवाल वही है: क्या वह एक ऐसी आईडी बन सकता है जिसे सर्वर लौटाए और क्लाइंट वापस भेजे? दस्तावेज़ों के काम में जवाब आम तौर पर हाँ होता है, और आम तौर पर यह प्राइवेसी के लिए भी फ़ायदा है।
कोई हैंडशेक नहीं: वर्ज़न हर रिक्वेस्ट के साथ चलता है
दूसरी बात MCP को प्रोटोकॉल स्तर पर स्टेटलेस बनाती है। initialize और notifications/initialized का आदान-प्रदान हटा दिया गया है, और "every request now carries its protocol version and client capabilities in _meta": अब हर रिक्वेस्ट अपना प्रोटोकॉल वर्ज़न और क्लाइंट की क्षमताएँ _meta में लाती है। HTTP पर वर्ज़न एक हेडर में भी जाता है। Streamable HTTP पेज कहता है कि हर POST "MUST include an MCP-Protocol-Version header", और उसकी वैल्यू _meta वाली वैल्यू से मेल खानी चाहिए; वरना सर्वर HeaderMismatch एरर के साथ 400 लौटाता है।
नए रूप में किसी दस्तावेज़ टूल का कॉल कुछ ऐसा दिखता है। हेडर और _meta की कुंजियाँ स्पेसिफ़िकेशन के अपने उदाहरण के अनुसार हैं; टूल और उसके आर्ग्युमेंट हमारे हैं, प्लेसहोल्डर के साथ:
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: scan_document
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "scan_document",
"arguments": { "image_base64": "<base64 image>", "retain_hours": 0 },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "<client>", "version": "<version>" },
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
सर्वर के लिए इसका मतलब है एक हैंडशेक की जगह हर रिक्वेस्ट पर तीन जाँचें:
- वर्ज़न। अगर सर्वर माँगे गए वर्ज़न को सपोर्ट नहीं करता, तो वह 400 के साथ एक
UnsupportedProtocolVersionErrorलौटाता है, जिसमें उसके सपोर्ट किए गए वर्ज़न की सूची होती है। - हेडर बनाम बॉडी।
Mcp-Methodहर रिक्वेस्ट पर अनिवार्य है, औरMcp-Nametools/call,resources/readऔरprompts/getपर। ये मेथड और टूल के नाम को दोहराते हैं, और बेमेल होनाHeaderMismatchएरर है। - क्षमताएँ। सर्वर पहले
initializeसे जो कुछ याद रखता था, अब वह उसे हाथ में मौजूद रिक्वेस्ट से पढ़ता है।
दस्तावेज़ सर्वर के लिए हेडर जितने दिखते हैं उससे ज़्यादा अहम हैं। एक scan_document कॉल पूरी इमेज base64 में लाता है; हमारा होस्टेड सर्वर 36 MiB तक की रिक्वेस्ट बॉडी स्वीकार करता है। Mcp-Method और Mcp-Name हेडर में होने से कोई गेटवे महँगे टूल को सस्ते टूलों से अलग रूट कर सकता है, गिन सकता है या उसकी रेट लिमिट कर सकता है, वह भी बॉडी पढ़े बिना। स्पेसिफ़िकेशन ऐसे गेटवे के लिए एक चेतावनी जोड़ता है: उन्हें "SHOULD verify", यानी जाँचना चाहिए कि वर्ज़न हेडर ऐसे वर्ज़न का नाम देता है जिसमें हेडर और बॉडी का सत्यापन ज़रूरी है, और वरना रिक्वेस्ट ठुकरा देनी चाहिए, बजाय ऐसे हेडर पर भरोसा करने के जिसे किसी ने जाँचा ही नहीं।
server/discover अनिवार्य है
तीसरी बात server/discover जोड़ती है, और "servers MUST implement this RPC to advertise their supported protocol versions, capabilities, and identity": सर्वरों को अपने सपोर्ट किए गए प्रोटोकॉल वर्ज़न, क्षमताएँ और पहचान बताने के लिए यह RPC लागू करना ही होगा। क्लाइंट वर्ज़न चुनने के लिए इसे सबसे पहले कॉल कर सकते हैं, या stdio पर इसे कम्पैटिबिलिटी जाँच की तरह इस्तेमाल कर सकते हैं।
यह अकेला बदलाव है जिसे स्टेटलेस सर्वर छोड़ नहीं सकता। हमारा सर्वर अब भी GET / पर एक छोटा डिस्कवरी दस्तावेज़ दिखाता है (नाम, वर्ज़न, ट्रांसपोर्ट और एंडपॉइंट), लेकिन वह एक सादा वेब पेज है, प्रोटोकॉल मेथड नहीं। जो सर्वर 2026-07-28 बोलना चाहता है, वह server/discover का जवाब ख़ुद देता है।
नतीजे: resultType, कैशिंग और क्रम
तीन छोटी बातें बदलती हैं कि नतीजा कैसा दिखता है।
resultType। अब हर नतीजे में यह होता है: सामान्य जवाब के लिए"complete", और कई राउंड-ट्रिप वाली रिक्वेस्ट के बीच के जवाब के लिए"input_required"। क्लाइंट "MUST treat results from earlier-protocol servers that omit the field as"complete"", यानी पुराने प्रोटोकॉल वाले सर्वरों के जिन नतीजों में यह फ़ील्ड नहीं है, उन्हें"complete"मानना होगा; इसलिए पुराना सर्वर चलता रहता है, लेकिन नया सर्वर इसे भेजता है।ttlMsऔरcacheScope।tools/list,prompts/list,resources/list,resources/readऔरresources/templates/listके नतीजों में मिलीसेकंड में ताज़गी का संकेत और एक स्कोप होना चाहिए,"public"या"private"। जिस सर्वर की टूल लिस्ट सिर्फ़ डिप्लॉय पर बदलती है और जिसके रिसोर्स पैकेज के साथ आने वाला डॉक्यूमेंटेशन हैं, उसके लिए"public"के साथ लंबाttlMsस्वाभाविक है। कॉलर की की पर निर्भर रिसोर्स"private"होगा।- टूलों का निर्धारित क्रम। सर्वरों को "SHOULD return tools from
tools/listin a deterministic order", ताकि क्लाइंट कैशिंग और प्रॉम्प्ट कैश हिट में मदद मिले। अगर टूल कोड में तय क्रम से रजिस्टर होते हैं, तो उसे वैसा ही रहने दें; हमारा सर्वर छह टूल हर बार एक ही क्रम में रजिस्टर करता है।
यूज़र से और जानकारी माँगना: कई राउंड-ट्रिप वाली रिक्वेस्ट
पुराने संस्करण सर्वर को कॉल के बीच में क्लाइंट को अपनी रिक्वेस्ट भेजने देते थे: यूज़र से कुछ पूछने के लिए elicitation/create, क्लाइंट का मॉडल उधार लेने के लिए sampling/createMessage, अनुमत फ़ोल्डर जानने के लिए roots/list। नया संस्करण इसकी जगह Multi Round-Trip Requests पैटर्न लाता है। सर्वर resultType: "input_required" और inputRequests की एक सूची के साथ जवाब देता है, और क्लाइंट मूल रिक्वेस्ट को inputResponses के साथ दोबारा भेजता है।
दस्तावेज़ टूल के लिए यह "फ़ोटो बाईं ओर से कटी है, दूसरी भेजेंगे?" जैसे सवाल की साफ़-सुथरी जगह है। चूँकि दोबारा भेजी गई रिक्वेस्ट वही रिक्वेस्ट है, इसलिए दोनों कॉल के बीच सर्वर पर कुछ भी रखने की ज़रूरत नहीं पड़ती। जो सर्वर, हमारे सर्वर की तरह, सर्वर की ओर से शुरू की जाने वाली किसी भी रिक्वेस्ट का इस्तेमाल नहीं करता था, उसके पास यहाँ माइग्रेट करने को कुछ नहीं है।
क्या डिप्रिकेटेड है, और उसकी जगह क्या इस्तेमाल करें
Roots, Sampling और Logging डिप्रिकेटेड हैं। वे कम से कम बारह महीने की डिप्रिकेशन अवधि तक काम करते रहेंगे, लेकिन "new implementations should not add support for them": नए इम्प्लीमेंटेशन को इनका सपोर्ट नहीं जोड़ना चाहिए। सुझाए गए विकल्प दस्तावेज़ सर्वर पर अच्छे से बैठते हैं:
- Roots की जगह, फ़ाइलें टूल आर्ग्युमेंट या कॉन्फ़िगरेशन के ज़रिए दें। हमारा लोकल सर्वर फ़ाइल पाथ तभी पढ़ता है जब उसके कॉन्फ़िगरेशन में इमेज डायरेक्टरी सेट हो, और सिर्फ़ उसी डायरेक्टरी के अंदर; उसके बाहर का पाथ ठुकरा दिया जाता है। आर्ग्युमेंट मॉडल चुनता है; बाड़ ऑपरेटर तय करता है।
- Logging की जगह, stderr या OpenTelemetry में लॉग लिखें। यह संस्करण
logging/setLevelको भी हटाता है; लॉग लेवल अब हर रिक्वेस्ट के साथ_metaमें जाता है, और सर्वरों को उन रिक्वेस्ट के लिए लॉग मैसेज नहीं भेजने चाहिए जिन्होंने उन्हें माँगा नहीं। ट्रेस कॉन्टेक्स्ट (traceparent) भी_metaमें जा सकता है।
पुराने क्लाइंट कॉल करते रहेंगे
सारे क्लाइंट एक ही दिन नए संस्करण पर नहीं आते, इसलिए ट्रांसपोर्ट पेज बताता है कि सिर्फ़ 2026-07-28 सपोर्ट करने वाले सर्वर को पुराने ट्रैफ़िक के साथ क्या करना चाहिए:
- MCP एंडपॉइंट पर GET या DELETE: 405 Method Not Allowed।
Mcp-Session-Idहेडर: उसे अनदेखा करें, और कभी कोई सेशन आईडी न बनाएँ, न लौटाएँ।Last-Event-IDहेडर: उसे अनदेखा करें, क्योंकि स्ट्रीम अब रिज़्यूम नहीं होतीं।
हमारा होस्टेड सर्वर अपने एंडपॉइंट पर GET और DELETE का जवाब पहले से ही 405 और Allow: POST, OPTIONS हेडर के साथ देता है, और कोई सेशन आईडी नहीं बनाता। जो क्लाइंट अब भी पुराना संस्करण बोलता है, उसे यह एरर बॉडी से पता चलता है: स्पेसिफ़िकेशन उसे initialize पर तभी लौटने को कहता है जब 400 की बॉडी कोई पहचाना हुआ आधुनिक एरर न हो।
हमारा सर्वर कहाँ खड़ा है
सटीक कहें तो: होस्टेड सर्वर TypeScript SDK के वर्ज़न 1.30.0 पर बना है, और हमारा अपना कोड अभी कहीं भी 2026-07-28 का नाम नहीं लेता। ऊपर के जो हिस्से उस पर पहले से लागू होते हैं, वे उसके डिज़ाइन से आते हैं: कोई सेशन नहीं, हैंडल के रूप में आईडी, GET और DELETE के लिए 405, कॉन्फ़िगरेशन से घिरी फ़ाइलें। server/discover, हेडर की जाँचें, resultType और कैश फ़ील्ड वह काम हैं जो बाक़ी है। पासपोर्ट OCR MCP सर्वर पेज और MCP सर्वर गाइड बताते हैं कि आज क्लाइंट किससे कनेक्ट होते हैं।
अगर आप agents के लिए दस्तावेज़ API चुन रहे हैं, तो पासपोर्ट OCR API तुलना सेवाओं की सूची देती है; MCP वाले पहलू के बारे में हर एक से अलग से पूछना फ़ायदेमंद है।
अपने टूल सर्वर के लिए एक चेकलिस्ट
- रिक्वेस्ट के बीच कोई स्टेट नहीं रहता; बाद के कॉल को जो चाहिए वह सर्वर की लौटाई एक आईडी है।
- हर रिक्वेस्ट का वर्ज़न
MCP-Protocol-Versionहेडर से मिलाया जाता है, और जिस वर्ज़न को आप सपोर्ट नहीं करते उसके लिएUnsupportedProtocolVersionErrorलौटता है। Mcp-MethodऔरMcp-Nameको बॉडी से मिलाया जाता है।server/discoverवर्ज़न, क्षमताओं और पहचान के साथ जवाब देता है।- नतीजों में
resultTypeहोता है; लिस्ट और रीड नतीजों मेंttlMsऔरcacheScopeहोते हैं। tools/listहर बार एक ही क्रम लौटाता है।- GET और DELETE को 405 मिलता है; सेशन और इवेंट-आईडी हेडर अनदेखे किए जाते हैं।
- फ़ाइलें Roots के ज़रिए नहीं, बल्कि कॉन्फ़िगर की गई बाड़ के अंदर आर्ग्युमेंट के रूप में आती हैं।
- लॉग क्लाइंट को नहीं, stderr या OpenTelemetry में जाते हैं।
पूरा पाठ modelcontextprotocol.io पर है, और रिलीज़ पोस्ट पृष्ठभूमि बताती है। हमारे सर्वर के बारे में और जानकारी पासपोर्ट OCR MCP सर्वर पेज पर है।
आपसे एक सवाल: क्या आपका MCP सर्वर सेशन में कुछ ऐसा रखता था जिसे अब आपको हैंडल में बदलना है? नीचे कमेंट में हमें बताएँ।