Stateless MCP servers میں اصل تبدیلی کیا ہے؟
MCP revision 2026-07-28 نے sessions اور initialize handshake ختم کر دیے۔ جانیں اس کا reverse proxy، health checks، timeouts اور auth پر کیا اثر ہے۔
ایک stateless MCP server کیا ہوتا ہے
stateless MCP server درخواستوں کے درمیان فی کلائنٹ state محفوظ نہیں رکھتا۔ ہر درخواست میں protocol version، client capabilities اور وہ credentials شامل ہوتے ہیں جن کی server کو جواب دینے کے لیے ضرورت ہوتی ہے، اس لیے کسی بھی machine پر چلنے والا کوئی بھی process کسی بھی درخواست کا جواب دے سکتا ہے۔ MCP (Model Context Protocol، وہ wire format جسے agents tools تک پہنچنے کے لیے استعمال کرتے ہیں) نے revision 2026-07-28 میں اسے ایک اصول بنایا۔ اس revision میں initialize handshake اور اس کے نیچے موجود HTTP session ختم کر دیا گیا۔
یہی اس کا مکمل عملی مقصد ہے۔ جو server فی کلائنٹ کچھ محفوظ نہیں رکھتا، اسے session affinity کے بغیر عام load balancer کے پیچھے چلایا جا سکتا ہے۔ deploy کے دوران اسے restart کرنے سے clients متاثر نہیں ہوتے۔ اسے ایک process کے بجائے چار یکساں processes کے طور پر بھی چلایا جا سکتا ہے۔ session-oriented server اضافی نظام کے بغیر یہ کام نہیں کر سکتا۔
Model Context Protocol ایک stateless protocol ہے: درخواست کو process کرنے کے لیے درکار تمام معلومات خود درخواست میں موجود ہوتی ہیں۔ server ہر درخواست کو آزادانہ طور پر process کرتا ہے؛ پچھلی درخواستوں سے کوئی state اخذ نہیں کی جانی چاہیے، چاہے وہ اسی connection یا stream پر بھیجی گئی ہوں۔
stateless کا مطلب یہ نہیں کہ آپ کا server کچھ بھی محفوظ نہیں کرتا۔ آپ کا database، queue اور cache بدستور موجود رہتے ہیں۔ اس کا مطلب یہ ہے کہ connection پر protocol کوئی state منتقل نہیں کرتا، اس لیے server کو کسی connection، process یا کھلے socket کو "یہ client، گفتگو کے دوران" کا متبادل نہیں سمجھنا چاہیے۔
2026-07-28 کی نظرثانی میں کیا ہٹایا گیا
2026-07-28 اگست 2026 تک specification کی موجودہ نظرثانی ہے۔ 2025-11-25 کے مقابلے میں اس میں وہ پانچ چیزیں ہٹا دی گئی ہیں جو sessions کے لیے موجود تھیں۔
initializerequest اورnotifications/initializednotification۔ اب کوئی handshake نہیں ہوتا (SEP-2575)۔Mcp-Session-Idheader، اور HTTPDELETEکے ذریعے session termination (SEP-2567)۔- standalone HTTP
GETstream، جس پر servers notifications push کرتے تھے۔ اس کی جگہsubscriptions/listenنے لے لی ہے، جو ایک عام POST ہے اور اس کا response طویل مدتی stream ہوتا ہے۔ - SSE (server-sent events) stream کی resumability۔
Last-Event-IDheader اور ہر event کی IDs ختم کر دی گئی ہیں، اس لیے stream ٹوٹنے پر زیرِ عمل request ضائع ہو جاتی ہے۔ Client کو اسے نئی request ID کے ساتھ نئی request کے طور پر دوبارہ بھیجنا ہوگا۔ ping،logging/setLevelاورnotifications/roots/list_changed۔ اب log level ہر request کا field ہے،io.modelcontextprotocol/logLevelمیں_meta۔
ایک method شامل کیا گیا ہے، اور ہر server کے لیے اسے implement کرنا لازمی ہے۔ server/discover ایک ہی call میں server کے supported protocol versions، capabilities اور identity واپس کرتا ہے۔ یہ باقی رہ جانے والی handshake سے سب سے زیادہ مشابہ چیز ہے، اور clients کے لیے اسے call کرنا اختیاری ہے۔
پروڈکشن میں session transport چلانا مشکل کیوں تھا
2025-11-25 اور اس سے پہلے، server initialization کے وقت session ID بنا سکتا تھا اور اسے Mcp-Session-Id header میں InitializeResult پر واپس بھیج سکتا تھا۔ اس کے بعد client کو ہر آئندہ request کے ساتھ وہ header بھیجنا پڑتا تھا۔ negotiated protocol version اور client کی capabilities server کی memory میں اسی ID کے ذریعے محفوظ رہتی تھیں۔ ان میں سے ہر انتخاب کی انتظامی لاگت تھی۔
- restart سے session table ختم ہو جاتا تھا۔ specification کے مطابق server کو dead session ID رکھنے والی ہر request کا جواب
404 Not Foundکے ساتھ دینا ہوتا تھا، اور client کو نئےInitializeRequestکے ساتھ دوبارہ آغاز کرنا پڑتا تھا۔ ہر deploy تمام connected clients کے لیے reconnect event بن جاتا تھا۔ - دوسرے replica کو پہلے replica کے sessions کا علم نہیں ہوتا تھا۔ scale out کرنے کے لیے load balancer پر sticky routing درکار ہوتی تھی، یا shared session store استعمال کرنا پڑتا تھا جسے ہر replica ہر request پر پڑھتا تھا۔
- session table ایسی memory استعمال کرتی تھی جو idle clients کی تعداد کے ساتھ بڑھتی جاتی تھی۔
DELETEoptional تھا، اور جو clients اسے بھیجے بغیر بند ہو جاتے تھے، وہ entries باقی چھوڑ دیتے تھے۔ - list results ہر connection کے لحاظ سے مختلف ہو سکتے تھے، اس لیے server کے سامنے caching محفوظ نہیں تھی۔
sessions ختم کرنے سے یہ چاروں مسائل ایک ساتھ ختم ہو جاتے ہیں۔ کسی بھی configuration کو تبدیل کرنے سے پہلے اس تبدیلی کو سمجھنا ضروری ہے۔
اب ہر درخواست کے ساتھ کیا شامل ہوتا ہے
MCP endpoint کو بھیجی جانے والی ہر POST درخواست الگ ہوتی ہے۔ پروٹوکول ورژن اور client کی capabilities درخواست کے body میں _meta کے تحت شامل ہوتی ہیں، جبکہ منتخب fields HTTP headers میں بھی درج کی جاتی ہیں تاکہ کوئی intermediary JSON parse کیے بغیر ان کی بنیاد پر routing کر سکے۔
POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
Authorization: Bearer <access token>
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {"location": "Seattle, WA"},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {"name": "ExampleClient", "version": "1.0.0"},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}ہر درخواست میں io.modelcontextprotocol/protocolVersion اور io.modelcontextprotocol/clientCapabilities لازمی ہیں۔ clientInfo لازمی نہیں ہے، تاہم clients کو اسے بھیجنا چاہیے۔ اگر کسی درخواست میں لازمی field موجود نہ ہو تو وہ malformed ہوتی ہے۔ اس لیے server کو اسے JSON-RPC error -32602 اور HTTP 400 Bad Request کے ساتھ مسترد کرنا چاہیے۔
Mcp-Method header ہر درخواست میں لازمی ہے۔ Mcp-Name، tools/call، resources/read اور prompts/get پر لازمی ہے۔ Header کی value body کی value سے مطابقت رکھنی چاہیے۔ اگر server body کو process کرتا ہے اور دونوں values مختلف ہوں تو اسے درخواست کو 400 Bad Request اور error code -32020، HeaderMismatch کے ساتھ مسترد کرنا چاہیے۔ اس اصول کی وجہ یہ ہے کہ header کی بنیاد پر routing کرنے والا load balancer اور body کی بنیاد پر کارروائی کرنے والا server، سچائی کے دو مختلف ذرائع استعمال کر رہے ہوتے ہیں۔ اگر آپ ان headers کی بنیاد پر routing یا rate limiting کرتے ہیں تو پہلے MCP-Protocol-Version کی جانچ کریں۔ پہلے کے revisions میں header اور body کی values کی باہمی توثیق نہیں کی جاتی تھی، اس لیے ان versions میں header کی value قابلِ اعتماد نہیں ہے۔
اب version کا اختلاف handshake failure کے بجائے ہر درخواست کی معمول کی error ہے۔ اگر server مطلوبہ version کو implement نہیں کرتا تو وہ 400 Bad Request کا جواب -32022، UnsupportedProtocolVersion کے ساتھ دیتا ہے، اور data.supported میں اپنے supported versions کی فہرست شامل کرتا ہے۔ Client اس فہرست میں سے ایک version منتخب کرکے دوبارہ درخواست بھیجتا ہے۔
جہاں state منتقل ہوئی: tokens، cursors، subscriptions
State غائب نہیں ہوئی۔ یہ ان مقامات پر منتقل ہوئی جنہیں آپ دیکھ اور log کر سکتے ہیں۔
Credentials ہر request میں شامل ہوتی ہیں۔ کسی identity کو منسلک کرنے کے لیے کوئی session موجود نہیں ہوتا، اس لیے access token ہر HTTP call کے ساتھ بھیجا جاتا ہے اور ہر مرتبہ validate کیا جاتا ہے۔ تفصیلات ذیل کے authentication section میں موجود ہیں۔
Cursors کو اپنی position ساتھ رکھنی ہوتی ہے۔ tools/list، resources/list، prompts/list اور resources/templates/list پر pagination ایک opaque cursor string استعمال کرتی ہے، اور clients کو اسے parse یا modify نہیں کرنا چاہیے۔ Single-process server پر offset کو session کے مطابق memory میں رکھنا عام تھا۔ Session نہ ہونے کی صورت میں cursor میں اتنی معلومات ہونی چاہیے کہ کوئی بھی replica listing کو دوبارہ جاری رکھ سکے؛ اس کے لیے position کو cursor کے اندر encode کرکے اسے sign کریں، یا اسے ایسی storage میں رکھیں جو تمام replicas کے لیے مشترک ہو۔ Invalid cursor پر -32602 واپس آنا چاہیے۔ اسے sign کریں، کیونکہ opaque cursor بھی client کی فراہم کردہ input ہے جسے آپ کا code decode اور trust کرتا ہے۔
Subscriptions کسی connection کے بجائے request سے وابستہ ہوتی ہیں۔ Change notifications چاہنے والا client subscriptions/listen بھیجتا ہے، جس میں مطلوبہ types کا نام دینے والا filter شامل ہوتا ہے: toolsListChanged، promptsListChanged، resourcesListChanged اور resourceSubscriptions۔ Server notifications/subscriptions/acknowledged کے ساتھ جواب دیتا ہے اور اس response stream کو کھلا رکھتا ہے۔ اگر stream منقطع ہو جائے تو server کچھ محفوظ نہیں رکھتا، اور client اسے دوبارہ حاصل کرنے کے لیے subscriptions/listen دوبارہ بھیجتا ہے۔
Cross-call application state ایک واضح handle بن جاتی ہے۔ جب server کو واقعی calls کے درمیان کوئی چیز یاد رکھنی ہو تو specification کا حل یہ ہے کہ server کی جانب سے بنایا گیا identifier عام tool argument کے طور پر واپس بھیجا جائے۔ یہ tool schema میں ظاہر ہوتا ہے، log کیا جا سکتا ہے، اور connection سے کبھی implied نہیں ہوتا۔ حقیقی per-user data رکھنے والا server، جیسے self-hosted MCP email server، session کے بجائے یہی طریقہ استعمال کرتا ہے: mailbox یا draft identifier ایک tool argument ہوتا ہے، اس لیے کوئی بھی replica اگلی call سنبھال سکتی ہے۔ بہت سے tools کو کسی handle کی ضرورت ہی نہیں ہوتی: آپ کی اپنی SearXNG instance کے ذریعے چلنے والا search tool query لیتا ہے اور results واپس کرتا ہے؛ اگلی call جاری رکھنے کے لیے کچھ محفوظ نہیں کرنا پڑتا، اور اس بات کی کوئی اہمیت نہیں ہوتی کہ جواب کس replica نے دیا۔
تعیناتی: reverse proxy، timeouts، health checks
MCP endpoint ایک ایسا path ہے جو POST قبول کرتا ہے۔ زیادہ تر traffic مختصر request اور JSON response پر مشتمل ہوتا ہے، جسے کوئی بھی proxy handle کر لیتا ہے۔ استثنا streaming response ہے، جہاں proxy کے default settings آپ کے خلاف کام کرتے ہیں۔ یہی وہ حصہ ہے جو laptop demo سے VPS پر چلنے والے MCP server کی طرف منتقل ہوتے وقت تبدیل ہوتا ہے۔
location /mcp {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_read_timeout 1h;
proxy_send_timeout 1h;
}proxy_buffering off اس لیے اہم ہے کہ nginx default طور پر proxied responses کو buffer کرتا ہے۔ اس کے نتیجے میں SSE events اس وقت تک رکے رہتے ہیں جب تک buffer بھر نہ جائے یا response ختم نہ ہو جائے۔ Specification سرورز سے SSE responses پر X-Accel-Buffering: no بھیجنے کا تقاضا کرتی ہے، اور nginx اس header کی پابندی کرتا ہے۔ اس لیے درست server خود proxy کو درست ہدایت دے دیتا ہے۔ پھر بھی directive set کریں، کیونکہ یہ وہ حصہ ہے جس پر آپ کا اختیار ہے۔
proxy_read_timeout کی default قدر 60 seconds ہے۔ اگر subscriptions/listen stream اس سے زیادہ دیر تک خاموش رہے تو اسے آپ کا server نہیں بلکہ nginx بند کرتا ہے۔ اس صورت میں logs میں process صحت مند دکھائی دیتا ہے، جبکہ client dropped stream دکھاتا ہے۔ اسے صرف MCP location پر بڑھائیں، پورے server پر نہیں۔ سرورز کو یہ بھی تجویز کیا جاتا ہے کہ خاموش اوقات میں keep-alive کے لیے SSE comment line بھیجیں، یعنی ایسی line جو colon سے شروع ہو۔ اس سے intermediaries stream کو timeout نہیں کرتے۔
Caddy کے لیے کم configuration درکار ہوتی ہے۔ یہ default طور پر wire efficiency کے لیے جزوی buffering کرتا ہے اور جب response میں Content-Type: text/event-stream موجود ہو تو فوراً flush کر دیتا ہے۔ اس لیے streaming اضافی directives کے بغیر کام کرتی ہے۔
mcp.example.com {
reverse_proxy 127.0.0.1:8080 {
health_uri /healthz
health_interval 10s
}
}توجہ دیں کہ health check کس endpoint کو target کرتا ہے۔ MCP endpoint پر GET کے ساتھ active check نہ چلائیں، کیونکہ صرف اس revision کو implement کرنے والا server 405 Method Not Allowed اور GET کے جواب میں DELETE دیتا ہے، جبکہ Caddy کا default health method GET ہے۔ اس کے نتیجے میں proxy ایک مکمل طور پر صحت مند backend کو down قرار دے گا۔ Proxy کے لیے /healthz جیسا سادہ path فراہم کریں، اور protocol کو POST کے ذریعے الگ check کریں۔
curl -sS https://mcp.example.com/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: server/discover' \
-d '{"jsonrpc":"2.0","id":"health-1","method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'200 جس میں supportedVersions list ہو، اس کا مطلب ہے کہ process چل رہا ہے اور protocol کے مطابق جواب دے رہا ہے۔ JSON-RPC error -32601 والا 404 بتاتا ہے کہ process چل رہا ہے، لیکن server/discover فراہم نہیں کرتا، جسے ہر 2026-07-28 server کے لیے implement کرنا ضروری ہے۔ -32022 کے ساتھ 400 کا مطلب ہے کہ checker نے ایسا version طلب کیا ہے جسے یہ build support نہیں کرتا۔ Dependency upgrade کے بعد یہی وہ خرابی ہے جسے آپ پکڑنا چاہتے ہیں۔ Open source nginx میں active health checks موجود نہیں ہیں۔ اس لیے upstream پر passive max_fails اور fail_timeout استعمال کریں، اور protocol check اپنے monitoring system سے چلائیں۔
اب rolling restart کے دوران صرف زیرِعمل requests متاثر ہوں گی، اس کے علاوہ کچھ نہیں۔ پہلے traffic drain کریں، open POST requests کو مکمل ہونے دیں، نیا process شروع کریں، اور جو requests fail ہوں انہیں clients دوبارہ بھیج دیں۔ اب بھی صرف ایک چیز drop ہوگی: کوئی بھی open subscriptions/listen stream، کیونکہ وہ stream ایک مخصوص process کے ساتھ live connection ہوتی ہے۔ Statelessness نے session affinity ختم کر دی ہے۔ اس نے اس stream کے لیے connection affinity ختم نہیں کی جو اس وقت open ہو۔ کوئی routing rule اسے درست نہیں کر سکتا۔ Client دونوں صورتوں میں فرق معلوم کر سکتا ہے: جو stream خالی subscriptions/listen result کے ساتھ ختم ہو، وہ gracefully بند ہوئی ہے؛ جو اس result کے بغیر ختم ہو، وہ drop ہوئی ہے، اور client اسے reconnect کرنے کی وجہ سمجھ سکتا ہے۔
اب پہلی بار caching ممکن ہو جاتی ہے۔ List methods کے results میں اب ttlMs اور cacheScope شامل ہوتے ہیں، اور cacheScope: "public" shared intermediaries کو بتاتا ہے کہ وہ response cache کر سکتے ہیں۔ یہ صرف اس لیے محفوظ ہے کہ list results اب ہر connection کے لحاظ سے مختلف نہیں رہتے۔ یہ sessions ختم کرنے کا براہِ راست نتیجہ ہے۔
جب کوئی session نہ ہو تو authentication کیوں بدل جاتی ہے
session کے ساتھ یہ طریقہ اختیار کرنا آسان لگتا تھا کہ initialize پر ایک مرتبہ authentication کی جائے اور اس کے بعد session ID کو ہر کارروائی کے لیے ثبوت سمجھا جائے۔ اس طرح استعمال کی جانے والی session ID ایک bearer credential ہوتی ہے، جس کی کوئی audience، expiry یا revocation path نہیں ہوتی اور جسے آپ کا اپنا server جاری کرتا ہے۔ sessions ختم کرنے سے یہ آسان راستہ بھی ختم ہو جاتا ہے، اور اس کا متبادل زیادہ سخت تقاضے رکھتا ہے۔
محفوظ MCP server، OAuth 2.1 resource server کے طور پر کام کرتا ہے۔ client کی ہر HTTP request میں Authorization: Bearer <access token> موجود ہونا چاہیے، اور server ہر request پر token کی توثیق کرتا ہے۔ اس توثیق میں audience بھی شامل ہوتی ہے: RFC 8707 (Resource Indicators for OAuth 2.0) کے مطابق server کو تصدیق کرنی چاہیے کہ token خاص طور پر اسی کے لیے جاری کیا گیا ہے، اور اسے کسی دوسری سروس کے لیے بنائے گئے token کو قبول یا آگے منتقل نہیں کرنا چاہیے۔ clients server کے canonical URI کے ساتھ resource parameter بھیج کر درست audience طلب کرتے ہیں۔
Discovery ایک challenge کی بنیاد پر چلتی ہے۔ جب کوئی request قابلِ استعمال token کے بغیر آتی ہے تو server 401 Unauthorized واپس کرتا ہے۔
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
scope="files:read"client resource_metadata پڑھتا ہے، اس document کو حاصل کرتا ہے (RFC 9728، OAuth 2.0 Protected Resource Metadata، جسے MCP servers کے لیے implement کرنا لازم ہے)، authorization server تلاش کرتا ہے اور flow چلاتا ہے۔ درست token میں permissions ناکافی ہوں تو 403 Forbidden کے ساتھ error="insufficient_scope" اور اس operation کے لیے درکار scopes واپس کیے جاتے ہیں۔
اسے چلانے کے طریقے پر اس کے دو نتائج ہیں۔ اب token validation ہر session کے بجائے ہر request پر ہوتی ہے، اس لیے ہر call کے لیے introspection endpoint تک network round trip latency میں نمایاں ہو گا۔ بہتر ہے کہ ایسے tokens استعمال کریں جن کی signature، audience اور expiry کے خلاف مقامی طور پر توثیق ہو سکے، یا token کی بنیاد پر validation result کو مختصر مدت کے لیے cache کریں۔ مزید یہ کہ چونکہ identity برقرار رکھنے والا کوئی session موجود نہیں ہوتا، اس لیے authorization ہر call پر token سے حاصل کرنا ضروری ہے۔ یہ session model سے زیادہ درست طریقہ ہے، اور اس وسیع تر عمل سے بھی مطابقت رکھتا ہے جس میں credentials کو agent process سے باہر رکھا جاتا ہے۔ اس کی وضاحت AI agent سے secrets کو باہر رکھنا میں کی گئی ہے۔
اس revision کے بارے میں کیا درست ہے، اور کیا درست نہیں
اوپر دی گئی تمام وضاحتیں revision 2026-07-28 سے متعلق ہیں۔ یہ ہمیشہ کے لیے MCP کی وضاحت نہیں کرتیں، اور نہ ہی اس server کی جسے آپ نے گزشتہ سال deploy کیا تھا۔
2025-11-25 اور اس سے پہلے کے clients اور servers اب بھی handshake model استعمال کرتے ہیں۔ specification ان revisions کو legacy کہتی ہے، جبکہ ہر request کے metadata والی revisions کو modern کہتی ہے۔ جو server صرف اسی revision کو support کرتا ہو اور اسے ایک پرانے client کا سامنا ہو، اسے MCP endpoint پر GET یا DELETE کے جواب میں 405 Method Not Allowed دینا چاہیے، Mcp-Session-Id header کو نظرانداز کرنا چاہیے، اس کے لیے کوئی نیا token نہیں بنانا چاہیے اور نہ اسے واپس بھیجنا چاہیے، اور Last-Event-ID کو بھی نظرانداز کرنا چاہیے کیونکہ streams resume نہیں کی جا سکتیں۔ dual-era server ایک ہی endpoint پر دونوں کو serve کر سکتا ہے: modern _meta رکھنے والی request کو stateless طریقے سے serve کیا جاتا ہے، جبکہ initialize request پرانا session semantics منتخب کرتی ہے۔
اس لیے ان تمام باتوں پر اعتماد کرنے سے پہلے revision string چیک کریں۔ اگر آپ کا SDK اب بھی initialize بھیجتا ہے تو آپ کی deployment میں sessions اب بھی حقیقی ہیں، اور اوپر بیان کیے گئے session سے متعلق مسائل اب بھی آپ کو manage کرنے ہوں گے۔ یہی بات client side پر بھی لاگو ہوتی ہے: آپ کے اپنے box پر چلنے والا agent process، مثلاً VPS پر coding agent چلانے کی setup، اس مفہوم میں صرف اسی وقت stateless ہوگا جب اس کی استعمال کردہ library modern revision بولتی ہو۔ اپنے runtime کی negotiated version پڑھیں، پھر specification کی متعلقہ revision پڑھیں، اور اس صفحے کو عمومی protocol کے بجائے ایک مخصوص نام زد revision کی وضاحت سمجھیں۔
FAQ
کیا stateless MCP server کا مطلب ہے کہ میں کچھ بھی محفوظ نہیں کر سکتا؟
نہیں۔ Stateless سے مراد protocol ہے، آپ کی application نہیں۔ Databases، queues اور caches پہلے کی طرح کام کرتے ہیں۔ تبدیلی صرف یہ ہے کہ متعدد calls پر پھیلی ہوئی state کو ایک واضح identifier کے ذریعے refer کرنا ہوگا، جو client ہر request کے ساتھ بھیجے، مثلاً tool argument میں server کا بنایا ہوا handle۔ آپ connection سے context اخذ نہیں کر سکتے۔ Specification کے مطابق server کو capabilities، protocol version یا client identity قائم کرنے کے لیے اسی connection پر کی گئی سابقہ requests پر انحصار نہیں کرنا چاہیے، کیونکہ ہر request یہ معلومات _meta میں فراہم کرتی ہے۔
کیا مجھے اب بھی اپنے load balancer پر sticky sessions درکار ہیں؟
عام requests کے لیے نہیں۔ Revision 2026-07-28 کے تحت ہر POST اپنی protocol version، capabilities اور credentials ساتھ لے کر آتا ہے، اس لیے کوئی بھی replica کسی بھی request کا جواب دے سکتی ہے اور round-robin کافی ہے۔ باقی رہنے والی واحد طویل مدتی چیز subscriptions/listen response stream ہے، جو ایک ہی process کے ساتھ ایک single open connection ہوتی ہے۔ یہ connection اس process کے ختم ہونے پر بند ہو جاتی ہے، اور client اسے دوبارہ قائم کرنے کے لیے subscriptions/listen دوبارہ بھیجتا ہے۔ یہ session affinity نہیں بلکہ connection lifetime ہے، اور کوئی routing rule اسے نہیں روکتی۔
Mcp-Session-Id اور HTTP GET stream کا کیا ہوا؟
Revision 2026-07-28 میں SEP-2567 اور SEP-2575 کے تحت دونوں کو ہٹا دیا گیا۔ صرف اس revision کو implement کرنے والے server کو MCP endpoint پر GET اور DELETE کے جواب میں 405 Method Not Allowed بھیجنا چاہیے، اور Mcp-Session-Id header کو واپس echo کرنے کے بجائے نظرانداز کرنا چاہیے۔ Server-initiated change notifications اب standalone GET stream کے بجائے subscriptions/listen request کے response stream پر بھیجی جاتی ہیں۔ جن servers کو پرانے clients کی خدمت جاری رکھنی ہو، وہ اس revision کے ساتھ سابقہ revision کا behavior بھی implement کرتے ہیں۔
handshake کے بغیر MCP server کا health check کیسے کروں؟
دو سطحیں استعمال کریں۔ Proxy کا active check کسی ایسے plain HTTP path پر بھیجیں جو آپ کی application فراہم کرتی ہو، کیونکہ MCP endpoint کو بھیجا گیا GET درست طور پر 405 واپس کرتا ہے اور healthy backend کو down قرار دے سکتا ہے۔ اس کے بعد protocol کو خود check کریں۔ اس مقصد کے لیے server/discover کو POST کریں، جسے ہر 2026-07-28 server کو implement کرنا لازم ہے، اور تصدیق کریں کہ جواب HTTP 200 ہے اور اس میں وہ protocol version درج ہے جسے آپ کے clients استعمال کرتے ہیں۔ JSON-RPC error -32601 کے ساتھ 404 کا مطلب ہے کہ process چل رہا ہے، لیکن وہ method فراہم نہیں کر رہا۔ -32022 کے ساتھ 400 کا مطلب ہے کہ آپ کی درخواست کردہ version اس build میں supported نہیں ہے۔