Phase 13: Tools & Protocols

ساخت یک مشتری MCP: کشف، مسیریابی و بازگشت دو عصر

یک مشتری MCP مدرن قرارداد خود را در هر درخواست تکرار می کند. سخت ترین تصمیم سازگاری آن دانستن زمانی است که یک سرور قدیمی واقعا قدیمی است و زمانی که یک سرور مدرن یک خطای قابل اصلاح را گزارش می کند.

Type: Build

Languages: Python

Prerequisites: Phase 13, Lesson 07

Time: ~85 minutes

اهداف یادگیری

  • هر MCP رو بسازید2026-07-28درخواست با متاداتا فعلی
  • سرورهای استودیو را با server/discoverو نسخه ای را که به طور متقابل پشتیبانی می شود انتخاب کنید.
  • اجازه دادن به یک بررسی میراث محدود فقط برای همسالان به طور صریح اجازه داده شده است.
  • فقط بعد از تایید مثبت، دوران میراث را بپذیریinitializeنتیجه برای یک بازبینی پشتیبانی شده.
  • لیست ابزار تعیین کننده را بدون کتمان خاموشی درگیری ها ترکیب کنید.
  • تماس های روت به همسالانی که مالک هر ابزار هستند بدون اختراع جلسات پروتکل

مشکل

یک میزبان عامل معمولا با بیش از یک سرور MCP صحبت می کند. آن باید هر سرور را کشف کند، کاتالوگ ابزار را ترکیب کند، نام های تکراری را حل کند، تماس های مسیر را انجام دهد و از شکست حمل و نقل بهبود یابد.

.2026-07-28اصلاح حالت ثابت را ساده تر می کند زیرا هر درخواست مستقل است. مطابقت باعث می شود شروع ظریف تر شود. یک مشتری ممکن است با:

  • یک سرور مدرن که از نسخه مورد علاقه پشتیبانی می کند؛
  • یک سرور مدرن که یک نسخه شناخته شده یا خطای سرنخ را باز می گرداند؛
  • سرور قدیمی که تا حالا نشنیده بودserver/discover؛
  • یک سرور قدیمی که تا زمانی که دریافتش نمی کند ساکت می ماندinitialize. .

با توجه به اینکه هر خطا در حال بررسی به عنوان یک میراث خطرناک است. یک درخواست مدرن مخرب، یک سرور بیش از حد بارگذاری شده، یک فرآیند مرده و یک سرور قدیمی می تواند همه یک زمان پایان یا اتصال را به پایان برساند. این سیگنال ها مبهم هستند. مشتری باید قصد صریح کارگر را با شواهد پروتکل مثبت ترکیب کند قبل از اینکه عصر میراث را انتخاب کند.

مفهوم

یک همسال، نه جلسه پروتکل

یک رکورد تراکنش برای هر فرآیند یا نقطه پایان سرور نگه دارید:

  • عملکرد حمل و نقل یا ارسال؛
  • دوره و نسخه پروتکل انتخاب شده؛
  • آخرین قابلیت های سرور کشف شده؛
  • آخرین لیست ابزار تعیین کننده؛
  • شناسه های درخواست در انتظار برای ارتباط؛
  • بهداشت حمل و نقل

این حسابداری مشتری است. این حالت جلسه پروتکل نیست. در MCP مدرن، سرور هنوز هم نسخه و قابلیت های فعلی را در هر درخواست دریافت می کند.

هر درخواست مدرن رو از نو بساز

pythondef modern_request(request_id, method, params, version, capabilities):
    return {
        "jsonrpc": "2.0",
        "id": request_id,
        "method": method,
        "params": {
            **params,
            "_meta": {
                "io.modelcontextprotocol/protocolVersion": version,
                "io.modelcontextprotocol/clientCapabilities": capabilities,
                "io.modelcontextprotocol/clientInfo": CLIENT_INFO,
            },
        },
    }

یک بار به یک شی اتصال متاداتا را متصل نکنید و فرض کنید که به سیم رسیده است.

کشف مدرن

