Multi Round-Trip Requests چیست؟ معماری MRTR در MCP
Multi Round-Trip Requests یا MRTR الگوی جدید MCP برای اجرای تعاملهای چندمرحلهای است. در این راهنما با InputRequiredResult، inputRequests، requestState و اتصال این معماری به API درواره آشنا میشوید.
گاهی یک MCP Server نمیتواند درخواست کاربر را در همان مرحله اول تکمیل کند.
ممکن است Server برای ادامه کار به اطلاعات بیشتری نیاز داشته باشد:
- انتخاب مدل هوش مصنوعی
- مشخصکردن زبان خروجی
- دریافت تأیید کاربر
- انتخاب یکی از چند فایل
- تعیین قالب گزارش
- دریافت یک مقدار ضروری
- انتخاب سطح کیفیت یا سرعت
- تکمیل اطلاعات یک فرم
در نسخههای قبلی Model Context Protocol، Server میتوانست هنگام اجرای درخواست، یک پیام جدید برای Client ارسال کند و منتظر پاسخ بماند. این روش به یک کانال ارتباطی دوطرفه و معمولاً یک اتصال Stateful نیاز داشت.
اما در نسخه 2026-07-28 پروتکل MCP، معماری جدیدی به نام Multi Round-Trip Requests یا بهاختصار MRTR معرفی شد.
در MRTR، Server دیگر درخواست مستقلی برای Client ارسال نمیکند. در عوض، پاسخ میدهد که برای تکمیل عملیات به ورودی بیشتری نیاز دارد. Client اطلاعات لازم را جمعآوری میکند و درخواست اصلی را همراه پاسخهای جدید دوباره میفرستد.
این الگو یکی از تغییرات مهم معماری MCP برای ساخت Serverهای Remote، Stateless و مقیاسپذیر است.
MRTR چیست؟
MRTR مخفف Multi Round-Trip Requests است.
این الگو برای عملیاتهایی طراحی شده است که تکمیل آنها به بیش از یک رفتوبرگشت میان Client و Server نیاز دارد.
در یک Request و Response معمولی، جریان کار به این صورت است:
- Client درخواست را ارسال میکند.
- Server درخواست را پردازش میکند.
- Server نتیجه نهایی را برمیگرداند.
اما در MRTR، جریان کار چندمرحلهای است:
- Client درخواست اولیه را ارسال میکند.
- Server تشخیص میدهد اطلاعات کافی نیست.
- Server یک
InputRequiredResultبرمیگرداند. - Client ورودی لازم را از کاربر یا منبع دیگری دریافت میکند.
- Client درخواست اصلی را همراه
inputResponsesدوباره ارسال میکند. - Server درخواست جدید را پردازش میکند.
- اگر اطلاعات کافی باشد، نتیجه نهایی برگردانده میشود.
- اگر اطلاعات کافی نباشد، یک مرحله MRTR دیگر آغاز میشود.
بنابراین MRTR یک نوع Session مخفی یا اتصال دائمی نیست. هر مرحله یک درخواست مستقل است که اطلاعات موردنیاز خود را همراه دارد.
چرا MRTR به MCP اضافه شد؟
نسخه جدید MCP بر Stateless بودن تأکید دارد.
در معماری Stateless، Server نباید برای پردازش یک درخواست به حافظه اتصال قبلی یا یک Instance خاص وابسته باشد. هر درخواست باید بتواند به هر Instance سالمی از Server ارسال شود.
این ویژگی برای زیرساختهای Production اهمیت زیادی دارد؛ زیرا MCP Server ممکن است پشت این اجزا اجرا شود:
- Load Balancer
- Reverse Proxy
- Containerهای متعدد
- Serverless Function
- Kubernetes
- چند Region متفاوت
- سامانه Auto Scaling
در معماری قدیمی، Server ممکن بود هنگام پردازش درخواست، یک پیام جدید برای Client بفرستد و همان اتصال را باز نگه دارد. این رفتار اجرای Stateless را پیچیده میکرد.
MRTR این وابستگی را حذف میکند. Server بهجای آغاز یک درخواست جدید، اطلاعات موردنیاز را در پاسخ خود اعلام میکند.
Client سپس درخواست اصلی را از ابتدا و با ورودی تکمیلی Retry میکند.
تفاوت MRTR با Retry معمولی
در نگاه اول ممکن است MRTR شبیه Retry کردن یک درخواست ناموفق به نظر برسد، اما این دو مفهوم متفاوتاند.
Retry معمولاً زمانی انجام میشود که یک درخواست به دلایلی مانند خطای شبکه، Timeout یا خطای موقت Provider تکمیل نشده باشد.
اما MRTR یک جریان کنترلشده در سطح Protocol است. درخواست اول شکست نخورده است؛ بلکه Server بهصورت معتبر اعلام کرده که برای ادامه به ورودی بیشتری نیاز دارد.
| معیار | Retry معمولی | MRTR |
|---|---|---|
| علت تکرار | خطا یا عدم دریافت پاسخ | نیاز به اطلاعات تکمیلی |
| نتیجه درخواست اول | معمولاً ناموفق | input_required |
| ورودی جدید | معمولاً ندارد | در inputResponses ارسال میشود |
| وضعیت مرحله قبل | معمولاً بازسازی نمیشود | با requestState قابلانتقال است |
| نقش کاربر | معمولاً ندارد | ممکن است ورودی یا تأیید ارائه کند |
| کاربرد | پایداری ارتباط | Workflow چندمرحلهای |
اجزای اصلی MRTR
الگوی MRTR بر چند ساختار اصلی استوار است.
InputRequiredResult
اگر Server برای ادامه عملیات به اطلاعات بیشتری نیاز داشته باشد، بهجای نتیجه نهایی یک پاسخ با مقدار زیر برمیگرداند:
{
"resultType": "input_required"
}این پاسخ به Client میگوید عملیات هنوز کامل نشده و باید درخواستهای موجود در inputRequests را پردازش کند.
inputRequests
فیلد inputRequests شامل یک یا چند ورودی موردنیاز Server است.
هر ورودی یک شناسه دارد:
{
"inputRequests": {
"select_model": {
"method": "elicitation/create",
"params": {}
}
}
}شناسه select_model توسط Server تعیین شده است. Client باید نتیجه مربوط به همین درخواست را با همان شناسه در inputResponses برگرداند.
یک پاسخ میتواند چند درخواست ورودی داشته باشد:
{
"inputRequests": {
"select_model": {},
"select_language": {},
"confirm_generation": {}
}
}در این حالت Client میتواند ورودیهای موردنیاز را جمعآوری و در Retry بعدی ارسال کند.
inputResponses
پس از جمعآوری اطلاعات، Client درخواست اصلی را دوباره ارسال میکند و پاسخها را داخل inputResponses قرار میدهد:
{
"inputResponses": {
"select_model": {
"action": "accept",
"content": {
"model": "selected-model-id"
}
}
}
}کلیدهای inputResponses باید با کلیدهای تعریفشده در inputRequests مطابقت داشته باشند.
requestState
Server میتواند یک مقدار اختیاری به نام requestState برگرداند:
{
"requestState": "opaque-state-value"
}این مقدار وضعیت لازم برای ادامه عملیات را میان دو درخواست منتقل میکند.
Client نباید محتوای requestState را تغییر دهد یا براساس ساختار داخلی آن تصمیم بگیرد. این مقدار برای Client یک داده Opaque محسوب میشود و باید بدون تغییر در Retry بعدی به Server بازگردانده شود.
{
"requestState": "opaque-state-value"
}Server میتواند اطلاعاتی مانند این موارد را در State قرار دهد:
- مرحله فعلی Workflow
- شناسه عملیات
- اطلاعات موقت پردازش
- انتخابهای قبلی
- مرجع داده بازیابیشده
- نسخه Workflow
- زمان ایجاد درخواست
نباید API Key، اطلاعات حساس یا دادهای که Client مجاز به مشاهده آن نیست، بهصورت خوانا در requestState قرار گیرد.
نمونه کامل یک جریان MRTR
فرض کنید یک MCP Tool برای تولید خلاصه سند داریم. کاربر سند را ارسال کرده، اما Model ID را مشخص نکرده است.
Client ابتدا Tool را فراخوانی میکند:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "summarize_document",
"arguments": {
"document": "متن سند..."
}
}
}Server تشخیص میدهد که مدل انتخاب نشده است:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "input_required",
"inputRequests": {
"model_selection": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "مدل یا نوع پردازش موردنظر را انتخاب کنید.",
"requestedSchema": {
"type": "object",
"properties": {
"processing_mode": {
"type": "string",
"enum": [
"fast",
"balanced",
"high_quality"
]
}
},
"required": [
"processing_mode"
]
}
}
}
},
"requestState": "opaque-state-value"
}
}Client فرم مناسب را به کاربر نمایش میدهد. فرض کنیم کاربر گزینه balanced را انتخاب میکند.
Client درخواست اصلی را با یک JSON-RPC ID جدید تکرار میکند:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "summarize_document",
"arguments": {
"document": "متن سند..."
},
"inputResponses": {
"model_selection": {
"action": "accept",
"content": {
"processing_mode": "balanced"
}
}
},
"requestState": "opaque-state-value"
}
}Server این بار اطلاعات کافی دارد. براساس حالت انتخابشده، Model ID مناسب را تعیین و API مدل را فراخوانی میکند.
نتیجه نهایی:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"content": [
{
"type": "text",
"text": "خلاصه سند در این بخش قرار میگیرد."
}
],
"isError": false
}
}نکته مهم این است که درخواست دوم باید JSON-RPC ID متفاوتی داشته باشد؛ زیرا Retry یک درخواست جدید محسوب میشود.
ارتباط MRTR با Elicitation
Elicitation قابلیتی در MCP است که به Server اجازه میدهد اطلاعات یا تأیید موردنیاز را از کاربر دریافت کند.
MRTR و Elicitation یک مفهوم نیستند.
- Elicitation مشخص میکند چه اطلاعاتی باید از کاربر دریافت شود.
- MRTR مشخص میکند این درخواست و پاسخ چگونه میان Server و Client جابهجا شوند.
در نسخه جدید MCP، Server درخواست Elicitation را مستقیماً روی یک کانال باز برای Client ارسال نمیکند. آن را داخل inputRequests قرار میدهد.
Client ورودی کاربر را دریافت میکند و نتیجه را در inputResponses درخواست بعدی قرار میدهد.
بنابراین MRTR لایه انتقال تعامل چندمرحلهای است و Elicitation یکی از قابلیتهایی است که میتواند روی این الگو اجرا شود.
ارتباط MRTR با Sampling
Sampling در نسخههای قبلی به Server اجازه میداد از مدل تحت کنترل Client درخواست تولید پاسخ کند.
در نسخه 2026-07-28، قابلیت Sampling در وضعیت Deprecated قرار گرفته و مسیر پیشنهادی برای پروژههای جدید، اتصال مستقیم MCP Server به LLM Provider API است.
بااینحال، ساختار MRTR همچنان میتواند درخواستهای مربوط به sampling/createMessage را در قالب inputRequests حمل کند؛ اما این موضوع به معنی توصیه به استفاده از Sampling در پروژههای جدید نیست.
برای معماری جدید بهتر است:
- از MRTR برای دریافت انتخاب یا تأیید کاربر استفاده کنید.
- پس از تکمیل ورودیها، مدل را مستقیماً از MCP Server فراخوانی کنید.
- برای اتصال به مدلهای مختلف از یک LLM API مستقل مانند API درواره استفاده کنید.
ارتباط MRTR با MCP Tasks
MCP Tasks برای عملیات طولانی یا قابلپیگیری طراحی شده است. یک Task میتواند وضعیت اجرای یک درخواست را در طول زمان نگه دارد و امکان Polling یا دریافت نتیجه در آینده را فراهم کند.
MRTR هدف دیگری دارد: دریافت اطلاعات تکمیلی پیش از ادامه عملیات.
| قابلیت | کاربرد اصلی |
|---|---|
| MRTR | دریافت ورودی لازم برای ادامه درخواست |
| Elicitation | دریافت اطلاعات یا تأیید از کاربر |
| Tasks | اجرای عملیات طولانی و دریافت نتیجه در آینده |
| Sampling | درخواست اجرای مدل توسط Client؛ اکنون Deprecated |
| LLM API مستقیم | اجرای مدل توسط MCP Server |
یک Workflow میتواند همزمان از MRTR و Tasks استفاده کند.
برای مثال:
- Server با MRTR نوع گزارش را از کاربر میپرسد.
- Client پاسخ را ارسال میکند.
- Server یک Task طولانی برای تحلیل اسناد میسازد.
- Task از API درواره برای اجرای مدل استفاده میکند.
- Client وضعیت Task را پیگیری میکند.
- نتیجه نهایی پس از اتمام پردازش دریافت میشود.
استفاده از MRTR همراه API درواره
یکی از کاربردهای عملی MRTR این است که قبل از فراخوانی مدل، ترجیحات کاربر را دریافت کنید.
برای مثال، Tool تولید محتوا ممکن است به این اطلاعات نیاز داشته باشد:
- نوع محتوا
- زبان خروجی
- لحن متن
- اندازه پاسخ
- اولویت سرعت یا کیفیت
پس از دریافت این اطلاعات، MCP Server میتواند Model ID مناسب را انتخاب و درخواست را از طریق API درواره اجرا کند.
Base URL رسمی API درواره:
https://api.darvareh.ir/v1برای مشاهده Model IDهای فعال باید به صفحه مدلهای درواره مراجعه کنید.
ساخت لایه انتخاب مدل
بهتر است گزینهای مانند «سریع» یا «باکیفیت» از کاربر دریافت شود، نه نام داخلی Provider یا اطلاعات فنی زیرساخت.
سپس Server گزینه کاربر را به Model ID مناسب نگاشت کند:
import os
MODEL_ROUTES = {
"fast": os.environ["FAST_MODEL_ID"],
"balanced": os.environ["BALANCED_MODEL_ID"],
"high_quality": os.environ["QUALITY_MODEL_ID"],
}
def resolve_model(processing_mode: str) -> str:
model = MODEL_ROUTES.get(processing_mode)
if not model:
raise ValueError("Unsupported processing mode")
return modelاین روش چند مزیت دارد:
- Model ID بدون تغییر رابط Tool قابلتعویض است.
- کاربر با جزئیات Provider درگیر نمیشود.
- میتوان مدلهای مختلف را قبل از انتشار آزمایش کرد.
- Routing در اختیار Backend باقی میماند.
- تغییر موجودی مدلها Workflow را خراب نمیکند.
اتصال به API درواره
برای فراخوانی مدل میتوان از OpenAI SDK استفاده کرد:
import os
from openai import AsyncOpenAI
client = AsyncOpenAI(
api_key=os.environ["DARVAREH_API_KEY"],
base_url="https://api.darvareh.ir/v1",
)تابع تولید خلاصه:
async def summarize_document(
document: str,
processing_mode: str,
) -> str:
model_id = resolve_model(processing_mode)
response = await client.chat.completions.create(
model=model_id,
messages=[
{
"role": "system",
"content": (
"شما یک دستیار حرفهای برای خلاصهسازی اسناد هستید. "
"فقط براساس متن ارائهشده پاسخ دهید."
),
},
{
"role": "user",
"content": document,
},
],
temperature=0.2,
)
content = response.choices[0].message.content
if not content:
raise RuntimeError("The model returned an empty response.")
return contentمنطق کامل Tool بهصورت مفهومی چنین خواهد بود:
async def handle_summarize_tool(params: dict) -> dict:
arguments = params.get("arguments", {})
input_responses = params.get("inputResponses", {})
document = arguments.get("document")
model_response = input_responses.get("model_selection")
if not model_response:
return {
"resultType": "input_required",
"inputRequests": {
"model_selection": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "نوع پردازش را انتخاب کنید.",
"requestedSchema": {
"type": "object",
"properties": {
"processing_mode": {
"type": "string",
"enum": [
"fast",
"balanced",
"high_quality",
],
}
},
"required": ["processing_mode"],
},
},
}
},
"requestState": create_request_state(),
}
if model_response.get("action") != "accept":
return {
"resultType": "complete",
"content": [
{
"type": "text",
"text": "انتخاب نوع پردازش لغو شد.",
}
],
"isError": False,
}
processing_mode = model_response["content"]["processing_mode"]
summary = await summarize_document(
document=document,
processing_mode=processing_mode,
)
return {
"resultType": "complete",
"content": [
{
"type": "text",
"text": summary,
}
],
"isError": False,
}این نمونه Framework-independent است و مفهوم اصلی MRTR را نمایش میدهد. نام کلاسها و Helperها ممکن است براساس نسخه Python یا TypeScript SDK متفاوت باشند.
معماری پیشنهادی برای Production
برای پروژه واقعی بهتر است اجزای MRTR را از منطق Tool جدا کنید:
MCP Tool Handler
↓
Input Requirement Service
↓
Workflow State Service
↓
Application Service
↓
Model Router
↓
API دروارهMCP Tool Handler
وظایف این بخش:
- دریافت درخواست
- اعتبارسنجی ساختار ورودی
- تشخیص درخواست اولیه یا Retry
- برگرداندن
input_requiredیاcomplete
Input Requirement Service
وظایف این بخش:
- تعریف ورودیهای موردنیاز
- ساخت JSON Schema
- پردازش
inputResponses - تشخیص Accept، Decline یا Cancel
Workflow State Service
وظایف این بخش:
- ایجاد
requestState - اعتبارسنجی State بازگشتی
- تشخیص انقضای State
- جلوگیری از تداخل نسخههای مختلف Workflow
Model Router
وظایف این بخش:
- انتخاب Model ID
- انتخاب مدل براساس سرعت یا کیفیت
- اعمال محدودیت هزینه
- مدیریت Fallback
- ارسال درخواست به API درواره
این تفکیک باعث میشود تغییر SDK یا ساختار MCP کمترین اثر را بر منطق اصلی محصول داشته باشد.
مدیریت action در پاسخ Elicitation
Client همیشه اطلاعات درخواستشده را تأیید نمیکند. پاسخ میتواند وضعیتهای متفاوتی داشته باشد:
acceptdeclinecancel
Server باید هر سه حالت را مدیریت کند.
def read_elicitation_response(response: dict) -> dict | None:
action = response.get("action")
if action == "accept":
return response.get("content", {})
if action == "decline":
return None
if action == "cancel":
return None
raise ValueError("Unknown elicitation action")نادیدهگرفتن decline یا cancel میتواند باعث شود Workflow در حلقه درخواست مجدد قرار گیرد.
چند ورودی در یک مرحله
MRTR اجازه میدهد Server چند درخواست را در یک پاسخ قرار دهد.
برای مثال، Server میتواند همزمان این اطلاعات را بخواهد:
{
"inputRequests": {
"output_preferences": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "تنظیمات خروجی را مشخص کنید.",
"requestedSchema": {
"type": "object",
"properties": {
"language": {
"type": "string",
"enum": ["fa", "en"]
},
"processing_mode": {
"type": "string",
"enum": ["fast", "balanced", "high_quality"]
},
"output_type": {
"type": "string",
"enum": ["summary", "report", "bullet_points"]
}
},
"required": [
"language",
"processing_mode",
"output_type"
]
}
}
}
}
}جمعآوری اطلاعات مرتبط در یک فرم میتواند تعداد رفتوبرگشتها را کاهش دهد.
بااینحال، نباید فرم بسیار بزرگی ایجاد کرد. فقط اطلاعاتی را درخواست کنید که برای اجرای همان مرحله ضروری هستند.
MRTR و Stateless بودن
Stateless بودن به معنی نداشتن هیچ نوع State در کل برنامه نیست. منظور این است که Server نباید وضعیت درخواست را از اتصال شبکه یا Instance قبلی استنتاج کند.
اگر اطلاعاتی باید میان دو مرحله باقی بماند، باید بهصورت صریح منتقل یا با یک شناسه مشخص بازیابی شود.
روشهای رایج عبارتاند از:
- قرار دادن State محدود در
requestState - ذخیره State در Database و ارسال شناسه آن
- استفاده از Cache اشتراکی
- ذخیره Workflow در یک سیستم Task
- بازسازی اطلاعات از آرگومانهای درخواست
در هر روش، درخواست دوم باید بتواند روی Instance دیگری پردازش شود.
آیا نتیجه input_required قابل Cache است؟
خیر. براساس Specification نسخه ۲۰۲۶، پاسخهای دارای:
{
"resultType": "input_required"
}نباید Cache شوند.
همچنین نتیجه درخواستهایی که شامل inputResponses یا requestState هستند نباید Cache شود؛ زیرا به ورودیهای تعاملی وابستهاند.
در مقابل، بعضی پاسخهای کامل مانند tools/list، resources/list و resources/read میتوانند دارای اطلاعات TTL و Cache Scope باشند.
خطاهای متداول در پیادهسازی MRTR
استفاده مجدد از JSON-RPC ID
درخواست Retry باید ID جدیدی داشته باشد. درخواست دوم ادامه همان پیام JSON-RPC نیست؛ یک درخواست جدید با اطلاعات تکمیلی است.
ذخیره State در حافظه یک Server
اگر State فقط در حافظه یک Process نگهداری شود، درخواست دوم ممکن است به Instance دیگری برسد و اطلاعات لازم را پیدا نکند.
تغییر requestState در Client
Client باید requestState را بهصورت Opaque در نظر بگیرد و همان مقدار دریافتی را برگرداند.
تکرار بیپایان input_required
Server باید تعداد مراحل Workflow را محدود کند. اگر ورودی معتبر دریافت نشد، بهتر است خطای مشخص یا نتیجه کنترلشده برگردانده شود.
درخواست اطلاعات غیرضروری
هر مرحله اضافی باعث افزایش Latency و پیچیدگی تجربه کاربر میشود. اطلاعاتی را که Server میتواند از تنظیمات، Context یا مقدار پیشفرض به دست آورد، دوباره از کاربر نپرسید.
وابستگی مستقیم Tool به Model ID
Tool بهتر است «حالت پردازش» را دریافت کند و Model Router شناسه واقعی مدل را تعیین کند.
فراخوانی مدل قبل از تکمیل ورودیها
تا زمانی که اطلاعات ضروری دریافت نشدهاند، نباید API مدل فراخوانی شود. در غیر این صورت ممکن است یک درخواست پرهزینه اجرا و سپس بهدلیل نبود اطلاعات کنار گذاشته شود.
چه زمانی از MRTR استفاده کنیم؟
MRTR برای این سناریوها مناسب است:
- Tool بدون انتخاب کاربر قابلاجرا نیست.
- عملیات به تأیید صریح نیاز دارد.
- Server باید یک فرم کوتاه نمایش دهد.
- کاربر باید یکی از چند گزینه را انتخاب کند.
- اطلاعات لازم هنگام درخواست اول موجود نیست.
- Workflow چند مرحله مشخص دارد.
- Server باید بدون اتصال Stateful اجرا شود.
چه زمانی MRTR مناسب نیست؟
در این شرایط معمولاً به MRTR نیاز ندارید:
- تمام ورودیها در آرگومان Tool موجودند.
- مقدار پیشفرض قابلاعتماد وجود دارد.
- Server میتواند اطلاعات را از Resource یا Database دریافت کند.
- عملیات فقط زمان زیادی نیاز دارد؛ در این حالت MCP Tasks مناسبتر است.
- مشکل صرفاً Timeout یا خطای موقت Provider است؛ در این حالت Retry معمولی لازم است.
- ورودی از مدل زبانی لازم است؛ در معماری جدید بهتر است Server مستقیماً LLM API را فراخوانی کند.
چکلیست پیادهسازی MRTR
پیش از استقرار یک Workflow مبتنی بر MRTR این موارد را بررسی کنید:
- ورودی موردنیاز واقعاً برای ادامه عملیات ضروری باشد.
- پاسخ
input_requiredساختار معتبر داشته باشد. - کلیدهای
inputRequestsیکتا باشند. - Client از قابلیت موردنیاز پشتیبانی کند.
inputResponsesاعتبارسنجی شود.- حالتهای Accept، Decline و Cancel مدیریت شوند.
- درخواست Retry دارای JSON-RPC ID جدید باشد.
requestStateقابلاعتماد و دارای زمان انقضا باشد.- Server به حافظه یک Instance وابسته نباشد.
- تعداد Round Tripها محدود شود.
- پاسخهای تعاملی Cache نشوند.
- API مدل فقط پس از تکمیل اطلاعات فراخوانی شود.
- Model ID در Environment Variable یا تنظیمات مرکزی قرار گیرد.
- Timeout و مدیریت خطای API درواره پیادهسازی شود.
- Workflow با چند Instance از MCP Server آزمایش شود.
جمعبندی
Multi Round-Trip Requests یا MRTR الگوی جدید MCP برای اجرای درخواستهایی است که به اطلاعات تکمیلی از Client یا کاربر نیاز دارند.
در این معماری:
- Client درخواست اولیه را ارسال میکند.
- Server یک
InputRequiredResultبرمیگرداند. - ورودیهای لازم در
inputRequestsقرار میگیرند. - Client اطلاعات را جمعآوری میکند.
- درخواست اصلی همراه
inputResponsesوrequestStateتکرار میشود. - Server نتیجه نهایی را برمیگرداند.
MRTR جایگزین معماری قدیمی Server-initiated Requests شده و امکان ساخت MCP Serverهای Stateless و مناسب زیرساختهای Remote را فراهم میکند.
در یک معماری AI Agent میتوان از MRTR برای انتخاب نوع پردازش، دریافت تنظیمات خروجی یا تأیید کاربر استفاده کرد. پس از تکمیل ورودیها، MCP Server میتواند مدل مناسب را انتخاب و مستقیماً از طریق API درواره اجرا کند.
این تفکیک باعث میشود:
- تعامل کاربر توسط MCP مدیریت شود.
- انتخاب مدل در اختیار Backend باقی بماند.
- Server به Client یا اتصال خاصی وابسته نباشد.
- زیرساخت روی چند Instance مقیاسپذیر باشد.
- مصرف و خطاهای LLM API قابلکنترلتر شوند.
برای شروع، در درواره حساب بسازید، API Key دریافت کنید و Model ID مناسب را از صفحه مدلها انتخاب کنید.
پرسشهای متداول
MRTR در MCP چیست؟
MRTR الگویی برای درخواستهای چندمرحلهای است. اگر Server به اطلاعات بیشتری نیاز داشته باشد، پاسخ input_required برمیگرداند و Client درخواست را همراه اطلاعات تکمیلی دوباره ارسال میکند.
آیا MRTR به اتصال دائمی نیاز دارد؟
خیر. MRTR برای معماری Stateless طراحی شده و هر مرحله آن یک درخواست مستقل محسوب میشود.
InputRequiredResult چیست؟
پاسخی است که نشان میدهد عملیات هنوز کامل نشده و Server برای ادامه به یک یا چند ورودی نیاز دارد.
requestState چه کاربردی دارد؟
requestState اطلاعات لازم برای ادامه Workflow را میان درخواست اولیه و Retry منتقل میکند. Client باید آن را بدون تغییر به Server بازگرداند.
تفاوت MRTR و Elicitation چیست؟
Elicitation روش تعریف اطلاعاتی است که باید از کاربر دریافت شود. MRTR الگوی انتقال این درخواست و پاسخ میان Client و Server است.
تفاوت MRTR و MCP Tasks چیست؟
MRTR برای دریافت ورودی تکمیلی استفاده میشود. MCP Tasks برای عملیات طولانی، Polling و دریافت نتیجه در آینده طراحی شده است.
آیا MRTR جایگزین Sampling است؟
MRTR روش حمل تعاملهای چندمرحلهای است؛ اما مسیر رسمی مهاجرت از Sampling، اتصال مستقیم MCP Server به LLM Provider API است.
آیا میتوان پس از MRTR از API درواره استفاده کرد؟
بله. Server میتواند ابتدا با MRTR تنظیمات یا انتخاب کاربر را دریافت کند و سپس مدل مناسب را از طریق API سازگار با OpenAI درواره فراخوانی کند.
مقالات مرتبط
- MCP Elicitation چیست؟ دریافت ورودی کاربر در AI Agent
- آموزش MCP در OpenCode؛ اتصال Agent به ابزارها
- PydanticAI چیست؟ آموزش ساخت AI Agent با پایتون و API درواره
- Instructor چیست؟ آموزش Structured Output با Python و API درواره
- آموزش اتصال API درواره به Dify و Flowise
منابع اصلی
- مستندات رسمی Multi Round-Trip Requests
- Message Patterns در MCP
- تغییرات نسخه ۲۰۲۶-۰۷-۲۸ پروتکل MCP
- مستندات رسمی MCP Tools
- مستندات Streamable HTTP در MCP
این مقاله صرفاً با هدف آموزش و اطلاعرسانی تهیه شده است. پیش از استفاده عملی، مستندات رسمی سرویسها و صفحه سلب مسئولیت را مطالعه کنید.