SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-13

تغییرات پروتکل MCP در نسخه 2026-07-28 و حذف نشست‌ها

در بازبینی 2026-07-28 پروتکل MCP هندشیک initialize و نشست‌ها حذف شدند. این راهنما تاثیر تغییرات روی لود بالانسر، احراز هویت و مدیریت تایم‌اوت در سرورهای stateless را بررسی می‌کند.

سرور MCP بدون وضعیت (stateless) چیست

یک سرور MCP بدون وضعیت، هیچ‌گونه وضعیتی (state) مختص به کلاینت را بین درخواست‌ها نگهداری نمی‌کند. هر درخواست شامل نسخه پروتکل، قابلیت‌های کلاینت و اعتبارنامه‌هایی است که سرور برای پاسخ‌دهی به آن نیاز دارد؛ بنابراین هر پردازشی روی هر ماشینی می‌تواند به هر درخواستی پاسخ دهد. پروتکل MCP (مخفف Model Context Protocol، فرمت ارتباطی که ایجنت‌ها برای دسترسی به ابزارها استفاده می‌کنند) این موضوع را در بازبینی 2026-07-28 به یک قانون تبدیل کرد که طی آن، هندشیک initialize و نشست HTTP زیرمجموعه آن حذف شدند.

این تمام نکته عملیاتی موضوع است. سروری که هیچ داده‌ای را به ازای هر کلاینت نگه نمی‌دارد، می‌تواند پشت یک لود بالانسر معمولی بدون نیاز به session affinity قرار بگیرد، در حین استقرار (deploy) بدون قطع ارتباط کلاینت‌ها ری‌استارت شود و به جای یک پردازش، به صورت چهار پردازش یکسان اجرا شود. یک سرور مبتنی بر نشست (session-oriented) بدون تجهیزات اضافی، هیچ‌کدام از این کارها را انجام نمی‌دهد.

پروتکل Model Context Protocol یک پروتکل بدون وضعیت است: تمام اطلاعات مورد نیاز برای پردازش یک درخواست، درون خودِ همان درخواست گنجانده شده است. سرور هر درخواست را به‌طور مستقل پردازش می‌کند؛ هیچ وضعیتی نباید از درخواست‌های قبلی استنباط شود، حتی اگر آن درخواست‌ها روی همان اتصال یا استریم باشند.

بدون وضعیت بودن به این معنا نیست که سرور شما هیچ چیزی ذخیره نمی‌کند. دیتابیس، صف و کش شما همچنان سر جای خود هستند. این یعنی پروتکل هیچ وضعیتی را روی اتصال حمل نمی‌کند، بنابراین سرور نباید یک اتصال، یک پردازش یا یک سوکت باز را به عنوان جایگزینی برای مفهوم «این کلاینت، در میانه گفتگو» در نظر بگیرد.

تغییرات نسخه 2026-07-28

2026-07-28 نسخه فعلی مشخصات تا اوت 2026 است. در مقایسه با 2025-11-25، این نسخه پنج موردی را که برای پشتیبانی از نشست‌ها (sessions) وجود داشت، حذف کرده است:

  • درخواست initialize و اعلان notifications/initialized. هیچ‌گونه دست‌دادنی (handshake) وجود ندارد (SEP-2575).
  • هدر Mcp-Session-Id و خاتمه نشست با استفاده از HTTP DELETE (SEP-2567).
  • استریم مستقل HTTP GET که سرورها اعلان‌ها را روی آن ارسال می‌کردند. این مورد با subscriptions/listen جایگزین شده است؛ یک POST معمولی که پاسخ آن یک استریم با عمر طولانی است.
  • قابلیت ازسرگیری استریم SSE (رویدادهای ارسالی از سرور). هدر Last-Event-ID و شناسه‌های هر رویداد حذف شده‌اند، بنابراین در صورت قطع استریم، درخواست در حال اجرا از دست می‌رود و کلاینت باید آن را به عنوان یک درخواست جدید با شناسه درخواست جدید ارسال کند.
  • ping، logging/setLevel و notifications/roots/list_changed. سطح لاگ اکنون یک فیلد در هر درخواست است، io.modelcontextprotocol/logLevel در _meta.