server/discoverنسخه های پشتیبانی شده، قابلیت های سرور، دستورالعمل ها، نکات کش و هویت سرور توصیه شده را باز می گرداند. یک مشتری بهترین نسخه مدرن پشتیبانی شده با هم را انتخاب می کند.

کشف برای یک مشتری مدرن فقط اختیاری است، اما در استودیو توصیه می شود. برخی از سرورهای قدیمی قبل از آغاز عملیات را قبول می کنند، بنابراین ارسال tools/listاول می تواند موفقیت مبهم را به ارمغان بیاورد.server/discoverمرز عصر پاک را ایجاد می کند.

ساند سازگاری استودیو

یک مشتری استودیویی دو عصر ارسال می کندserver/discoverبا متادای مدرن مورد علاقه خود قبل از هر درخواست دیگر وجود دارد. سه کلاس نتیجه وجود دارد:

  1. DiscoverResult.سرور مدرن است. یک نسخه متقابل پشتیبانی شده را انتخاب کنید و به هر درخواست متادتا ادامه دهید.
  2. Recognized modern error.سرور مدرن است-32022، از بينش انتخاب کنdata.supportedو دوباره با یک شناسه درخواست جدید تلاش کنید. برای خطا های سر یا قابلیت، درخواست را اصلاح کنید. ارسال نکنید initialize. .
  3. Ambiguous signal.یک خطا JSON-RPC شناخته نشده، زمان بندی، اتصال بسته یا پاسخ خالی یک دوره را شناسایی نمی کند. بسته شدن شکست خورده مگر اینکه آن همتایی دقیق برای سازگاری میراث پیکربندی شده باشد.

اشتباهات پروتکل مدرن شناخته شده عبارتند از:

  • -32020عنوان اشتباه
  • -32021نیازمندی: قابلیت مشتری
  • -32022پشتیبانی نشده پروتکل نسخه

خطا های شناخته شده مدرن حتی زمانی که همسال در لیست اجازه داده شده است، مدرن باقی می مانند. هنگامی که سرور ثابت می کند که از لغات خطا مدرن درک می کند، ارسال initializeاين يه درجه پايين خواهد بود

درمان نکن-32601این تنها یک همتایان را به طور صریح اجازه داده است که برای یک بررسی میراث واجد شرایط باشند. همان قانون برای یک زمان توقف، اتصال نزدیک یا پاسخ خالی اعمال می شود.

اجازه دادن به کار قصد کاربری است نه شواهد

سازگاری میراث باید یک ویژگی صریح یک پیکربندی همتایی قرار گیرد:

pythonclient.add_server("archive", archive_transport, allow_legacy=True)

این انتخاب را به دستور یا نقطه پایان پیکربندی کنید. از یک کارت وحشی استفاده نکنید که اجازه می دهد یک سرور تعسفی خود را به معنای ضعیف تر انتخاب کند. یک همتایی بدون allow_legacy=Trueبعد از یک کشف مبهم شکست می خورد و هرگز دریافت نمی کنهinitialize. .

اجازه دهنده اجازه داده تا جستجو کند. زمان را انتخاب نمی کند. مشتری یکی را می فرستد.initializeدر این صورت، در زمان زمانی که حمل و نقل مجبور به انجام آن می شود، تمام موارد زیر را نیاز دارد:

  • یک JSON-RPC 2.0پاسخ با شناسه درخواست مطابقت پذیر؛
  • دقیقاً یکresultو نهerror؛
  • a protocolVersionدر مجموعه بازبینی قدیمی پیکربندی شده مشتری؛
  • یک ارزش شیcapabilitiesمیدان؛
  • a serverInfoشی با رشته خالی نیستnameوversion. میدان ها

یک زمان توقف، بسته شدن اتصال، پاسخ خطا، نتیجه بد شکل، ID نامتناسب یا اصلاح غیر پشتیبانی نشده بسته می شود. تنها یک نتیجه مثبت معتبر از نظر ساختار، دوره میراث را انتخاب می کند. کد عبور می کند legacy_probe_timeout_msبه آداپتور حمل و نقل؛ یک آداپتور واقعی استودیو یا HTTP باید این مهلت را اجرا کند نه فقط آن را ثبت کند.

