Ce face InputRequiredResult (Multi Round-Trip Requests)
Multi Round-Trip Requests (MRTR) a apărut în revizia 2026-07-28 și înlocuiește cererile trimise de server către client. Este o schimbare incompatibilă: serverul trebuie să ceară roots/list, sampling/createMessage sau elicitation/create prin acest mecanism. Fluxul: clientul trimite cererea; serverul răspunde cu un InputRequiredResult (resultType: "input_required"); clientul adună informația și retrimite cererea originală, cu un id nou, plus inputResponses și requestState; serverul întoarce rezultatul final.
Doar tools/call, resources/read și prompts/get pot primi InputRequiredResult. inputRequests este o hartă cu chei alese de server (unice în cerere) și valori de tip ElicitRequest, CreateMessageRequest sau ListRootsRequest; inputResponses folosește aceleași chei. Rezultatul conține cel puțin unul dintre inputRequests și requestState. Serverul nu cere tipuri de input pe care clientul nu le-a declarat în capabilități și nu presupune că clientul va reîncerca.
requestState este un șir opac: clientul îl trimite înapoi exact, fără să-l citească sau să-l modifice, și nu îl include dacă serverul nu l-a dat. Pentru server, este input controlat de atacator: dacă influențează autorizarea, accesul sau logica, trebuie protejat (HMAC sau AEAD), iar starea care nu trece verificarea se respinge. Specificația recomandă includerea principalului autentificat, a unei expirări scurte și a unui identificator al cererii originale; acestea nu garantează folosirea unică.
Sintaxă și opțiuni
| Opțiune / Parametru | Descriere |
|---|---|
resultType: "input_required" |
Marchează un rezultat intermediar. Nu se pune în cache. |
inputRequests |
Hartă cheie → cerere (elicitation/create, sampling/createMessage, roots/list). |
requestState |
Șir opac al serverului (de exemplu JSON în base64 sau un JWT criptat), returnat neschimbat la reîncercare. |
inputResponses |
În parametrii reîncercării: hartă cheie → rezultat (ElicitResult, CreateMessageResult, ListRootsResult). |
id nou |
Reîncercarea este o cerere independentă și trebuie să aibă alt id JSON-RPC. |
Exemple practice
Exemplul 1: Serverul cere numele de utilizator GitHub
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "input_required",
"inputRequests": {
"github_login": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Please provide your GitHub username",
"requestedSchema": {
"type": "object",
"properties": {
"name": { "type": "string" }
},
"required": ["name"]
}
}
}
},
"requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
}
}
Exemplul 2: Clientul reîncearcă cu răspunsul
Același name și aceleași arguments, alt id, plus inputResponses și requestState primit.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"location": "New York"
},
"inputResponses": {
"github_login": {
"action": "accept",
"content": {
"name": "octocat"
}
}
},
"requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
}
}
Greșeli frecvente și bune practici
- Reîncerci cu același
idJSON-RPC. Cererea inițială s-a încheiat; reîncercarea este o cerere nouă. - Folosești
inputRequestssaurequestStatepentru alte cereri trimise în paralel. Ele privesc doar reîncercarea cererii originale. - Răspunzi cu eroare când clientul n-a trimis toate răspunsurile necesare. Specificația recomandă un nou
InputRequiredResultcare cere din nou informația lipsă.