یک متد اضافه شده است که تمام سرورها باید آن را پیاده‌سازی کنند. server/discover نسخه‌های پروتکل پشتیبانی‌شده، قابلیت‌ها و هویت سرور را در یک فراخوانی بازمی‌گرداند. این متد نزدیک‌ترین مورد به دست‌دادن (handshake) است که باقی مانده، و فراخوانی آن برای کلاینت‌ها اختیاری است.

چرا اجرای انتقال نشست (session transport) در محیط عملیاتی دشوار بود

در 2025-11-25 و نسخه‌های پیش از آن، سرور می‌توانست در زمان مقداردهی اولیه، یک session ID ایجاد کرده و آن را در هدر Mcp-Session-Id در پاسخ InitializeResult بازگرداند. سپس کلاینت مجبور بود آن هدر را در تمامی درخواست‌های بعدی ارسال کند. نسخه پروتکل توافق‌شده و قابلیت‌های کلاینت در حافظه سرور و با کلید همان ID ذخیره می‌شدند. هر یک از این انتخاب‌ها هزینه عملیاتی خاص خود را داشت.

  • راه‌اندازی مجدد (restart)، جدول نشست‌ها را پاک می‌کرد. مشخصات فنی ایجاب می‌کرد که سرور به هر درخواستی که حاوی یک session ID نامعتبر بود با 404 Not Found پاسخ دهد و کلاینت را ملزم می‌کرد تا با یک InitializeRequest جدید، فرآیند را از نو آغاز کند. هر استقرار (deploy) به یک رویداد اتصال مجدد برای تمامی کلاینت‌های متصل تبدیل می‌شد.
  • نسخه دوم (replica) از نشست‌های نسخه اول بی‌اطلاع بود. مقیاس‌پذیری (scaling out) مستلزم استفاده از sticky routing در load balancer یا یک حافظه اشتراکی برای نشست‌ها بود که هر replica در هر درخواست آن را می‌خواند.
  • جدول نشست‌ها حافظه‌ای بود که با افزایش تعداد کلاینت‌های غیرفعال (idle)، رشد می‌کرد. DELETE اختیاری بود و کلاینت‌هایی که بدون ارسال آن بسته می‌شدند، ورودی‌های بلااستفاده‌ای را در حافظه باقی می‌گذاشتند.
  • نتایج لیست‌ها می‌توانست در هر اتصال متفاوت باشد، بنابراین کش کردن در مقابل سرور ناامن بود.

حذف نشست‌ها هر چهار مشکل را به‌طور هم‌زمان برطرف می‌کند. این تغییری است که پیش از دست زدن به هرگونه پیکربندی، باید آن را درک کنید.

هر درخواست اکنون چه اطلاعاتی را حمل می‌کند

هر درخواست POST به endpoint مربوط به MCP مستقل است. نسخهٔ پروتکل و قابلیت‌های کلاینت در بدنهٔ درخواست تحت _meta ارسال می‌شوند و فیلدهای منتخب در هدرهای HTTP بازتاب می‌یابند تا واسط‌ها بتوانند بدون نیاز به تجزیه JSON، درخواست را مسیریابی کنند.

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 الزامی نیست، اگرچه کلاینت‌ها باید آن را ارسال کنند. درخواستی که فیلد الزامی نداشته باشد، ناقص (malformed) محسوب می‌شود؛ بنابراین سرور باید آن را با خطای JSON-RPC به شماره -32602 و کد وضعیت HTTP 400 Bad Request رد کند.

