From 18f197763bb3adbbe0d79ac4290d87cbaacc231f Mon Sep 17 00:00:00 2001 From: Omar Abdelwahab Date: Wed, 12 Nov 2025 16:17:53 -0800 Subject: [PATCH] fix(tool-runtime): Remove authorization from list_runtime_tools() The authorization parameter should only be on invoke_tool(), not on list_runtime_tools(). Tool listing typically doesn't require authentication, and the client SDK doesn't have this parameter yet. Changes: 1. Removed authorization parameter from ToolRuntime.list_runtime_tools() protocol method 2. Updated all implementations to remove the authorization parameter: - MCPProviderImpl.list_runtime_tools() - ToolRuntimeRouter.list_runtime_tools() - ToolGroupsRoutingTable.list_tools() and _index_tools() 3. Updated test to remove authorization from list_tools() call This ensures compatibility with the llama-stack-client SDK which doesn't support authorization on list_tools() yet. Only invoke_tool() requires and accepts the authorization parameter for authenticated tool execution. --- src/llama_stack/apis/tools/tools.py | 2 -- src/llama_stack/core/routers/tool_runtime.py | 5 ++--- src/llama_stack/core/routing_tables/toolgroups.py | 8 ++++---- .../model_context_protocol/model_context_protocol.py | 5 ++--- tests/integration/inference/test_tools_with_schemas.py | 1 - 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/llama_stack/apis/tools/tools.py b/src/llama_stack/apis/tools/tools.py index 06580dc74..de39a4294 100644 --- a/src/llama_stack/apis/tools/tools.py +++ b/src/llama_stack/apis/tools/tools.py @@ -199,13 +199,11 @@ class ToolRuntime(Protocol): self, tool_group_id: str | None = None, mcp_endpoint: URL | None = None, - authorization: str | None = None, ) -> ListToolDefsResponse: """List all tools in the runtime. :param tool_group_id: The ID of the tool group to list tools for. :param mcp_endpoint: The MCP endpoint to use for the tool group. - :param authorization: (Optional) OAuth access token for authenticating with the MCP server. :returns: A ListToolDefsResponse. """ ... diff --git a/src/llama_stack/core/routers/tool_runtime.py b/src/llama_stack/core/routers/tool_runtime.py index fe170eeb7..cd690985e 100644 --- a/src/llama_stack/core/routers/tool_runtime.py +++ b/src/llama_stack/core/routers/tool_runtime.py @@ -46,7 +46,6 @@ class ToolRuntimeRouter(ToolRuntime): ) async def list_runtime_tools( - self, tool_group_id: str | None = None, mcp_endpoint: URL | None = None, authorization: str | None = None + self, tool_group_id: str | None = None, mcp_endpoint: URL | None = None ) -> ListToolDefsResponse: - logger.debug(f"ToolRuntimeRouter.list_runtime_tools: {tool_group_id}") - return await self.routing_table.list_tools(tool_group_id, authorization=authorization) + return await self.routing_table.list_tools(tool_group_id) diff --git a/src/llama_stack/core/routing_tables/toolgroups.py b/src/llama_stack/core/routing_tables/toolgroups.py index 0761c5582..573c3444d 100644 --- a/src/llama_stack/core/routing_tables/toolgroups.py +++ b/src/llama_stack/core/routing_tables/toolgroups.py @@ -43,7 +43,7 @@ class ToolGroupsRoutingTable(CommonRoutingTableImpl, ToolGroups): routing_key = self.tool_to_toolgroup[routing_key] return await super().get_provider_impl(routing_key, provider_id) - async def list_tools(self, toolgroup_id: str | None = None, authorization: str | None = None) -> ListToolDefsResponse: + async def list_tools(self, toolgroup_id: str | None = None) -> ListToolDefsResponse: if toolgroup_id: if group_id := parse_toolgroup_from_toolgroup_name_pair(toolgroup_id): toolgroup_id = group_id @@ -55,7 +55,7 @@ class ToolGroupsRoutingTable(CommonRoutingTableImpl, ToolGroups): for toolgroup in toolgroups: if toolgroup.identifier not in self.toolgroups_to_tools: try: - await self._index_tools(toolgroup, authorization=authorization) + await self._index_tools(toolgroup) except AuthenticationRequiredError: # Send authentication errors back to the client so it knows # that it needs to supply credentials for remote MCP servers. @@ -70,10 +70,10 @@ class ToolGroupsRoutingTable(CommonRoutingTableImpl, ToolGroups): return ListToolDefsResponse(data=all_tools) - async def _index_tools(self, toolgroup: ToolGroup, authorization: str | None = None): + async def _index_tools(self, toolgroup: ToolGroup): provider_impl = await super().get_provider_impl(toolgroup.identifier, toolgroup.provider_id) tooldefs_response = await provider_impl.list_runtime_tools( - toolgroup.identifier, toolgroup.mcp_endpoint, authorization=authorization + toolgroup.identifier, toolgroup.mcp_endpoint ) tooldefs = tooldefs_response.data diff --git a/src/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py b/src/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py index 137effb33..4035df5c1 100644 --- a/src/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py +++ b/src/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py @@ -44,15 +44,14 @@ class ModelContextProtocolToolRuntimeImpl( self, tool_group_id: str | None = None, mcp_endpoint: URL | None = None, - authorization: str | None = None, ) -> ListToolDefsResponse: # this endpoint should be retrieved by getting the tool group right? if mcp_endpoint is None: raise ValueError("mcp_endpoint is required") - # Authorization now comes from request body parameter (not provider-data) + # MCP tool listing typically doesn't require authorization headers = {} return await list_mcp_tools( - endpoint=mcp_endpoint.uri, headers=headers, authorization=authorization + endpoint=mcp_endpoint.uri, headers=headers, authorization=None ) async def invoke_tool( diff --git a/tests/integration/inference/test_tools_with_schemas.py b/tests/integration/inference/test_tools_with_schemas.py index f6f15c0be..9f5cecbff 100644 --- a/tests/integration/inference/test_tools_with_schemas.py +++ b/tests/integration/inference/test_tools_with_schemas.py @@ -196,7 +196,6 @@ class TestMCPToolsInChatCompletion: # Get the tools from MCP tools_response = llama_stack_client.tool_runtime.list_tools( tool_group_id=test_toolgroup_id, - authorization=AUTH_TOKEN, ) # Convert to OpenAI format for inference