زمان انتخاب شده رو براي همسالي حمل و نقل به جا نگه داريد و قبل از هر تماس دوباره جستجو نکنید

میراث شاخه ی سازگاری است

هنگامی که یک بار از تحقیقات محدود شده شواهد معتبر مثبت میراث را باز می گرداند، مشتری از نسخه میراث انتخاب شده دقیقاً همانطور که در آن تجدید نظر تعریف شده است استفاده می کند:

  1. بررسی موشک پاسخ و شناسه ارتباط
  2. بررسی کنید که تجدید نظر مذاکره شده در مجموعه میراث پیکربندی شده است.
  3. قابلیت های تایید شده و هویت سرور را ثبت کنید.
  4. بفرستnotifications/initializedفقط بعد از اينکه تمام چک ها رد بشه
  5. از اشکال درخواست میراث برای طول عمر حمل استفاده کنید.

این شاخه برای قابلیت همکاری با همتایان شناخته شده وجود دارد. این طراحی پیش فرض برای سرورهای جدید یا درخواست های جدید نیست. اگر حمل و نقل دوباره شروع شود یا نقطه پایان آن تغییر کند، حافظه کش همتایان را کنار بگذارید و دوباره مذاکره کنید.

ابزار کشف و ذخیره سازی

برای هر همسال فعال، تماس بگیریدtools/list. نتیجه مدرن شاملresultType،ttlMsوcacheScope. به عنوان یک اشاره تازه در زمینه مجاز درست احترام بگذارید. پس از انقضاء یا یک رویداد تغییر لیست مشترک دوباره دریافت کنید.

مشتریان بايد يه گمشده رو درمان کننresultTypeاز یک سرور قدیمی به عنوان "complete". به میدان های جدید حافظه کش برای پاسخ از دوران مذاکره قبلی نیاز نیست

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

ترکیب فضای نام های ایمن از برخورد

دو سرور ممکنه هر دوشون رو افشا کننsearch. یک سیاست اعلام شده را انتخاب کنید:

  1. Prefix on collision.اولين اسم قنونيکي رو نگه دار و برخورد هاي بعد رو به عنوان<server>/<tool>. .
  2. Reject on collision.دوگونی را بار ندهید و یک خطا پیکربندی واضح را نشان ندهید.
  3. Silent overwrite.هرگز از اين استفاده نکن اين مخفي ميکنه که کدام سرور عملي را به صورت مدلي مي پذيرد

هم نام های کنونی و هم نام های محلی را ذخیره کنید. مدل نام کنونی را می بیند. نام خارج شدهtools/callاز نام محلی که سرور مالک اعلام شده استفاده می کند.

راه اندازی تماس

روتینگ یک جستجوی خالص است:

textcanonical tool name
  -> peer name + local tool name
  -> new JSON-RPC request id
  -> modern request metadata or explicit legacy shape
  -> matching response id

وقتی حمل و نقل مالک آن در دسترس نیست تماس ندهید. حمل و نقل را دوباره متصل کنید یا دوباره شروع کنید، سپس کشف و کشف را دوباره انجام دهید.tools/listدرخواست های مدرن در طی پرواز که در یک حمل و نقل خراب شده از دست رفته است می تواند با یک شناسه JSON-RPC جدید دوباره امتحان شود، زمانی که سیاست ایمنی عملیات اجازه می دهد.

اطلاعیه ها و اشتراک

تغییرات جدید لیست و منابع تنها در یک مشتری باز می شوند subscriptions/listen.مصرفي فيلتر اطلاع رساني رو ارسال ميکنه و منتظرش ميرهnotifications/subscriptions/acknowledged, و اتفاقات را با اسم درخواست شنیدن در متاداتا اطلاع رسانی مرتبط می کند.

در زمان قطع ارتباط، درخواست جدید گوش دادن را باز کنید و لیست ها یا منابع مربوطه را دوباره ارسال کنید. جریان های مدرن با Last-Event-ID. .

هیچ درخواست از سوی سرور آغاز نشده