هدر Mcp-Method در هر درخواست الزامی است. Mcp-Name در tools/call، resources/read و prompts/get الزامی می‌باشد. مقدار هدر باید با بدنه مطابقت داشته باشد و سروری که بدنه را پردازش می‌کند، باید در صورت عدم تطابق، درخواست را با 400 Bad Request و کد خطای -32020، HeaderMismatch رد کند. این قانون به این دلیل وجود دارد که load balancer که بر اساس هدر مسیریابی می‌کند و سروری که بر اساس بدنه اجرا می‌شود، دو منبع حقیقت متفاوت هستند. اگر بر اساس این هدرها مسیریابی یا rate-limiting انجام می‌دهید، ابتدا MCP-Protocol-Version را بررسی کنید: نسخه‌های قدیمی‌تر هرگز هدر را با بدنه اعتبارسنجی نمی‌کردند، بنابراین در آن نسخه‌ها مقدار هدر قابل اعتماد نیست.

عدم توافق بر سر نسخه اکنون یک خطای معمولی در هر درخواست است و نه یک handshake ناموفق. سروری که نسخهٔ درخواستی را پیاده‌سازی نکرده است، با 400 Bad Request و خطای -32022، UnsupportedProtocolVersion پاسخ می‌دهد و مواردی را که پشتیبانی می‌کند در data.supported فهرست می‌کند. کلاینت یکی را از آن لیست انتخاب کرده و دوباره تلاش می‌کند.

محل قرارگیری وضعیت: توکن‌ها، کرسرها و اشتراک‌ها

وضعیت از بین نرفته است. بلکه به مکان‌هایی منتقل شده که می‌توانید آن‌ها را مشاهده و لاگ کنید.

اعتبارنامه‌ها به هر درخواست منتقل می‌شوند. دیگر هیچ نشست (session) برای متصل کردن هویت وجود ندارد، بنابراین توکن دسترسی همراه با هر فراخوانی HTTP ارسال شده و هر بار اعتبارسنجی می‌شود. جزئیات در بخش احراز هویت در ادامه آمده است.

کرسرها باید موقعیت خود را حمل کنند. صفحه‌بندی در tools/list، resources/list، prompts/list و resources/templates/list از یک رشته کرسر مبهم (opaque) استفاده می‌کند و کلاینت‌ها نباید آن را تجزیه یا اصلاح کنند. در یک سرور تک‌پردازشی، معمول بود که offset در حافظه و با کلید نشست نگهداری شود. بدون نشست، کرسر باید برای هر replica کافی باشد تا لیست‌کردن را از سر بگیرد؛ بنابراین موقعیت را درون کرسر رمزگذاری و امضا کنید، یا آن را در حافظه‌ای که تمام replicaها به آن دسترسی دارند نگه دارید. یک کرسر نامعتبر باید -32602 برگرداند. آن را امضا کنید، زیرا یک کرسر مبهم همچنان ورودی ارائه‌شده توسط کلاینت است که کد شما آن را رمزگشایی کرده و به آن اعتماد می‌کند.

اشتراک‌ها متعلق به یک درخواست هستند، نه یک اتصال. کلاینتی که اعلان‌های تغییر را می‌خواهد، subscriptions/listen را با فیلتری که انواع مورد نظرش را نام می‌برد ارسال می‌کند: toolsListChanged، promptsListChanged، resourcesListChanged و resourceSubscriptions. سرور با notifications/subscriptions/acknowledged پاسخ می‌دهد و آن جریان پاسخ را باز نگه می‌دارد. اگر جریان قطع شود، سرور چیزی را نگه نمی‌دارد و کلاینت برای بازیابی آن، دوباره subscriptions/listen را ارسال می‌کند.

وضعیت برنامه در فراخوانی‌های متقاطع به یک هندل صریح تبدیل می‌شود. زمانی که سرور واقعاً باید چیزی را بین فراخوانی‌ها به خاطر بسپارد، پاسخ مشخصات فنی، یک شناسه تولیدشده توسط سرور است که به عنوان یک آرگومان ابزار معمولی بازگردانده می‌شود. این شناسه در طرحواره (schema) ابزار ظاهر می‌شود، قابل لاگ‌برداری است و هرگز توسط اتصال استنباط نمی‌شود. سروری که داده‌های واقعی هر کاربر را در پشت خود دارد، مانند یک سرور ایمیل MCP که خودتان میزبانی می‌کنید، به جای نشست از این الگو استفاده می‌کند: شناسه صندوق پستی یا پیش‌نویس، یک آرگومان ابزار است، بنابراین هر replica می‌تواند فراخوانی بعدی را دریافت کند. بسیاری از ابزارها اصلاً نیازی به هندل ندارند: یک ابزار جستجو که توسط نمونه SearXNG شخصی شما پشتیبانی می‌شود، یک پرس‌وجو را دریافت کرده و نتایج را بازمی‌گرداند، بدون اینکه چیزی برای از سرگیری در فراخوانی بعدی وجود داشته باشد و بدون اینکه اهمیتی داشته باشد کدام replica پاسخ داده است.

