- होम
- Documentation
- MCP
- MCP प्रोटोकॉल और ट्रांसपोर्ट आंतरिक संरचना
MCP प्रोटोकॉल और ट्रांसपोर्ट आंतरिक संरचना
यह दस्तावेज़ वर्णन करता है कि coding-agent MCP JSON-RPC मैसेजिंग को कैसे कार्यान्वित करता है और प्रोटोकॉल संबंधी चिंताओं को ट्रांसपोर्ट संबंधी चिंताओं से कैसे अलग किया जाता है।
इसमें शामिल है:
- JSON-RPC अनुरोध/प्रतिक्रिया और अधिसूचना प्रवाह
- stdio और HTTP/SSE ट्रांसपोर्ट के लिए अनुरोध सहसंबंध और जीवनचक्र
- टाइमआउट और रद्दीकरण व्यवहार
- त्रुटि प्रसारण और विकृत पेलोड हैंडलिंग
- ट्रांसपोर्ट चयन सीमाएं (
stdioबनामhttp/sse) - कौन सी पुनर्कनेक्ट/पुनर्प्रयास जिम्मेदारियां ट्रांसपोर्ट-स्तरीय हैं बनाम मैनेजर-स्तरीय
इसमें एक्सटेंशन ऑथरिंग UX या कमांड UI शामिल नहीं है।
कार्यान्वयन फ़ाइलें
Section titled “कार्यान्वयन फ़ाइलें”src/mcp/types.tssrc/mcp/transports/stdio.tssrc/mcp/transports/http.tssrc/mcp/transports/index.tssrc/mcp/json-rpc.tssrc/mcp/client.tssrc/mcp/manager.ts
परत सीमाएं
Section titled “परत सीमाएं”प्रोटोकॉल परत (JSON-RPC + MCP विधियाँ)
Section titled “प्रोटोकॉल परत (JSON-RPC + MCP विधियाँ)”- संदेश आकार
types.tsमें परिभाषित हैं (JsonRpcRequest,JsonRpcNotification,JsonRpcResponse,JsonRpcMessage)। - MCP क्लाइंट लॉजिक (
client.ts) विधि क्रम और सत्र हैंडशेक निर्धारित करता है:initializeअनुरोधnotifications/initializedअधिसूचनाtools/list,tools/callजैसी विधि कॉल
ट्रांसपोर्ट परत (MCPTransport)
Section titled “ट्रांसपोर्ट परत (MCPTransport)”MCPTransport डिलीवरी और जीवनचक्र को अमूर्त करता है:
request(method, params, options?) -> Promise<T>notify(method, params?) -> Promise<void>close()connected- वैकल्पिक कॉलबैक:
onClose,onError,onNotification
ट्रांसपोर्ट कार्यान्वयन फ्रेमिंग और I/O विवरणों के स्वामी हैं:
StdioTransport: सबप्रोसेस stdio पर न्यूलाइन-सीमांकित JSONHttpTransport: HTTP POST पर JSON-RPC, वैकल्पिक SSE प्रतिक्रियाओं/श्रवण के साथ
महत्वपूर्ण वर्तमान चेतावनी
Section titled “महत्वपूर्ण वर्तमान चेतावनी”ट्रांसपोर्ट कॉलबैक (onClose, onError, onNotification) कार्यान्वित हैं, लेकिन वर्तमान MCPClient/MCPManager प्रवाह इन कॉलबैक में पुनर्कनेक्शन लॉजिक को जोड़ते नहीं हैं। अधिसूचनाएं केवल तभी उपभोग की जाती हैं जब कॉलर हैंडलर पंजीकृत करता है।
ट्रांसपोर्ट चयन
Section titled “ट्रांसपोर्ट चयन”client.ts:createTransport() कॉन्फ़िगरेशन से ट्रांसपोर्ट चुनता है:
typeछोड़ दिया गया या"stdio"->createStdioTransport"http"या"sse"->createHttpTransport
"sse" को HTTP ट्रांसपोर्ट वेरिएंट (समान क्लास) के रूप में माना जाता है, एक अलग ट्रांसपोर्ट कार्यान्वयन के रूप में नहीं।
JSON-RPC संदेश प्रवाह और सहसंबंध
Section titled “JSON-RPC संदेश प्रवाह और सहसंबंध”अनुरोध ID
Section titled “अनुरोध ID”प्रत्येक ट्रांसपोर्ट प्रति-अनुरोध ID उत्पन्न करता है (Math.random + टाइमस्टैम्प स्ट्रिंग)। ID ट्रांसपोर्ट-स्थानीय सहसंबंध टोकन हैं।
Stdio सहसंबंध पथ
Section titled “Stdio सहसंबंध पथ”- आउटबाउंड अनुरोध एक JSON ऑब्जेक्ट +
\nके रूप में क्रमबद्ध किया जाता है। #pendingRequests: Map<id, {resolve,reject}>इन-फ्लाइट अनुरोधों को संग्रहीत करता है।- रीड लूप stdout से JSONL पार्स करता है और
#handleMessageको कॉल करता है। - यदि इनबाउंड संदेश में मेल खाता
idहै, तो अनुरोध resolve/reject होता है। - यदि इनबाउंड संदेश में
methodहै और कोईidनहीं है, तो इसे अधिसूचना के रूप में माना जाता है औरonNotificationको भेजा जाता है।
अज्ञात ID को अनदेखा किया जाता है (कोई rejection नहीं, कोई error कॉलबैक नहीं)।
HTTP सहसंबंध पथ
Section titled “HTTP सहसंबंध पथ”- आउटबाउंड अनुरोध JSON बॉडी और उत्पन्न
idके साथ HTTPPOSTहै। - गैर-SSE प्रतिक्रिया पथ: एक JSON-RPC प्रतिक्रिया पार्स करता है और
resultलौटाता है /errorपर throw करता है। - SSE प्रतिक्रिया पथ (
Content-Type: text/event-stream): इवेंट स्ट्रीम करता है, पहले संदेश को लौटाता है जिसकाidअपेक्षित अनुरोध ID से मेल खाता है और जिसमेंresultयाerrorहै। methodवाले और बिनाidवाले SSE संदेशों को अधिसूचना के रूप में माना जाता है।
यदि SSE स्ट्रीम मेल खाती प्रतिक्रिया से पहले समाप्त हो जाती है, तो अनुरोध No response received for request ID ... के साथ विफल होता है।
अधिसूचनाएं
Section titled “अधिसूचनाएं”क्लाइंट transport.notify(...) के माध्यम से JSON-RPC अधिसूचनाएं उत्सर्जित करता है।
- Stdio: stdin में अधिसूचना फ्रेम (
jsonrpc,method, वैकल्पिकparams) प्लस न्यूलाइन लिखता है। - HTTP: बिना
idके POST बॉडी भेजता है; सफलता2xxया202 Acceptedस्वीकार करती है।
सर्वर-आरंभित अधिसूचनाएं केवल ट्रांसपोर्ट onNotification के माध्यम से प्रदर्शित की जाती हैं; मैनेजर/क्लाइंट में कोई डिफ़ॉल्ट वैश्विक सब्सक्राइबर नहीं है।
Stdio ट्रांसपोर्ट आंतरिक संरचना
Section titled “Stdio ट्रांसपोर्ट आंतरिक संरचना”जीवनचक्र और स्थिति संक्रमण
Section titled “जीवनचक्र और स्थिति संक्रमण”- प्रारंभिक:
connected=false,process=null, pending map खाली connect():- कॉन्फ़िगर किए गए command/args/env/cwd के साथ सबप्रोसेस spawn करें
- connected चिह्नित करें
- stdout रीड लूप शुरू करें (
readJsonl) - stderr लूप शुरू करें (read/discard; वर्तमान में मूक)
close():- disconnected चिह्नित करें
- सभी pending अनुरोधों को reject करें (
Transport closed) - सबप्रोसेस kill करें
- रीड लूप शटडाउन की प्रतीक्षा करें
onCloseउत्सर्जित करें
यदि रीड लूप अप्रत्याशित रूप से बाहर निकलता है, तो finally #handleClose() को ट्रिगर करता है जो समान pending-request rejection और close कॉलबैक करता है।
टाइमआउट और रद्दीकरण
Section titled “टाइमआउट और रद्दीकरण”प्रति अनुरोध:
- टाइमआउट डिफ़ॉल्ट
config.timeout ?? 30000है - कॉलर से वैकल्पिक
AbortSignal - abort और timeout दोनों pending promise को reject करते हैं और map entry साफ़ करते हैं
रद्दीकरण केवल स्थानीय है: ट्रांसपोर्ट सर्वर को प्रोटोकॉल-स्तरीय रद्दीकरण अधिसूचना नहीं भेजता।
विकृत पेलोड हैंडलिंग
Section titled “विकृत पेलोड हैंडलिंग”रीड लूप में:
- प्रत्येक पार्स की गई JSONL लाइन
try/catchमें#handleMessageको पास की जाती है - विकृत/अमान्य संदेश हैंडलिंग अपवाद छोड़ दिए जाते हैं (
Skip malformed linesटिप्पणी) - लूप जारी रहता है, इसलिए एक खराब संदेश कनेक्शन को समाप्त नहीं करता
यदि अंतर्निहित स्ट्रीम पार्सर throw करता है, तो onError invoked होता है (जब अभी भी connected हो), फिर कनेक्शन बंद हो जाता है।
डिस्कनेक्ट/विफलता व्यवहार
Section titled “डिस्कनेक्ट/विफलता व्यवहार”जब प्रक्रिया बाहर निकलती है या स्ट्रीम बंद होती है:
- सभी इन-फ्लाइट अनुरोध
Transport closedके साथ reject होते हैं - कोई स्वचालित पुनरारंभ या पुनर्कनेक्ट नहीं
- उच्च परतों को एक नया ट्रांसपोर्ट बनाकर पुनर्कनेक्ट करना होगा
बैकप्रेशर/स्ट्रीमिंग नोट्स
Section titled “बैकप्रेशर/स्ट्रीमिंग नोट्स”- आउटबाउंड राइट drain सेमांटिक्स की प्रतीक्षा किए बिना
stdin.write()+flush()का उपयोग करते हैं। - ट्रांसपोर्ट में कोई स्पष्ट कतार या high-watermark प्रबंधन नहीं है।
- इनबाउंड प्रोसेसिंग स्ट्रीम-संचालित है (
readJsonlपरfor await), एक समय में एक पार्स किया गया संदेश।
HTTP/SSE ट्रांसपोर्ट आंतरिक संरचना
Section titled “HTTP/SSE ट्रांसपोर्ट आंतरिक संरचना”जीवनचक्र और कनेक्शन सेमांटिक्स
Section titled “जीवनचक्र और कनेक्शन सेमांटिक्स”HTTP ट्रांसपोर्ट में तार्किक कनेक्शन स्थिति है, लेकिन अनुरोध पथ प्रति HTTP कॉल स्टेटलेस है:
connect()connected=trueसेट करता है (कोई सॉकेट/सत्र हैंडशेक नहीं)Mcp-Session-Idहेडर के माध्यम से वैकल्पिक सर्वर सत्र ट्रैकिंगclose()वैकल्पिक रूप सेMcp-Session-Idके साथDELETEभेजता है, SSE लिसनर को abort करता है,onCloseउत्सर्जित करता है
इसलिए connected का अर्थ है “ट्रांसपोर्ट उपयोग योग्य है”, न कि “स्थायी स्ट्रीम स्थापित है”।
सत्र हेडर व्यवहार
Section titled “सत्र हेडर व्यवहार”- POST प्रतिक्रिया पर, यदि
Mcp-Session-Idहेडर उपस्थित है, तो ट्रांसपोर्ट इसे संग्रहीत करता है। - बाद के अनुरोध/अधिसूचनाएं
Mcp-Session-Idशामिल करती हैं। close()HTTP DELETE के साथ सर्वर सत्र समाप्त करने का प्रयास करता है; समाप्ति विफलताओं को अनदेखा किया जाता है।
टाइमआउट और रद्दीकरण
Section titled “टाइमआउट और रद्दीकरण”request() और notify() दोनों के लिए:
- टाइमआउट
AbortController(config.timeout ?? 30000) का उपयोग करता है - बाहरी सिग्नल, यदि प्रदान किया गया हो,
AbortSignal.any([...])के माध्यम से मर्ज किया जाता है - AbortError हैंडलिंग कॉलर abort बनाम timeout को अलग करती है
फेंकी गई त्रुटियां:
- टाइमआउट:
Request timeout after ...ms(याSSE response timeout ...,Notify timeout ...) - कॉलर abort: जब बाहरी सिग्नल पहले से abort हो तो मूल AbortError पुनः फेंका जाता है
HTTP त्रुटि प्रसारण
Section titled “HTTP त्रुटि प्रसारण”गैर-OK प्रतिक्रिया पर:
- प्रतिक्रिया टेक्स्ट फेंकी गई त्रुटि में शामिल है (
HTTP <status>: <text>) - यदि उपस्थित हो,
WWW-AuthenticateऔरMcp-Auth-Serverसे auth संकेत जोड़े जाते हैं
JSON-RPC error ऑब्जेक्ट पर:
MCP error <code>: <message>throw करता है
विकृत JSON बॉडी (response.json() विफलता) parse अपवाद के रूप में प्रसारित होती है।
SSE व्यवहार और मोड
Section titled “SSE व्यवहार और मोड”दो SSE पथ मौजूद हैं:
-
प्रति-अनुरोध SSE प्रतिक्रिया (
#parseSSEResponse)- जब POST प्रतिक्रिया content type
text/event-streamहो तब उपयोग किया जाता है - मेल खाते response id मिलने तक स्ट्रीम का उपभोग करता है
- समान स्ट्रीम के दौरान इंटरलीव्ड अधिसूचनाओं को संसाधित कर सकता है
- जब POST प्रतिक्रिया content type
-
पृष्ठभूमि SSE लिसनर (
startSSEListener())- सर्वर-आरंभित अधिसूचनाओं के लिए वैकल्पिक GET लिसनर
- वर्तमान में MCP मैनेजर/क्लाइंट द्वारा स्वचालित रूप से शुरू नहीं किया जाता
- यदि GET
405लौटाता है, तो लिसनर चुपचाप स्वयं को अक्षम कर देता है (सर्वर इस मोड का समर्थन नहीं करता)
विकृत पेलोड और डिस्कनेक्ट हैंडलिंग
Section titled “विकृत पेलोड और डिस्कनेक्ट हैंडलिंग”SSE JSON पार्सिंग त्रुटियां readSseJson से बाहर निकलती हैं और अनुरोध/लिसनर को reject करती हैं।
- अनुरोध SSE पार्स त्रुटियां सक्रिय अनुरोध को reject करती हैं।
- पृष्ठभूमि लिसनर त्रुटियां
onErrorट्रिगर करती हैं (AbortError को छोड़कर)। - पृष्ठभूमि लिसनर के लिए कोई ऑटो-रिकनेक्ट नहीं।
json-rpc.ts उपयोगिता बनाम ट्रांसपोर्ट अमूर्तता
Section titled “json-rpc.ts उपयोगिता बनाम ट्रांसपोर्ट अमूर्तता”src/mcp/json-rpc.ts प्रत्यक्ष HTTP MCP कॉल के लिए callMCP() और parseSSE() हेल्पर प्रदान करता है (Exa एकीकरण द्वारा उपयोग किया जाता है), MCPClient/MCPManager द्वारा उपयोग की जाने वाली MCPTransport अमूर्तता नहीं।
HttpTransport से उल्लेखनीय अंतर:
- पहले संपूर्ण प्रतिक्रिया टेक्स्ट पार्स करता है, फिर पहली
data:लाइन निकालता है (parseSSE), JSON फ़ॉलबैक के साथ - कोई अनुरोध टाइमआउट प्रबंधन नहीं, कोई abort API नहीं, कोई session-id हैंडलिंग नहीं, कोई ट्रांसपोर्ट जीवनचक्र नहीं
- कच्चा JSON-RPC envelope ऑब्जेक्ट लौटाता है
यह पथ हल्का है लेकिन पूर्ण ट्रांसपोर्ट कार्यान्वयन से कम मजबूत है।
पुनर्प्रयास/पुनर्कनेक्ट जिम्मेदारियां
Section titled “पुनर्प्रयास/पुनर्कनेक्ट जिम्मेदारियां”ट्रांसपोर्ट-स्तरीय
Section titled “ट्रांसपोर्ट-स्तरीय”वर्तमान ट्रांसपोर्ट कार्यान्वयन निम्नलिखित नहीं करते:
- विफल अनुरोधों का पुनर्प्रयास
- stdio प्रक्रिया बाहर निकलने के बाद पुनर्कनेक्ट
- SSE लिसनर को पुनर्कनेक्ट
- डिस्कनेक्ट के बाद इन-फ्लाइट अनुरोध पुनः भेजना
वे तेजी से विफल होते हैं और त्रुटियां प्रसारित करते हैं।
मैनेजर/क्लाइंट-स्तरीय
Section titled “मैनेजर/क्लाइंट-स्तरीय”MCPManager खोज/प्रारंभिक कनेक्शन ऑर्केस्ट्रेशन को संभालता है और केवल कनेक्ट प्रवाह (connectToServer/discoverAndConnect पथ) फिर से चलाकर पुनर्कनेक्ट कर सकता है। यह रनटाइम विफलता कॉलबैक पर पहले से जुड़े ट्रांसपोर्ट को ऑटो-हील नहीं करता।
MCPManager में धीमे सर्वरों के लिए स्टार्टअप फ़ॉलबैक व्यवहार है (कैश से स्थगित उपकरण), लेकिन यह उपकरण उपलब्धता फ़ॉलबैक है, ट्रांसपोर्ट पुनर्प्रयास नहीं।
विफलता परिदृश्य सारांश
Section titled “विफलता परिदृश्य सारांश”- विकृत stdio संदेश लाइन: छोड़ दी गई; स्ट्रीम जारी रहती है।
- Stdio स्ट्रीम/प्रक्रिया समाप्त: ट्रांसपोर्ट बंद; pending अनुरोध
Transport closedके रूप में reject। - HTTP गैर-2xx: अनुरोध/notify HTTP त्रुटि throw करता है।
- अमान्य JSON प्रतिक्रिया: parse अपवाद प्रसारित।
- SSE मेल खाते id के बिना समाप्त: अनुरोध
No response received for request ID ...के साथ विफल। - टाइमआउट: ट्रांसपोर्ट-विशिष्ट टाइमआउट त्रुटि।
- कॉलर abort: कॉलर सिग्नल से AbortError/कारण प्रसारित।
व्यावहारिक सीमा नियम
Section titled “व्यावहारिक सीमा नियम”यदि चिंता संदेश आकार, id सहसंबंध, या MCP विधि क्रम से संबंधित है, तो यह प्रोटोकॉल/क्लाइंट लॉजिक में आती है।
यदि चिंता फ्रेमिंग (JSONL बनाम HTTP/SSE), स्ट्रीम पार्सिंग, fetch/spawn जीवनचक्र, टाइमआउट क्लॉक, या कनेक्शन टियरडाउन से संबंधित है, तो यह ट्रांसपोर्ट कार्यान्वयन में आती है।