ورود به دروازه های MCP بدون تابعیت و ثبت
Type: Learn
Languages: Python
Prerequisites: Phase 13 · 15 (security), Phase 13 · 16 (authorization)
Time: ~75 minutes
اهداف یادگیری
- چند سرور MCP را در پشت یک نقطه پایان 2026-07-28 جمع آوری کنید بدون ارتباط جلسه.
- قبل از ارسال یا ارسال سیاست ها، متاداتا و سرنخ های رویت را بر حسب درخواست تأیید کنید.
- ابزارها را با نام های ثابت، ترتیب تعیین کننده، پین های توصیف کننده، RBAC و ذخیره سازی خصوصی ادغام کنید.
- پرونده های ثبت را به عنوان شواهد کشف که هنوز هم نیاز به سیاست پذیرش دارد، در نظر بگیرید.
- SSE که در مورد درخواست مسیر مشخص شده است
subscriptions/listen، MRTR دوباره تلاش ميکنه و درخواست تمديد وظايف درست شده - دست دادن و پشتیبانی از جلسات قدیمی را از مسیر مدرن جدا کنید.
مشکل
اتصال یک مشتری به یک سرور مستقیم ساده است. یک انتشار بزرگتر نیاز به پاسخ ثابت به سوالات سخت تر دارد:
- چه سرورها مجاز هستند؟
- چه مدير مي تونه هر ابزار رو ببينه و صدا بزنه؟
- چه اتفاقی می افتد وقتی دو پس زمینه از یک نام را افشا کنند؟
- چگونه تغییرات در توصیفات مورد بررسی قرار می گیرد؟
- محدودیت های نرخ و رویدادهای حسابرسی در کجا اعمال می شود؟
- ميشه يه نمونه از درخواست بعد رو رد کرد؟
یک دروازه بین مشتریان و سرورهای MCP پس زمینه قرار دارد. این یک نقطه پایان MCP را ارائه می دهد، سیاست های متقابل را اعمال می کند و درخواست های تأیید شده را ارسال می کند.
طرح های قدیمی تر دروازه اغلب یک جلسه مشتری را به چندین جلسه پس از پایان متصل می کنند و دوباره نوشته می شوند Mcp-Session-Id. اين يه طرح پيوندگيري قدیمیه . هسته 2026-07-28 هيچ جلسه پروتکل نداره
مفهوم
راه دروازه مدرن
برای هر درخواست:
- اعتبار اصلی را از مجوز حمل و نقل تأیید کنید.
- اعتبارش را تایید کن
MCP-Protocol-Version،Mcp-Method،Mcp-Nameوparams._meta. . - اجازه دادن به اصل، منابع، روش، ابزار و استدلال ها.
- سیاست های شرح، ثبت، نرخ و داده ها را اعمال کنید.
- یک درخواست تازه و مستقل برای پس زمینه انتخاب شده ایجاد کنید.
- نتیجه پسدید را تایید کنید و نتیجه دروازه را بازگردانید.
- بدون ثبت اسرار، یک رویداد حسابرسی ثبت کنید.
هیچ مرحله ای به یک جلسه پروتکل پنهان نیاز ندارد. حالت برنامه هنوز هم می تواند در پایگاه داده ها، دستی های صریح، وظایف یا حالت MRTR محافظت شده از سالمیت وجود داشته باشد.
سیاست زمان اجرا تصمیم اصلی دروازه است
پذیرش تصمیم می گیرد که کدام نسخه پشتیبان ممکن است وارد دروازه شود. این اجازه تماس زنده را نمی دهد. برای هر درخواست، دروازه سیاست را از اصلی معتبر، صادر کننده و منبع، مستاجر، روش و نام مطابقت پذیر، استدلال های عادی، پین توصیف کننده پذیرفته، سلامت فعلی پشت سر، تقاطع قابلیت، طبقه بندی داده ها، وضعیت نرخ و هرگونه تأیید مربوط به عمل دوباره محاسبه می کند.
این امر مهم است. یک رکورد ثبت می تواند در حالی که نقش کاربر لغو می شود فعال بماند. یک توصیفگر می تواند در حالی که یک استدلال مقصد از مرز مستاجر عبور می کند، ثابت بماند. یک پس زمینه می تواند در حالی که سیاست حریم خصوصی تماس های تغییر وضعیت را تایید می کند، تأیید شود. بنابراین سیاست زمان اجرا تصمیم اصلی اجازه یا انکار است، با ثبت و شواهد توصیفگر به عنوان ورودی.
یک تصمیم اجازه را در زیر یک اتصال یا شناسایی جلسه حذف نکنید. اگر سیاست در دسترس نباشد، از یک سیاست شکست اعلام شده توسط کلاس عملیات پیروی کنید. یک پیش فرض امن برای تغییر حالت و خواندن حساس بسته شدن است، در حالی که مسیرهای خواندن عمومی صریحاً تایید شده فقط می توانند از سیاست آخرین شناخته شده کوتاه مدت استفاده کنند زمانی که مدل ریسک آنها اجازه می دهد. ثبت کنید که کدام نسخه سیاست و مسیر شکست تصمیم گرفته است، سپس نتیجه پس از بازگشت را تأیید کنید.
یک نقطه پایان POST
HTTP Streamable مدرن هر پیام JSON-RPC را از طریق POST ارسال می کند:
textPOST /mcp
Authorization: Bearer <gateway-token>
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: notes.search
Accept: application/json, text/event-streamدروازه می تواند JSON یا درخواست-اسکاپ SSE را برای آن پست بازگردانید. GET و DELETE برای درخواست های مدرن 405 را بازگردانید. Mcp-Session-IdوLast-Event-IDایجاد اقتدار، علاقه یا تکرار رفتار نکنید.
ارزش های سر و بدن باید با هم موافق باشند.-32020این اجازه می دهد تا متوازن کننده های بار، دروازه ها و محدودیات سرعت بدون تجزیه و تحلیل کل بدن در حالی که حفظ یکپارچگی پایان به پایان.
تایید در یک ترتیب دقیق: JSON-RPC و انواع متاداتا، برابر عنوان و بدن، سپس پشتیبانی از نسخه مطابقت پذیر. یک عدم مطابقت HTTP 400 را با -32020اگر عنوان و بدن در یک نسخه غیر پشتیبانی شده توافق کنند، HTTP 400 را با -32022وdataدقیقاً{"supported":["2026-07-28"],"requested":"<actual>"}. یک روش ناشناخته HTTP 404 را با -32601. .
ProtocolErrorاختیاری حمل می کندdata، و دروازه آن را به عنوان یک سریال به JSON-RPC خطا اعتراض.id، بنابراین هیچ گاه موفقیت یا خطا JSON-RPC دریافت نمی کند. یک اطلاعیه HTTP پذیرفته شده با یک جسم خالی 202 را باز می آورد.
انجام کشف در هر لایه
دروازه اجرا می شودserver/discoverهمچنین هر backend را کشف می کند تا نسخه های پروتکل، قابلیت ها و افزونه ها را بشناسد.
مثال نتیجه گیتوی:
json{
"resultType": "complete",
"supportedVersions": ["2026-07-28"],
"capabilities": {
"tools": {"listChanged": true}
},
"ttlMs": 30000,
"cacheScope": "private",
"_meta": {
"io.modelcontextprotocol/serverInfo": {
"name": "enterprise-gateway",
"version": "2.0.0"
}
}
}فقط به وسیله ی قابلیت های متقابل که دروازه می تواند از پایان به آخر احترام بگذارد تبلیغ کنید. یک ویژگی پس از پایان به طور خودکار برای افشا کردن ایمن نیست. یک ویژگی دروازه بدون مسیر پس از پایان برای تبلیغ مفید نیست.
serverInfoداده های خود گزارش شده نمایش و تشخیصی است. از آن به عنوان ثبت یا اثبات ناشر استفاده نکنید.
قابلیت های هر درخواست مشتری
هر درخواست ارسال شده به یک درخواست فعلی نیاز داره_metaپاکت:
json{
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": {
"name": "enterprise-gateway",
"version": "1.0.0"
}
}قابلیت های مشتری خارجی را به صورت کور به یک backend کپی نکنید. دروازه مشتری backend است. فقط تبلیغات ویژگی های دروازه به درستی میانجی خواهد شد.
فاصله نام های تعیین کننده
ابزار های پس زمینه را تحت نام های عمومی پایدار ادغام کنید:
textnotes.search
notes.create
issues.list
issues.openیک نقشه از نام عمومی به نام پشتیبان و ابزار اصلی نگه دارید. هرگز اولین یا آخرین برخورد را انتخاب نکنید. یک نام عمومی بخشی از قرارداد تأیید و حسابرسی است، بنابراین تغییر آن یک مهاجرت است.
tools/listباید تعیین کننده باشد. وقتی دید با اصل متفاوت باشد، بازگشتcacheScope: private. یک محدودttlMsکاهش بار کشف پس از پایان بدون اجازه دادن به لیستی مخصوص کاربر برای لیک در زمینه های مجوز.
هر توصیف کننده ابزار در معرض قرار داده شده شامل یک نام ثابت، توصیف و ریشه شی است inputSchema. نام گذاری نمی تواند زمینه های مورد نیاز توصیف کننده را حذف کند. نتیجه لیست کامل شامل resultType، متاداتا هویت سرور و اشاره های کش
توصیفات تایید شده از پن
در زمان پذیرش، توضیحات کامل را به عنوان یک کتاب مقدس تبدیل کنید و هضم آن را تحت نام عمومی واجد شرایط ذخیره کنید. در زمان لیست و تماس، هضم زنده را با هضم تایید شده مقایسه کنید.
اگر تغییر کند:
- ازش بردار
tools/list. . - تماس های مستقیم رو رد کن
- یک رویداد حسابرسی را منتشر کنید.
- قبل از بروزرسانی پین، نیاز به تایید مجدد سیاست یا انسانی داشته باشد.
یک دروازه یک نقطه اجرای مرکزی مفید است، اما یک توصیف کننده را که برای اولین بار دیده می شود به یک توصیف کننده امن تبدیل نمی کند. بازبینی اولیه همچنان ضروری است.
ثبت نامه ها کمک می کنند تا کشف کنند نه تصمیم بگیرند
یک دفتر ثبتserver.jsonیک رکورد با حمایت بسته می تواند به این شکل باشد:
json{
"$schema": "https: TOK0
"name": "com.example/notes",
"description": "Example notes MCP server.",
"version": "1.0.0",
"packages": [
{
"registryType": "npm",
"identifier": "@example/notes-mcp",
"version": "1.0.0",
"transport": {"type": "stdio"}
}
]
}متاداتا انتشار تصمیم امنیتی دروازه را ندارد. مدارک معتبر ناشر و منبع را در حالت پذیرش جداگانه نگه دارید:
json{
"registryName": "com.example/notes",
"registryVersion": "1.0.0",
"publisher": {"namespace": "com.example", "status": "verified"},
"provenance": {
"source": "registry.modelcontextprotocol.io",
"recordId": "com.example/notes@1.0.0"
},
"admission": {"status": "approved", "reviewedBy": "gateway-policy"}
}دروازه ها کنترل ميکننserver.jsonدروازه هنوز به یک سیاست پذیرش نیاز دارد.
برای هر پسدیدی که قبول شده است، ثبت کنید:
- شماره ثبت و شناسه دقیق
- فضای نام ناشر تایید شده یا شواهد دامنه.
- اجازه حمل و نقل و نقطه ی آخر
- نسخه ی پینی شده یا سیاست های ارتقاء تایید شده
- هضم اثر هنری یا توصیف کننده
- صادر کننده مجوز و منبع
- بازرس، زمان تایید و انقضاء
سرور را قبول نکنید زیرا نام نمایش آن به یک محصول آشنا شباهت دارد. حضور در ثبت نام را به عنوان بررسی امنیتی عملیاتی نگاه نکنید. سرورهای خصوصی می توانند از طریق همان طرح شواهد حتی اگر هرگز در یک ثبت نام عمومی ظاهر نشود، پذیرفته شوند.
این درس به دنبال راه حل است: شواهد انتشار را با پذیرش محلی قبل از اینکه یک پس زمینه قابل راه اندازی شود، ترکیب کنید. Lesson 30: MCP Registry Supply Chain, Admission, Drift, and Rollbackسطح کنترل کامل را برای اثبات دقیق فضای نام، اصل اثاثه، پین های بی تغییر، حرکت توصیف زنده، هماهنگی وضعیت ثبت نام، یک دفترچه پذیرش آشکار و پشتيبانی بر شواهد ایجاد می کند. این وضعیت زنجیره تامین را از تصمیم زمان اجرا در هر درخواست فوق جدا نگه دارید.
واسطه ی اعتبار
دروازه تماس گیرنده ها را تأیید می کند و به طور جداگانه به پس زمینه ها تأیید می کند. اعتبار پس زمینه هرگز به مشتری نمی رود.
این تعهدات را واضح نگه دارید:
textouter principal -> gateway role and policy
backend issuer + resource -> backend registration and tokenهرگز توکن دروازه خارجی را به یک backend منتقل نکنید. هرگز توکن backend را در یک صادر کننده یا منبع مختلف مجددا استفاده نکنید. اگر یک ابزار به نمایندگی از یک کاربر نهایی عمل کند، این نمایندگی را با یک مدل مبادله یا ادعای طراحی شده حفظ کنید تا به جای تظاهر به کاربر با اعتبارنامه سرویس مشترک.
محدودیت نرخ بدون جلسات
محدودیت های کلیدی توسط اصلی معتبر، صادر کننده، منبع، ابزار عمومی، کلاس هزینه و پنجره زمان. یک شناسه جلسه از بین رفته است و حتی اگر وجود داشته باشد، به راحتی قابل چرخش است.
قبل از مصرف کار گران قیمت، تایید ارزان قیمت را اجرا کنید. تصمیم بگیرید که آیا تماس های رد شده با محدودیت های سوء استفاده، کوتاهای تجاری یا هر دو مورد حساب می شوند.
حسابرسی زنجیره تصمیم گیری
به اندازه کافی ضبط کنید تا تماس رو بازسازی کنید:
- شناسه های درخواست و ردیابی
- سرمایه گذاری و صادر کننده معتبر
- ابزار عمومی و مسیر پشت سرانه
- نسخه ی پین توصيف کننده
- تصمیم گیری سیاسی و دلیل
- کلاس تاخیر و نتیجه
- در صورت لزوم، شناسایی دور MRTR یا وظیفه.
توکن های حامل نسخه جدید، کد مجوز، توکن های تازه، راز خام و استدلال های حساس غیر ضروری.
SSE در مقیاس درخواست
یک POST عادی ممکن است SSE درخواست-سکوپ را در هنگام جریان کاری در طول آن یک درخواست بازگرداند. بسته شدن جریان پاسخ درخواست HTTP مدرن در پرواز را لغو می کند.
یک جریان GET جداگانه ایجاد نکنید و وعده بازی مجدد آخرین رویداد را ندهید. این فرضیه های قدیمی تر حمل و نقل است.
اطلاعیه های تغییر طولانی مدت
برای اطلاعیه های تغییر لیست و منابع، یک مشتری فعلی ارسال می کند subscriptions/listenفیلترهای اطلاع رسانی از زمینه های صاف دقیق استفاده می کنند toolsListChanged،promptsListChanged،resourcesListChangedوresourceSubscriptions:
json{
"jsonrpc": "2.0",
"id": "listen-tools",
"method": "subscriptions/listen",
"params": {
"notifications": {
"toolsListChanged": true
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}اولین رویداد زیر مجموعه پشتیبانی شده را تأیید می کند. شناسه اشتراک آن ID JSON-RPC درخواست است که جریان را باز کرد:
json{
"jsonrpc": "2.0",
"method": "notifications/subscriptions/acknowledged",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": "listen-tools"
},
"notifications": {
"toolsListChanged": true
}
}
}دروازه بعد فقط انواع تغییر پذیرفته شده را ارسال می کند. هر اطلاعیه در آن جریان دارای همان است io.modelcontextprotocol/subscriptionIdدرparams._meta. هیچ بازخورد اتوماتیک و یا دوباره شنیدن اتوماتیک وجود ندارد. در اتصال مجدد، مشتری اشتراک را باز می کند و لیست هایی را که به آن وابسته است، تازه می کند. یک بسته بندی خوش خوری که توسط سرور آغاز می شود، یک نتیجه کامل نهایی را با همان شناسه اشتراک نشان می دهد.
راه مدرن جایگزینش می کنهresources/subscribe،resources/unsubscribeو بدون درخواست پخش مستقل GET. فقط این ها را در مسیر قدیمی تر نگه دارید.
MRTR از طریق یک دروازه
وقتی یه backend برگردهresultType: input_required، دروازه می تواند این نتیجه را فقط در صورتی ارسال کند که مشتری خارجی درخواست ورودی مورد نیاز را پشتیبانی کند.requestStateبایت به بایت مگر اینکه دروازه عمداً تعامل را متوقف و دوباره منتشر کند.
مشتری ابزار عمومی اصلی را با یک شناسه JSON-RPC تازه و inputResponsesدروازه دوباره مجوز امتحان، بررسی همان مسیر عمومی، سپس ارسال یک درخواست جدید پس از پایان. آن را نمی تواند فرض یک دور قبلی اعطا مجوز نامحدود.
راه اندازی وظایف تمدید
وظایف یک تمدید رسمی هستند که توسط io.modelcontextprotocol/tasksاونا جايگزين جلسه ي اصلي نيستن
مشتری در داخل قابلیت های مشتری در هر درخواست اعلام می کند و دروازه آن را در کشف تنها زمانی اعلام می کند که می تواند چرخه عمر را از پایان به آخر حفظ کند. برای یک پشتیبانی tools/call، تنها پس از پایان تصمیم می گیرد که آیا به بازگشت نتیجه عادی یاresultType: task. نتیجه ی یک کار به همراه داردtaskId،status، زمان نامه هاttlMs، و اختیاریpollIntervalMsاین کار باید قبل از ارسال این نتیجه قابل خواندن باشد.
دروازه ثبت شده اصلی و مسیر پشت سرانه برای شناسایی کار نامشفق است.tasks/get،tasks/updateوtasks/cancelتماس با استفادهparams.taskIdمثلMcp-Name، که به واسطه ها کلید رویت می دهد.tasks/getبازپرداختresultType: completeبا حالت کاری فعلی و خطای نهایی یا پروتکل را در حالت نهایی قرار می دهد. tasks/updateکلید می فرستدinputResponsesبرای ورودی مهم برجسته و بازگشت یک تایید کامل خالی. tasks/cancelاین یک هدف همکاری با یک تایید کامل خالی است، نه یک تضمین که کار متوقف می شود.
استفاده از برنامه های جدید را اجرا نکنیدtasks/listیاtasks/resultروش ها. آنها به مدل تجربی قدیمی تعلق دارند. یک کار که نیاز به ورودی دارد، درخواست های کامل درون ورودی را از طریق tasks/get؛ مشتری بهشون جواب ميدهtasks/update، نه با تکرار تماس ابزار اصلی. مشتری هنوز در فاصله پیشنهاد شده رای می دهد؛ ایجاد کار همچنان به سمت سرور هدایت می شود.
حالت مسیر کار پایدار داده های برنامه ای است که توسط دستی کار کلید داده شده است نه یک جلسه پروتکل.
مرز مطابقت
اگر دروازه باید به یک مشتری قدیمی تر یا backend خدمت کند:
- عصر رو به طور صریح تشخیص بده
- شروع کردن، جلسات حمل و نقل، جریان GET، اشتراک منابع و لغات کار قدیمی را در یک آداپتور قدیمی نگه دارید.
- هرگز یه اسم جلسه قدیمی رو به رویتینگ مدرن یا مجوز نخرید
- ترجیح میدم یک ساند کشف محدود و سیاست صریح عقب نشینی به جای کاهش صامت.
آن را بسازید
code/main.pyدر حال اجرا یک دروازه پروتکل در فرآیند و دو سرور پس از پایان. هر پس از پایان دریافت یک درخواست جدید از پروتکل فعلی. دروازه ارائه می دهد کشف، کاربر فیلتر تعیین کننده tools/list, مسیر نامي , ثبت نامserver.jsonعلاوه بر وضعیت پذیرش خارجی، پین های توصیف کننده، RBAC، محدودیت های نرخ کلیدی اصلی، تصمیمات حسابرسی و یک مدل سازی subscriptions/listenتایید SSE
این مدل دریافت اجسام درخواست تجزیه شده، سرنخ های مسیریابی و هویت معتبر حامل را دریافت می کند. این یک آداپتور HTTP کامل نیست و تجزیه و تحلیل نمی کند.Content-Typeیا کاملAcceptقرارداد. آن را به آداپتور HTTP Streamable درسی 09 متصل کنید، که نیاز داردContent-Type: application/jsonو یکAcceptارزش حاوی هر دوapplication/jsonوtext/event-stream. .
اجرا کن
bashcd phases/13-tools-and-protocols/17-mcp-gateways-and-registries
python3 code/main.py
python3 -m unittest discover code/tests -vدر دیمو، آدرس درخواست خارجی و آدرس درخواست پس زمینه جدید چاپ می شود تا هپ بدون دولت قابل مشاهده باشد.
ازش استفاده کن
اجزای پس زمینه در فرآیند را با مشتریان پروتکل فعلی واقعی جایگزین کنید. همان پیچ ها را حفظ کنید:
- سابقه ورود قبل از اتصال
- کشف پس زمینه قبل از افشا کردن قابلیت
- نام عمومی قبل از مجوز.
- قبل از لیست یا تماس، پین توصيف کننده را نشان دهید.
- متاداتا تازه در هر درخواست قبل از ارسال
- تایید نتیجه قبل از بازگشت
-باده
اين درس به ما ميگيرهoutputs/skill-gateway-bootstrap.md. این یک طراحی دروازه مدرن را تولید می کند که شامل ورود، کشف، پذیرش، نام فضا، مجوز، ذخیره سازی، جریان، اشتراک، MRTR، وظایف، مشاهده و انزوا میراث می باشد.
تمرینات
- به متادای درخواست خارجی و ارسال شده، زمینه ردیابی اضافه کنید و ارتباط را در رویداد حسابرسی ثبت کنید.
- اضافه کردن یک Backend و روت قابل انجام وظایف
tasks/getبا عنوان وظیفه درMcp-Name. . - یک توضیحات پس زمینه را تغییر دهید و ثابت کنید که کشف و تماس مستقیم مسدود شده است.
- قابلیت سرور خاص اصلی را اضافه کنید و توضیح دهید که چرا کشف باید به صورت خصوصی ذخیره شود.
- یک رابط آداپتور قدیمی را بدون اضافه کردن هیچ حالت قدیمی به حالت مدرن بنویسید
Gatewayکلاس
اصطلاحات کلیدی
| Term | Meaning |
|---|---|
| MCP gateway | Policy and routing server between clients and backend MCP servers |
| Admission record | Evidence and policy decision allowing one backend into the gateway |
| Qualified tool name | Stable public route such as notes.search |
| Descriptor pin | Approved digest checked during discovery and dispatch |
| Private cache scope | Cached result restricted to one authorization context |
| Request-scoped SSE | Streaming response attached to one POST request |
subscriptions/listen | Client-opened SSE stream for selected long-lived change notifications |
| Task route | Application mapping from an opaque task id to its backend |
| Legacy adapter | Explicit version-gated boundary for old handshake and session behavior |
خواندن بیشتر
- Streamable HTTP transport
- Server discovery
- Official Registry server.json requirements
- MCP Tasks extension
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.