استقرار: reverse proxy، زمان‌بندی‌ها و بررسی سلامت

نقطه پایانی MCP یک مسیر واحد است که درخواست‌های POST را می‌پذیرد. بخش عمده ترافیک شامل یک درخواست کوتاه و پاسخ JSON است که هر پروکسی به‌راحتی آن را مدیریت می‌کند. استثنا، پاسخ‌های streaming است که تنظیمات پیش‌فرض پروکسی در آنجا علیه شما عمل می‌کنند. این همان بخشی است که هنگام انتقال از یک دموی محلی به یک سرور MCP در حال اجرا روی VPS تغییر می‌کند.

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 به‌طور پیش‌فرض پاسخ‌های proxied را بافر می‌کند؛ این کار باعث می‌شود رویدادهای SSE تا زمان پر شدن بافر یا پایان پاسخ، نگه داشته شوند. مشخصات فنی همچنین از سرورها می‌خواهد که در پاسخ‌های SSE هدر X-Accel-Buffering: no را ارسال کنند و nginx به این هدر احترام می‌گذارد، بنابراین یک سرور صحیح، دستورالعمل درست را به پروکسی شما اعلام می‌کند. با این حال، این دستورالعمل را تنظیم کنید، زیرا این بخشی است که شما کنترل می‌کنید.

مقدار پیش‌فرض proxy_read_timeout برابر با 60 ثانیه است. یک استریم subscriptions/listen که بیش از این مدت ساکت بماند، توسط nginx (و نه سرور شما) بسته می‌شود؛ در نتیجه لاگ‌های شما یک پردازش سالم را نشان می‌دهند اما کلاینت با قطع استریم مواجه می‌شود. این مقدار را فقط برای location مربوط به MCP افزایش دهید، نه برای کل سرور. همچنین به سرورها توصیه می‌شود در دوره‌های سکوت، یک خط کامنت SSE (خطی که با دونقطه شروع می‌شود) به عنوان keep-alive ارسال کنند تا از قطع شدن استریم توسط واسط‌ها جلوگیری شود.

Caddy به تنظیمات کمتری نیاز دارد. این ابزار به‌طور پیش‌فرض برای بهره‌وری شبکه، بافرینگ جزئی انجام می‌دهد و به محض اینکه پاسخ حاوی Content-Type: text/event-stream باشد، آن را تخلیه می‌کند؛ بنابراین streaming بدون نیاز به دستورالعمل‌های اضافی کار می‌کند.

mcp.example.com {
	reverse_proxy 127.0.0.1:8080 {
		health_uri /healthz
		health_interval 10s
	}
}