سرورهای مدرن با درخواست های JSON-RPC مستقل برای نمونه گیری، ایجاد یا ریشه به مشتری تماس نمی گیرند. آنها به شما باز می گردند input_required، و مشتری بعد از تکمیل درخواست های ورودی داخلی درخواست اصلی را دوباره امتحان می کند.

هنگام انجام ورودی، خواننده پاسخ همتایان را مسدود نکنید. ارتباط را حفظ کنید و یک شناسه JSON-RPC جدید برای دوباره تلاش ایجاد کنید.

ازش استفاده کن

code/main.pyاین سیستم از عملکردهای همتایی در فرآیند استفاده می کند تا تصمیمات پروتکل قابل مشاهده باقی بمانند. آن به دو همتایی مدرن و یک همتایی میراث به طور عمدی اجازه داده شده متصل می شود، سپس ابزار آنها را ادغام و مسیر می دهد. کال کال کال کال ترانسپورت بودجه ای را دریافت می کند تا شاخه سازگاری نمی تواند یک سوند بی محدودیت را پنهان کند.

bashcd code
python3 main.py
python3 -m unittest discover tests -v

تست ها ثابت ميکنه که مرزهای معمولي که ديمو ها از دست ميدن:

  • درخواست های مدرن متاداتا را تکرار می کنند؛
  • -32022تلاش برای کشف مدرن بدون شروع مجدد
  • اشتباهات مدرن شناخته شده هرگز درجه پایین نیاید، حتی برای یک همسال مجاز؛
  • وقت قطع، بسته شدن اتصال، پاسخ های خالی و خطا های ناشناخته باعث نمی شوند initializeبدون اجازه نامه ای؛
  • یک همسال مجاز تنها پس از یک تایید معتبر به ارث می رسدinitializeنتیجه؛
  • نتایج ورثاتی که با اشکال نادرست و پشتیبانی نشده است، باعث می شود که همتایان در دسترس نباشند.
  • یک دوره موفق انتخاب شده برای عمر حمل و نقل ذخیره می شود.

-باده

اين درس به ما ميگيرهoutputs/skill-mcp-client-harness.md. این استفادۀ مدرن درخواست مهر، استودیو عصر مذاکره، تعیین کننده namespace ادغام، روتینگ و یک شکست بسته میراث مطابقت شاخه.

تمرینات

  1. يه سرور جوري بازگردانيد-32022بدون نسخه ای که به طور متقابل پشتیبانی شود. تایید کنید که مشتری شکست خورده است به جای ارسالinitialize. .
  2. اجازه دادن به یک سرور قدیمی جعلی، محدود کردنشinitializeزماني رو آزمايش کن و ثابت کن که همسالش اينجاستunknownو در دسترس نیست
  3. اضافه کردنcacheScope: "private"لیست ابزار برای دو زمینه مجوز. تایید کنید که مشتری هرگز نتیجه ذخیره شده یک زمینه را با دیگری به اشتراک نمی گذارد.
  4. سیاست برخورد را به رد تغییر دهید و با هر دو نام همتایان در خطا شروع به شکست دهید.
  5. يه عدد محدود اضافه کنsubscriptions/listenدر زمان از دست دادن جریان، دوباره با یک شناسه درخواست جدید گوش کنید و ابزار بازنویسی را استفاده کنید.

اصطلاحات کلیدی

TermMeaning
PeerClient-side record for one server transport and its discovered data
Protocol eraModern per-request metadata or legacy initialization semantics
Discovery probeInitial server/discover used to identify the stdio era
Recognized modern errorError that proves modern behavior and forbids legacy fallback
Legacy allowlistOperator configuration permitting one bounded compatibility probe for a pinned peer
Positive legacy evidenceValid, correlated initialize result for an explicitly supported legacy revision
Merged namespaceCanonical tool names across all active peers
Collision policyPrefix or reject rule for duplicate tool names
Era cacheSelected modern or legacy behavior stored for one transport peer
Transport recoveryRestart or reconnect, rediscover, relist, and retry safely with a new id

خواندن بیشتر

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.