@@ -193,7 +193,8 @@ export type ClientOptions = ProtocolOptions & {
193193
194194 /**
195195 * SEP-2322: maximum number of incomplete-result rounds before failing. Each round
196- * services the server's `inputRequests` via local handlers and re-sends with
196+ * services the server's `inputRequests` via local handlers (sampling, elicitation,
197+ * roots, ping only; other methods are rejected) and re-sends with
197198 * `params.{inputResponses, requestState}`. Prevents unbounded looping on a server
198199 * that returns `incomplete` forever.
199200 *
@@ -205,9 +206,18 @@ export type ClientOptions = ProtocolOptions & {
205206const DEFAULT_MRTR_MAX_ROUNDS = 16 ;
206207
207208/** SEP-2322 client-side detection. The server signals it cannot complete without client input. */
209+ /**
210+ * Methods the SEP-2322 retry loop will service from `inputRequests`. The server cannot
211+ * use this channel to invoke arbitrary client handlers (e.g. a custom-method handler the
212+ * application registered for unrelated purposes); only the spec-defined client-side
213+ * request methods are dispatched.
214+ */
215+ const ALLOWED_INPUT_REQUEST_METHODS : ReadonlySet < string > = new Set ( [ 'sampling/createMessage' , 'elicitation/create' , 'roots/list' , 'ping' ] ) ;
216+
208217function isIncompleteResult ( r : unknown ) : r is IncompleteResult {
209218 if ( typeof r !== 'object' || r === null ) return false ;
210219 const o = r as { resultType ?: unknown ; inputRequests ?: unknown } ;
220+ // (deliberately narrow guard; the loop body validates method against ALLOWED_INPUT_REQUEST_METHODS)
211221 if ( o . resultType !== 'incomplete' ) return false ;
212222 if ( o . inputRequests === undefined ) return true ;
213223 return typeof o . inputRequests === 'object' && o . inputRequests !== null && ! Array . isArray ( o . inputRequests ) ;
@@ -1159,6 +1169,12 @@ export class Client extends Protocol<ClientContext> {
11591169 const out : Record < string , unknown > = { } ;
11601170 for ( const [ key , ir ] of Object . entries ( reqs ) ) {
11611171 signal ?. throwIfAborted ( ) ;
1172+ if ( ! ALLOWED_INPUT_REQUEST_METHODS . has ( ir . method ) ) {
1173+ throw new ProtocolError (
1174+ ProtocolErrorCode . InvalidRequest ,
1175+ `inputRequest method '${ ir . method } ' is not a client-serviceable method`
1176+ ) ;
1177+ }
11621178 const resp = await this . _serviceInboundRequest (
11631179 { jsonrpc : '2.0' , id : `mrtr:${ key } ` , method : ir . method , params : ir . params } ,
11641180 signal
0 commit comments