دقت کنید که آن بررسی سلامت (health check) به کجا اشاره دارد. یک بررسی فعال را با GET به سمت نقطه پایانی MCP هدایت نکنید، زیرا سروری که فقط این نسخه را پیاده‌سازی کرده است به GET و DELETE پاسخ 405 Method Not Allowed می‌دهد و متد پیش‌فرض بررسی سلامت در Caddy برابر با GET است. در این صورت، پروکسی یک backend کاملاً سالم را به اشتباه از دسترس خارج می‌کند. برای پروکسی، یک مسیر ساده مانند /healthz ارائه دهید و پروتکل را به‌طور جداگانه با یک درخواست POST بررسی کنید.

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 باشد، به این معنی است که پردازش بالا آمده و پروتکل را می‌فهمد. یک 404 با خطای JSON-RPC به شماره -32601 به این معنی است که پردازش فعال است اما server/discover را ارائه نمی‌دهد؛ موردی که هر سرور 2026-07-28 باید پیاده‌سازی کند. یک 400 با -32022 به این معنی است که بررسی‌کننده شما نسخه‌ای را درخواست کرده که این build از آن پشتیبانی نمی‌کند؛ این دقیقاً همان چیزی است که باید پس از ارتقای وابستگی‌ها شناسایی کنید. نسخه متن‌باز nginx بررسی سلامت فعال ندارد، بنابراین از max_fails و fail_timeout غیرفعال روی upstream استفاده کنید و بررسی پروتکل را از طریق سیستم مانیتورینگ خود انجام دهید.

اکنون یک rolling restart فقط باعث از دست رفتن درخواست‌های در حال اجرا می‌شود و نه چیز دیگر. پردازش را تخلیه کنید، اجازه دهید POSTهای باز تمام شوند، پردازش جدید را شروع کنید و کلاینت‌ها هر آنچه شکست خورده را دوباره ارسال می‌کنند. تنها چیزی که همچنان قطع می‌شود، هر استریم subscriptions/listen باز است، زیرا آن استریم یک اتصال زنده به یک پردازش خاص است. Stateless بودن، session affinity را حذف کرد، اما connection affinity را برای استریمی که همین حالا باز است حذف نکرد و هیچ قانون مسیریابی نمی‌تواند آن را اصلاح کند. کلاینت می‌تواند تفاوت را تشخیص دهد: استریمی که با نتیجه خالی subscriptions/listen پایان می‌یابد به‌درستی بسته شده و استریمی که بدون آن پایان می‌یابد قطع شده است، که کلاینت ممکن است آن را دلیلی برای اتصال مجدد بداند.

Caching برای اولین بار ممکن می‌شود. نتایج حاصل از متدهای لیست اکنون دارای ttlMs و cacheScope هستند و cacheScope: "public" به واسط‌های اشتراکی اعلام می‌کند که می‌توانند پاسخ را cache کنند. این کار تنها به این دلیل ایمن است که نتایج لیست دیگر بر اساس هر اتصال تغییر نمی‌کنند، که نتیجه مستقیم حذف sessionها است.

چرا با نبود نشست (session)، احراز هویت تغییر می‌کند

در مدل مبتنی بر نشست، وسوسه‌انگیز بود که یک‌بار در initialize احراز هویت انجام شود و سپس شناسه نشست (session ID) به عنوان مدرکی برای تمام درخواست‌های بعدی در نظر گرفته شود. شناسه نشستی که به این شکل استفاده شود، یک اعتبارنامه حامل (bearer credential) بدون مخاطب (audience)، بدون تاریخ انقضا و بدون مسیر ابطال است که توسط سرور خودتان صادر شده است. حذف نشست‌ها این میان‌بر را از بین می‌برد و جایگزین آن سخت‌گیرانه‌تر است.

یک سرور MCP محافظت‌شده، به عنوان یک Resource Server در OAuth 2.1 عمل می‌کند. هر درخواست HTTP از سمت کلاینت باید حاوی Authorization: Bearer <access token> باشد و سرور در هر درخواست، توکن را اعتبارسنجی می‌کند. اعتبارسنجی شامل بررسی مخاطب (audience) است: سرور باید تأیید کند که توکن مشخصاً برای او صادر شده است (مطابق با RFC 8707 یا همان Resource Indicators for OAuth 2.0) و نباید توکن‌هایی که برای مقاصد دیگر صادر شده‌اند را بپذیرد یا منتقل کند. کلاینت‌ها با ارسال پارامتر resource به همراه URI استاندارد سرور، مخاطب صحیح را درخواست می‌کنند.

فرآیند کشف (Discovery) با یک چالش آغاز می‌شود. هنگامی که درخواستی بدون توکن قابل‌استفاده برسد، سرور با 401 Unauthorized پاسخ می‌دهد.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         scope="files:read"

