diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index ad743416550..fe95360352e 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -872,10 +872,15 @@ class MCPServerManager: if toolset_id is None: keys_to_remove = [k for k in cache_dict if k.startswith("toolset_")] else: + # Evict permission-cache entries that reference this toolset ID. + # Also evict ALL name-cache entries (toolset_name:*): we can't map + # toolset_id → toolset_name without a DB call, and the name may have + # changed in an update anyway. keys_to_remove = [ k for k in cache_dict - if k.startswith("toolset_") and toolset_id in k + if (k.startswith("toolset_perms:") and toolset_id in k) + or k.startswith("toolset_name:") ] for k in keys_to_remove: cache_dict.pop(k, None) diff --git a/litellm/proxy/_experimental/mcp_server/toolset_db.py b/litellm/proxy/_experimental/mcp_server/toolset_db.py index 2d22b52e331..72cb5eb98e4 100644 --- a/litellm/proxy/_experimental/mcp_server/toolset_db.py +++ b/litellm/proxy/_experimental/mcp_server/toolset_db.py @@ -59,7 +59,7 @@ async def list_mcp_toolsets( rows = await prisma_client.db.litellm_mcptoolsettable.find_many(where=where) return [_toolset_from_row(r) for r in rows] except Exception as e: - verbose_proxy_logger.debug( + verbose_proxy_logger.warning( "litellm.proxy._experimental.mcp_server.toolset_db::list_mcp_toolsets - {}".format( str(e) ) diff --git a/litellm/proxy/management_endpoints/mcp_management_endpoints.py b/litellm/proxy/management_endpoints/mcp_management_endpoints.py index 1b59f573383..0ab35604ee1 100644 --- a/litellm/proxy/management_endpoints/mcp_management_endpoints.py +++ b/litellm/proxy/management_endpoints/mcp_management_endpoints.py @@ -2164,7 +2164,19 @@ if MCP_AVAILABLE: touched_by = ( litellm_changed_by or user_api_key_dict.user_id or LITELLM_PROXY_ADMIN_NAME ) - result = await update_mcp_toolset(prisma_client, payload, touched_by) + try: + result = await update_mcp_toolset(prisma_client, payload, touched_by) + except UniqueViolationError: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, + detail={ + "error": ( + f"A toolset named '{payload.toolset_name}' already exists." + if payload.toolset_name + else "A toolset with that name already exists." + ) + }, + ) if result is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND,