@@ -202,7 +202,8 @@ export type ClientOptions = ProtocolOptions & {
202202
203203 /**
204204 * SEP-2322: maximum number of incomplete-result rounds before failing. Each round
205- * services the server's `inputRequests` via local handlers and re-sends with
205+ * services the server's `inputRequests` via local handlers (sampling, elicitation,
206+ * roots, ping only; other methods are rejected) and re-sends with
206207 * `params.{inputResponses, requestState}`. Prevents unbounded looping on a server
207208 * that returns `incomplete` forever.
208209 *
@@ -214,9 +215,18 @@ export type ClientOptions = ProtocolOptions & {
214215const DEFAULT_MRTR_MAX_ROUNDS = 16 ;
215216
216217/** SEP-2322 client-side detection. The server signals it cannot complete without client input. */
218+ /**
219+ * Methods the SEP-2322 retry loop will service from `inputRequests`. The server cannot
220+ * use this channel to invoke arbitrary client handlers (e.g. a custom-method handler the
221+ * application registered for unrelated purposes); only the spec-defined client-side
222+ * request methods are dispatched.
223+ */
224+ const ALLOWED_INPUT_REQUEST_METHODS : ReadonlySet < string > = new Set ( [ 'sampling/createMessage' , 'elicitation/create' , 'roots/list' , 'ping' ] ) ;
225+
217226function isIncompleteResult ( r : unknown ) : r is IncompleteResult {
218227 if ( typeof r !== 'object' || r === null ) return false ;
219228 const o = r as { resultType ?: unknown ; inputRequests ?: unknown } ;
229+ // (deliberately narrow guard; the loop body validates method against ALLOWED_INPUT_REQUEST_METHODS)
220230 if ( o . resultType !== 'incomplete' ) return false ;
221231 if ( o . inputRequests === undefined ) return true ;
222232 return typeof o . inputRequests === 'object' && o . inputRequests !== null && ! Array . isArray ( o . inputRequests ) ;
@@ -1176,6 +1186,12 @@ export class Client extends Protocol<ClientContext> {
11761186 const out : Record < string , unknown > = { } ;
11771187 for ( const [ key , ir ] of Object . entries ( reqs ) ) {
11781188 signal ?. throwIfAborted ( ) ;
1189+ if ( ! ALLOWED_INPUT_REQUEST_METHODS . has ( ir . method ) ) {
1190+ throw new ProtocolError (
1191+ ProtocolErrorCode . InvalidRequest ,
1192+ `inputRequest method '${ ir . method } ' is not a client-serviceable method`
1193+ ) ;
1194+ }
11791195 const resp = await this . _serviceInboundRequest (
11801196 { jsonrpc : '2.0' , id : `mrtr:${ key } ` , method : ir . method , params : ir . params } ,
11811197 signal
0 commit comments