کلاینت resource_metadata را می‌خواند، آن سند را دریافت می‌کند (RFC 9728، متادیتای منابع محافظت‌شده OAuth 2.0 که سرورهای MCP ملزم به پیاده‌سازی آن هستند)، سرور احراز هویت را پیدا کرده و جریان (flow) را اجرا می‌کند. یک توکن معتبر که دسترسی‌های کافی ندارد، با 403 Forbidden و error="insufficient_scope" به همراه دامنه‌های (scopes) مورد نیاز برای آن عملیات مواجه می‌شود.

این موضوع دو پیامد برای نحوه اجرای شما دارد. اعتبارسنجی توکن اکنون به جای یک‌بار در هر نشست، در هر درخواست انجام می‌شود؛ بنابراین یک رفت‌وبرگشت شبکه به endpoint درون‌سنجی (introspection) در هر فراخوانی، در تأخیر (latency) شما نمایان خواهد شد: توکن‌هایی را ترجیح دهید که بتوانید به‌صورت محلی با بررسی امضا، مخاطب و تاریخ انقضا تأیید کنید، یا نتیجه اعتبارسنجی را برای یک بازه زمانی کوتاه با کلید توکن کش (cache) کنید. و از آنجا که هیچ نشستی برای نگهداری هویت وجود ندارد، مجوزها باید در هر فراخوانی از روی توکن محاسبه شوند. این روش نسبت به مدل نشست صادقانه‌تر است و با رویه گسترده‌ترِ دور نگه‌داشتن اعتبارنامه‌ها از فرآیند عامل (agent process) همخوانی دارد که در دور نگه‌داشتن اسرار از یک عامل هوش مصنوعی به آن پرداخته شده است.

چه چیزی در مورد این نسخه درست است و چه چیزی نیست

تمام مطالب بالا نسخه 2026-07-28 را توصیف می‌کند. این مطالب توصیف‌کننده همیشگی MCP نیست و سروری که سال گذشته مستقر کرده‌اید را نیز شامل نمی‌شود.

کلاینت‌ها و سرورها در نسخه 2025-11-25 و قدیمی‌تر همچنان از مدل handshake استفاده می‌کنند. در این مشخصات، آن نسخه‌ها «قدیمی» (legacy) و نسخه‌های دارای متادیتایِ هر-درخواست، «مدرن» نامیده می‌شوند. سروری که فقط از این نسخه پشتیبانی می‌کند، هنگام مواجهه با یک کلاینت قدیمی، باید در endpoint مربوط به MCP پاسخ 405 Method Not Allowed به GET یا DELETE بدهد، هرگونه هدر Mcp-Session-Id را بدون ایجاد یا بازتاب آن نادیده بگیرد، و از آنجا که استریم‌ها قابل ازسرگیری نیستند، Last-Event-ID را نیز نادیده بگیرد. یک سرور دوگانه می‌تواند هر دو مدل را روی یک endpoint ارائه دهد: درخواستی که دارای _meta مدرن باشد به صورت stateless (بدون وضعیت) پردازش می‌شود و درخواست initialize، معناشناسی نشست (session) قدیمی‌تر را انتخاب می‌کند.

بنابراین پیش از اعتماد به هر یک از این موارد، رشته نسخه را بررسی کنید. اگر SDK شما همچنان initialize ارسال می‌کند، نشست‌ها برای استقرار شما همچنان واقعی هستند و مشکلات مربوط به ساختار نشست که در بالا ذکر شد، همچنان بر عهده شماست. همین موضوع در سمت کلاینت نیز صدق می‌کند: یک پردازش عامل (agent) روی سیستم خودتان، مانند تنظیمات در اجرای یک عامل کدنویسی روی VPS، تنها در صورتی از نظر این مفهوم stateless است که کتابخانه مورد استفاده‌اش از یک نسخه مدرن پشتیبانی کند. نسخه‌ای که runtime شما مذاکره می‌کند را بخوانید، سپس نسخه منطبق در مشخصات را مطالعه کنید و این صفحه را به عنوان توصیفی از یک نسخه خاص در نظر بگیرید، نه پروتکل به صورت کلی.

