88- Tool invocation: mTLS + jwt-bearer grant → user-scoped token (principal propagation)
99"""
1010
11- import asyncio
1211import json
1312import logging
1413import os
@@ -432,17 +431,18 @@ async def _list_server_tools(
432431
433432async def get_mcp_tools_customer (
434433 credentials : CustomerCredentials ,
434+ system_token : str ,
435435 timeout : float ,
436- app_tid : str | None = None ,
437436) -> list [MCPTool ]:
438437 """List all MCP tools from servers defined in credentials.
439438
440439 Iterates over all integrationDependencies in the credentials file and
441- discovers tools from each MCP server using mTLS client credentials .
440+ discovers tools from each MCP server using a pre-fetched system token .
442441
443442 Args:
444443 credentials: Customer credentials with integrationDependencies.
445- app_tid: BTP Application Tenant ID of subscriber (optional).
444+ system_token: Pre-fetched raw system token for authentication.
445+ timeout: HTTP timeout in seconds for MCP server calls.
446446
447447 Returns:
448448 List of MCPTool objects from all servers.
@@ -459,12 +459,6 @@ async def get_mcp_tools_customer(
459459
460460 logger .info ("Discovering tools from %d MCP server(s)" , len (dependencies ))
461461
462- # Get system token for discovery
463- loop = asyncio .get_running_loop ()
464- system_token = await loop .run_in_executor (
465- None , get_system_token_mtls , credentials , timeout , app_tid
466- )
467-
468462 tools : list [MCPTool ] = []
469463
470464 for dep in dependencies :
@@ -490,53 +484,30 @@ async def get_mcp_tools_customer(
490484
491485
492486async def call_mcp_tool_customer (
493- credentials : CustomerCredentials ,
494487 tool : MCPTool ,
495- user_token : str | None ,
488+ auth_token : str ,
496489 timeout : float ,
497- app_tid : str | None = None ,
498490 ** kwargs ,
499491) -> str :
500492 """Invoke an MCP tool using customer flow.
501493
502- If user_token is provided, exchanges it for an AGW -scoped token to preserve
503- user identity for principal propagation. Otherwise, falls back to system token .
494+ Uses a pre-fetched token (either user-scoped or system -scoped) for
495+ authentication against the MCP server .
504496
505497 Args:
506- credentials: Customer credentials.
507498 tool: MCPTool to invoke.
508- user_token: User's JWT token for principal propagation (optional).
509- If None, system token is used instead (no principal propagation).
510- app_tid: BTP Application Tenant ID of subscriber (optional).
499+ auth_token: Pre-fetched raw access token for authentication.
500+ timeout: HTTP timeout in seconds for the MCP server call.
511501 **kwargs: Tool input parameters.
512502
513503 Returns:
514504 Tool execution result as string.
515505 """
516506 logger .info ("Calling tool '%s' on server '%s'" , tool .name , tool .server_name )
517507
518- loop = asyncio .get_running_loop ()
519-
520- if user_token :
521- # Exchange user token for AGW-scoped token (with principal propagation)
522- agw_token = await loop .run_in_executor (
523- None , exchange_user_token , credentials , user_token , timeout , app_tid
524- )
525- else :
526- # TODO: IBD workaround - use system token when user_token is not available.
527- # This bypasses principal propagation. Remove this fallback once IBD
528- # supports proper user token flow.
529- logger .warning (
530- "No user_token provided - using system token for tool invocation. "
531- "Principal propagation will NOT work."
532- )
533- agw_token = await loop .run_in_executor (
534- None , get_system_token_mtls , credentials , timeout , app_tid
535- )
536-
537508 async with httpx .AsyncClient (
538509 headers = {
539- "Authorization" : f"Bearer { agw_token } " ,
510+ "Authorization" : f"Bearer { auth_token } " ,
540511 "x-correlation-id" : str (uuid .uuid4 ()),
541512 },
542513 timeout = timeout ,
0 commit comments