@@ -238,6 +238,52 @@ async def exchange_authorization_code(
238
238
scope = " " .join (authorization_code .scopes ),
239
239
)
240
240
241
+ async def exchange_client_credentials (self , client : OAuthClientInformationFull , scopes : list [str ]) -> OAuthToken :
242
+ """Exchange client credentials for an MCP access token."""
243
+ mcp_token = f"mcp_{ secrets .token_hex (32 )} "
244
+ self .tokens [mcp_token ] = AccessToken (
245
+ token = mcp_token ,
246
+ client_id = client .client_id ,
247
+ scopes = scopes ,
248
+ expires_at = int (time .time ()) + 3600 ,
249
+ )
250
+ return OAuthToken (
251
+ access_token = mcp_token ,
252
+ token_type = "Bearer" ,
253
+ expires_in = 3600 ,
254
+ scope = " " .join (scopes ),
255
+ )
256
+
257
+ async def exchange_token (
258
+ self ,
259
+ client : OAuthClientInformationFull ,
260
+ subject_token : str ,
261
+ subject_token_type : str ,
262
+ actor_token : str | None ,
263
+ actor_token_type : str | None ,
264
+ scope : list [str ] | None ,
265
+ audience : str | None ,
266
+ resource : str | None ,
267
+ ) -> OAuthToken :
268
+ """Exchange an external token for an MCP access token."""
269
+ if not subject_token :
270
+ raise ValueError ("Invalid subject token" )
271
+
272
+ mcp_token = f"mcp_{ secrets .token_hex (32 )} "
273
+ self .tokens [mcp_token ] = AccessToken (
274
+ token = mcp_token ,
275
+ client_id = client .client_id ,
276
+ scopes = scope or [self .settings .mcp_scope ],
277
+ expires_at = int (time .time ()) + 3600 ,
278
+ resource = resource ,
279
+ )
280
+ return OAuthToken (
281
+ access_token = mcp_token ,
282
+ token_type = "Bearer" ,
283
+ expires_in = 3600 ,
284
+ scope = " " .join (scope or [self .settings .mcp_scope ]),
285
+ )
286
+
241
287
async def load_access_token (self , token : str ) -> AccessToken | None :
242
288
"""Load and validate an access token."""
243
289
access_token = self .tokens .get (token )
0 commit comments