چیتشیت
کلاینتها و بسترهای انتقال MCP
MCP Clients and Transports
آزمون ارزیابی، merge و هدایت طرفهای ارتباط MCP 2026-07-28 روی stdio و پروتکل HTTP جریانی. تلاش مجدد دورهای MRTR. قالببندی فریمهای JSON-RPC.
فهرست مطالب
کلاینت چندسروری
معماریآزمون ارزیابی دورهی stdio
گامبهگام- کلاینت
server/discoverرا قبل از هر درخواست دیگری میفرستد. - نتیجهمدرن. انتخاب بالاترین نسخهی مشترک.
- -32022مدرن. انتخاب از
data.supported. تلاش مجدد با شناسه جدید. - -32020, -32021مدرن. اصلاح درخواست. بدون
initialize. - پایان مهلت، قطع اتصال، خطای ناشناختهمبهم. پایان امن با خطا (Fail closed).
- طرف ارتباط در لیست مجازیک
initializeمحدود. بررسیprotocolVersion،capabilities،serverInfo. - کش دورهی سازگارینگهداری آن در طول عمر بستر انتقال.
وظایف کلاینت در کد
کار و کد| وظیفه | کد |
|---|---|
| ثبت یک طرف ارتباط مدرن | client.add_server("notes", notes) |
| مجوز یک آزمون ارزیابی میراثی | client.add_server("archive", archive, allow_legacy=True) |
| آزمون ارزیابی تمام طرفهای ارتباط به ترتیب نام | client.connect_all() |
| فهرستکردن ابزارهای هر طرف ارتباط فعال | client.discover_tools() |
| رد نامهای تکراری | client.merge(policy="reject") |
| فراخوانی با نام استاندارد | client.call("notes/search", {}) |
| بازتاب فیلدهای بدنه در هدرها | http_headers_for(message) |
| پاسخدهی به خطوط JSON-RPC تا رسیدن به EOF | serve(handler, StdioTransport(stdin, stdout)) |
اجرای درسها
دستورها| دستور | عملکرد |
|---|---|
python3 code/main.py | 11.14: شناسایی demo-server در نسخهی 2026-07-28 |
python3 main.py | 13.08 در code/: طرفهای ارتباط، ابزارهای merge شده، فراخوانیها |
python3 main.py --probe | 13.09: اجرای آزمون ارزیابی HTTP روی یک پورت آزاد |
python3 main.py --serve | 13.09: ارائهی سرویس روی http://127.0.0.1:8017/mcp |
python3 main.py | 13.11 در code/: شناسههای درخواست [1, 2, 3] |
python3 code/main.py | 19.22: دموی BytesIO، چاپ server_responses |
python3 -m unittest discover tests -v | اجرای آزمونها از code/ |
درج مهر روی تمام درخواستهای مدرن
کدpython
def modern_request(request_id, method, params, version, capabilities=None):
body_params = dict(params or {})
body_params["_meta"] = request_meta(version, capabilities) # جدید در هر فراخوانی
return {"jsonrpc": "2.0", "id": request_id, "method": method, "params": body_params}
VERSION_KEY = "io.modelcontextprotocol/protocolVersion" # الزامی
CAPABILITIES_KEY = "io.modelcontextprotocol/clientCapabilities" # الزامی
CLIENT_INFO_KEY = "io.modelcontextprotocol/clientInfo" # هویت کلاینت
RECOGNIZED_MODERN_ERRORS = {-32020, -32021, -32022} # هرگز به نسخهی پایینتر برنگردید
stdio یا پروتکل HTTP جریانی
مقایسه| عامل | stdio | پروتکل HTTP جریانی |
|---|---|---|
| مورد استفاده برای | زیرفرایند راهاندازیشده توسط کلاینت | سرویس شبکه |
| قالببندی فریمها | یک پیام JSON-RPC به صورت UTF-8 در هر خط | یک پیام JSON-RPC به ازای هر POST |
| زمینهی نسخه | params._meta | params._meta به همراه هدرهای بازتابیافته |
| پاسخ | یک خط روی stdout | پاسخ JSON یا رویدادهای ارسالی سرور در دامنهی درخواست |
| اعلان | بدون خط پاسخ | 202 Accepted، بدون بدنه |
| عیبیابی | فقط stderr | وضعیت HTTP به همراه خطای JSON-RPC |
| رویدادهای تغییر | بازگشایی مجدد پس از راهاندازی دوباره | جریان POST مربوط به subscriptions/listen |
| امنیت | خروج با دریافت EOF در stdin | اعتبارسنجی Origin، اتصال به 127.0.0.1 |
دور MRTR برای نمونهبرداری (Sampling)
گامبهگام- کلاینت
tools/callرا فراخوانی میکند. قابلیتها شاملsamplingهستند. - سرورمقادیر
input_required،inputRequestsوrequestStateرا برمیگرداند. - کلاینتخطمشی را بررسی کرده و از مدل خود میپرسد.
- کلاینتهمان متد و آرگومانها، شناسهی جدید،
inputResponses، دقیقاً همانrequestState. - سروراعتبارسنجی HMAC، هویت اصلی، خلاصهی آرگومانها و انقضا.
- سرورآخرین دور
resultType: "complete"را برمیگرداند.
مقادیر پیشفرض در کد درس
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
discovery_timeout_ms | 1_000 | باید مثبت باشد |
legacy_probe_timeout_ms | 1_000 | ارسالشده به تطبیقدهندهی بستر انتقال |
`merge` policy | prefix-on-collision | یا reject |
Discovery `ttl_ms` | 3_600_000 | cache_scope="public" |
MAX_REQUEST_BYTES | 1_048_576 | بدنهی بزرگتر خطای -32700 میدهد |
READ_TIMEOUT_SECONDS | 5.0 | مهلت زمانی سوکت هنگام خواندن بدنه |
maxTokens | 400 | به ازای هر درخواست نمونهبرداری تعبیهشده |
`requestState` expiry | 300 | ثانیههای پس از اولین فراخوانی |
کدهای وضعیت و خطا
عیبیابیکد HTTP 400،
-32020- علت
- هدر موجود نیست یا با بدنه تفاوت دارد
- راهحل
- ساخت هدرها از روی بدنهی نهایی
کد HTTP 400،
-32022- علت
- نسخه پشتیبانی نمیشود
- راهحل
- تلاش مجدد با مقداری از
supported
-32021- علت
- کلاینت فاقد قابلیت الزامی است
- راهحل
- خواندن
data.requiredCapabilities
-32602- علت
_metaناموجود یاrequestStateنامعتبر- راهحل
- ارسال
_metaو بازتاب وضعیت
کد HTTP 403
- علت
Originدر لیست مجاز نیست- راهحل
- استفاده از تطابق دقیق Origin
کد HTTP 404،
-32601- علت
- متد مدرن ناشناخته
- راهحل
- آن را به عنوان اثبات میراثی تلقی نکنید
کد HTTP 405
- علت
- متد GET یا DELETE روی
/mcp - راهحل
- استفاده از POST و
subscriptions/listen
-32700، با id برابر null- علت
- یک خط stdio فرمت JSON نامعتبر دارد
- راهحل
- حلقه با خط بعدی ادامه مییابد
پرسشها
پرسش و پاسخ- آیا -32601 اثبات سرور میراثی است؟
- خیر. فقط به یک طرف ارتباط در لیست مجاز اجازهی یک آزمون ارزیابی میدهد.
- آیا جریان میتواند از سر گرفته شود؟
- خیر.
Last-Event-IDنادیده گرفته میشود. یک درخواست جدید با شناسهی جدید بفرستید. - وضعیت جریان کاری کجا ذخیره میشود؟
- درون هندلی که توسط سرور صادر شده و کلاینت آن را به عنوان آرگومان ارسال میکند.
- آیا سرور میتواند کلاینت را فراخوانی کند؟
- خیر.
input_requiredبرمیگرداند و کلاینت دوباره تلاش میکند. - آیا ترجیحات مدل به یک جمع میشوند؟
- خیر. آنها راهنماییهای مستقلی هستند.
پروژه: میز کار شناسایی ابزار MCP
دستورها| دستور | عملکرد |
|---|---|
python3 scripts/project_test.py mcp-at-scale --all --path <dir> --strict | اجرای تصحیحکننده. ابتدا مقداردهی اولیه با --init <dir> |
python3 cli.py samples/inventory.json --query "pods count" --max-chars 500 | بهترین اسکیماها در چارچوب بودجه |
python3 cli.py /absolute/inventory.json --serve | سرور stdio با catalog_search |
Checks | قبل از initialize: کد -32002. صفحههای 32 ابزاری. 250 نام در 8 صفحه |
نکات
نکتهها- درخواست سریالسازیشدهی نهایی را بازرسی کنید.
- ارسال
Mcp-Nameغیر ASCII به صورت=?base64?{Base64EncodedValue}?=. - ایجاد سقف برای دورهای MRTR. اعتبارسنجی هر پاسخ نمونهبرداری.
- در صورت قطع جریان، ارسال مجدد
subscriptions/listenو واکشی مجدد. - در حالت stdio، پیامهای عیبیابی را در stderr بنویسید.