Skip to content

Commit 03545dd

Browse files
committed
fix: update MCP tool discovery to handle token expiration during discovery loop
1 parent 7410a0d commit 03545dd

1 file changed

Lines changed: 28 additions & 43 deletions

File tree

src/sap_cloud_sdk/agentgateway/_customer.py

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,15 @@ async def get_mcp_tools_customer(
499499

500500
logger.info("Discovering tools from %d MCP server(s)", len(dependencies))
501501

502-
# Get system token for discovery
503-
loop = asyncio.get_running_loop()
504-
system_token = await loop.run_in_executor(
505-
None, get_system_token_mtls, credentials, timeout, config, cache, app_tid
506-
)
502+
system_token = None
503+
# Define a helper closure to refetch the system token on demand, since it may need to be
504+
# refreshed during the discovery loop if any server returns a 401
505+
async def refetch_system_token() -> str:
506+
loop = asyncio.get_running_loop()
507+
new_token = await loop.run_in_executor(
508+
None, get_system_token_mtls, credentials, timeout, config, cache, app_tid
509+
)
510+
return new_token
507511

508512
tools: list[MCPTool] = []
509513

@@ -516,47 +520,28 @@ async def get_mcp_tools_customer(
516520
dep.global_tenant_id,
517521
)
518522

519-
try:
520-
server_tools = await _list_server_tools(url, system_token, dep, timeout)
521-
tools.extend(server_tools)
522-
logger.debug("Loaded %d tool(s) from %s", len(server_tools), dep.ord_id)
523-
except Exception as exc:
524-
unwrapped = _unwrap_exception_group(exc)
525-
if _is_unauthorized(unwrapped):
526-
logger.info(
527-
"401 from %s — invalidating cached system token and retrying",
528-
dep.ord_id,
529-
)
530-
cache.invalidate_system_token(app_tid)
531-
try:
532-
fresh_token = await loop.run_in_executor(
533-
None,
534-
get_system_token_mtls,
535-
credentials,
536-
timeout,
537-
config,
538-
cache,
539-
app_tid,
540-
)
541-
server_tools = await _list_server_tools(
542-
url, fresh_token, dep, timeout
543-
)
544-
tools.extend(server_tools)
545-
# Replace stale token for remaining iterations
546-
system_token = fresh_token
547-
logger.debug(
548-
"Loaded %d tool(s) from %s after retry",
549-
len(server_tools),
550-
dep.ord_id,
551-
)
552-
continue
553-
except Exception:
554-
logger.exception(
555-
"Failed to load tools from %s after retry — skipping",
523+
while True:
524+
if not system_token:
525+
# won't catch exceptions here - if token acquisition fails,
526+
# we want the discovery to fail immediately
527+
system_token = await refetch_system_token()
528+
529+
try:
530+
server_tools = await _list_server_tools(url, system_token, dep, timeout)
531+
tools.extend(server_tools)
532+
logger.debug("Loaded %d tool(s) from %s", len(server_tools), dep.ord_id)
533+
except Exception as exc:
534+
unwrapped = _unwrap_exception_group(exc)
535+
if _is_unauthorized(unwrapped):
536+
logger.info(
537+
"401 from %s — invalidating cached system token and retrying",
556538
dep.ord_id,
557539
)
540+
cache.invalidate_system_token(app_tid)
541+
system_token = None # Force refetch on next loop iteration
558542
continue
559-
logger.exception("Failed to load tools from %s — skipping", dep.ord_id)
543+
logger.exception("Failed to load tools from %s — skipping", dep.ord_id)
544+
break # Success, move to next server
560545

561546
logger.info(
562547
"Loaded %d MCP tool(s) from %d server(s)", len(tools), len(dependencies)

0 commit comments

Comments
 (0)