88 * @module
99 */
1010
11- import type { FetchLike } from '@modelcontextprotocol/core' ;
12- import { IdJagTokenExchangeResponseSchema , OAuthErrorResponseSchema , OAuthTokensSchema } from '@modelcontextprotocol/core' ;
11+ import type { FetchLike , OAuthTokens } from '@modelcontextprotocol/core' ;
12+ import { IdJagTokenExchangeResponseSchema , OAuthTokensSchema } from '@modelcontextprotocol/core' ;
1313
1414import type { ClientAuthMethod } from './auth.js' ;
15- import { applyClientAuthentication , discoverAuthorizationServerMetadata } from './auth.js' ;
15+ import { applyClientAuthentication , discoverAuthorizationServerMetadata , parseErrorResponse } from './auth.js' ;
1616
1717/**
1818 * Options for requesting a JWT Authorization Grant via RFC 8693 Token Exchange.
@@ -104,7 +104,7 @@ export interface JwtAuthGrantResult {
104104 *
105105 * @param options - Configuration for the token exchange request
106106 * @returns The JWT Authorization Grant and related metadata
107- * @throws {Error } If the token exchange fails or returns an error response
107+ * @throws {OAuthError } If the token exchange fails or returns an error response
108108 *
109109 * @example
110110 * ```ts
@@ -154,16 +154,7 @@ export async function requestJwtAuthorizationGrant(options: RequestJwtAuthGrantO
154154 } ) ;
155155
156156 if ( ! response . ok ) {
157- const errorBody = await response . json ( ) . catch ( ( ) => ( { } ) ) ;
158-
159- // Try to parse as OAuth error response
160- const parseResult = OAuthErrorResponseSchema . safeParse ( errorBody ) ;
161- if ( parseResult . success ) {
162- const { error, error_description } = parseResult . data ;
163- throw new Error ( `Token exchange failed: ${ error } ${ error_description ? ` - ${ error_description } ` : '' } ` ) ;
164- }
165-
166- throw new Error ( `Token exchange failed with status ${ response . status } : ${ JSON . stringify ( errorBody ) } ` ) ;
157+ throw await parseErrorResponse ( response ) ;
167158 }
168159
169160 const parseResult = IdJagTokenExchangeResponseSchema . safeParse ( await response . json ( ) ) ;
@@ -186,7 +177,7 @@ export async function requestJwtAuthorizationGrant(options: RequestJwtAuthGrantO
186177 *
187178 * @param options - Configuration including IdP URL for discovery
188179 * @returns The JWT Authorization Grant and related metadata
189- * @throws {Error } If discovery fails or the token exchange fails
180+ * @throws {OAuthError } If the token exchange fails or returns an error response
190181 *
191182 * @example
192183 * ```ts
@@ -226,7 +217,7 @@ export async function discoverAndRequestJwtAuthGrant(options: DiscoverAndRequest
226217 *
227218 * @param options - Configuration for the JWT grant exchange
228219 * @returns OAuth tokens (access token, token type, etc.)
229- * @throws {Error } If the exchange fails or returns an error response
220+ * @throws {OAuthError } If the exchange fails or returns an error response
230221 *
231222 * Defaults to `client_secret_basic` (HTTP Basic Authorization header), matching
232223 * `CrossAppAccessProvider`'s declared `token_endpoint_auth_method` and the
@@ -257,7 +248,7 @@ export async function exchangeJwtAuthGrant(options: {
257248 */
258249 authMethod ?: ClientAuthMethod ;
259250 fetchFn ?: FetchLike ;
260- } ) : Promise < { access_token : string ; token_type : string ; expires_in ?: number ; scope ?: string } > {
251+ } ) : Promise < OAuthTokens > {
261252 const { tokenEndpoint, jwtAuthGrant, clientId, clientSecret, authMethod = 'client_secret_basic' , fetchFn = fetch } = options ;
262253
263254 // Prepare JWT bearer grant request per RFC 7523
@@ -279,16 +270,7 @@ export async function exchangeJwtAuthGrant(options: {
279270 } ) ;
280271
281272 if ( ! response . ok ) {
282- const errorBody = await response . json ( ) . catch ( ( ) => ( { } ) ) ;
283-
284- // Try to parse as OAuth error response
285- const parseResult = OAuthErrorResponseSchema . safeParse ( errorBody ) ;
286- if ( parseResult . success ) {
287- const { error, error_description } = parseResult . data ;
288- throw new Error ( `JWT grant exchange failed: ${ error } ${ error_description ? ` - ${ error_description } ` : '' } ` ) ;
289- }
290-
291- throw new Error ( `JWT grant exchange failed with status ${ response . status } : ${ JSON . stringify ( errorBody ) } ` ) ;
273+ throw await parseErrorResponse ( response ) ;
292274 }
293275
294276 const responseBody = await response . json ( ) ;
0 commit comments