FAQ

آیا stateless بودن سرور MCP به این معنی است که نمی‌توانم هیچ داده‌ای را ذخیره کنم؟

خیر. واژه stateless به پروتکل اشاره دارد، نه به برنامه شما. پایگاه‌های داده، صف‌ها و کش‌ها دقیقاً مانند گذشته کار می‌کنند. آنچه تغییر می‌کند این است که وضعیت (state) در فراخوانی‌های متعدد باید توسط یک شناسه صریح که کلاینت در هر درخواست ارسال می‌کند، ارجاع داده شود؛ مانند یک handle که توسط سرور در آرگومان ابزار (tool argument) تولید شده است. آنچه مجاز نیست، استنباط context از طریق اتصال است: مشخصات فنی می‌گوید سرور نباید برای تعیین قابلیت‌ها، نسخه پروتکل یا هویت کلاینت به درخواست‌های قبلی در همان اتصال متکی باشد، زیرا هر درخواست این موارد را در _meta ارائه می‌دهد.

آیا همچنان به sticky sessions در load balancer نیاز دارم؟

برای درخواست‌های معمولی، خیر. طبق بازبینی 2026-07-28، هر POST نسخه پروتکل، قابلیت‌ها و اعتبارنامه‌های خاص خود را حمل می‌کند، بنابراین هر replica می‌تواند به هر درخواستی پاسخ دهد و استفاده از round-robin مشکلی ندارد. تنها مورد طولانی‌مدت باقی‌مانده، جریان پاسخ subscriptions/listen است که یک اتصال باز واحد به یک پردازش واحد است. این جریان با پایان یافتن آن پردازش خاتمه می‌یابد و کلاینت برای برقراری مجدد آن، subscriptions/listen را دوباره ارسال می‌کند. این موضوع مربوط به طول عمر اتصال است، نه session affinity، و هیچ قانون مسیریابی نمی‌تواند مانع آن شود.

چه اتفاقی برای Mcp-Session-Id و جریان HTTP GET افتاد؟

هر دو در بازبینی 2026-07-28 و تحت SEP-2567 و SEP-2575 حذف شدند. سروری که فقط این بازبینی را پیاده‌سازی می‌کند، باید به 405 Method Not Allowed با GET و DELETE در endpoint مربوط به MCP پاسخ دهد و باید هدر Mcp-Session-Id را نادیده بگیرد، نه اینکه آن را بازتاب دهد. اعلان‌های تغییر که توسط سرور آغاز می‌شوند، اکنون به جای یک جریان مستقل GET، از طریق جریان پاسخ یک درخواست subscriptions/listen ارسال می‌شوند. سرورهایی که باید به کلاینت‌های قدیمی‌تر سرویس‌دهی کنند، رفتار بازبینی‌های قبلی را در کنار این بازبینی پیاده‌سازی می‌کنند.

چگونه یک سرور MCP را بدون handshake بررسی سلامت (health check) کنم؟

از دو سطح استفاده کنید. بررسی فعال (active check) پروکسی را به یک مسیر HTTP ساده که برنامه شما ارائه می‌دهد هدایت کنید، زیرا یک GET به endpoint مربوط به MCP به درستی 405 برمی‌گرداند و باعث می‌شود یک backend سالم، از دسترس خارج (down) تلقی شود. سپس خود پروتکل را با ارسال یک POST به server/discover بررسی کنید که هر سرور 2026-07-28 باید آن را پیاده‌سازی کرده باشد، و اطمینان حاصل کنید که پاسخ HTTP 200 است و شامل نسخه پروتکلی است که کلاینت‌های شما استفاده می‌کنند. یک 404 با خطای JSON-RPC به شماره -32601 به این معنی است که پردازش در حال اجراست اما آن متد را ارائه نمی‌دهد، و یک 400 با -32022 به این معنی است که نسخه درخواستی شما توسط آن build پشتیبانی نمی‌شود.