|
22 | 22 | from pydantic import ValidationError |
23 | 23 | from sqlalchemy import and_, delete, desc, or_, select |
24 | 24 | from sqlalchemy.exc import IntegrityError, OperationalError |
25 | | -from sqlalchemy.orm import joinedload, selectinload, Session |
| 25 | +from sqlalchemy.orm import joinedload, selectinload, Session, with_loader_criteria |
26 | 26 |
|
27 | 27 | # First-Party |
28 | 28 | from mcpgateway.config import settings |
@@ -359,11 +359,12 @@ def convert_server_to_read(self, server: DbServer, include_metrics: bool = False |
359 | 359 | else: |
360 | 360 | server_dict["metrics"] = None |
361 | 361 | # Add associated IDs from relationships |
362 | | - server_dict["associated_tools"] = [tool.name for tool in server.tools] if server.tools else [] |
363 | | - server_dict["associated_tool_ids"] = [str(tool.id) for tool in server.tools] if server.tools else [] |
364 | | - server_dict["associated_resources"] = [res.id for res in server.resources] if server.resources else [] |
365 | | - server_dict["associated_prompts"] = [prompt.id for prompt in server.prompts] if server.prompts else [] |
366 | | - server_dict["associated_a2a_agents"] = [agent.id for agent in server.a2a_agents] if server.a2a_agents else [] |
| 362 | + # Filter out deactivated entities for consistent API responses |
| 363 | + server_dict["associated_tools"] = [tool.name for tool in server.tools if getattr(tool, "enabled", True)] if server.tools else [] |
| 364 | + server_dict["associated_tool_ids"] = [str(tool.id) for tool in server.tools if getattr(tool, "enabled", True)] if server.tools else [] |
| 365 | + server_dict["associated_resources"] = [res.id for res in server.resources if getattr(res, "enabled", True)] if server.resources else [] |
| 366 | + server_dict["associated_prompts"] = [prompt.id for prompt in server.prompts if getattr(prompt, "enabled", True)] if server.prompts else [] |
| 367 | + server_dict["associated_a2a_agents"] = [agent.id for agent in server.a2a_agents if getattr(agent, "enabled", True)] if server.a2a_agents else [] |
367 | 368 |
|
368 | 369 | # Team name is loaded via server.team property from email_team relationship |
369 | 370 | server_dict["team"] = getattr(server, "team", None) |
@@ -790,13 +791,18 @@ async def list_servers( |
790 | 791 | return (cached_servers, cached.get("next_cursor")) |
791 | 792 |
|
792 | 793 | # Build base query with ordering and eager load relationships to avoid N+1 |
| 794 | + # Filter out deactivated tools, resources, prompts, and agents at query level |
793 | 795 | query = ( |
794 | 796 | select(DbServer) |
795 | 797 | .options( |
796 | 798 | selectinload(DbServer.tools), |
| 799 | + with_loader_criteria(DbTool, DbTool.enabled.is_(True)), |
797 | 800 | selectinload(DbServer.resources), |
| 801 | + with_loader_criteria(DbResource, DbResource.enabled.is_(True)), |
798 | 802 | selectinload(DbServer.prompts), |
| 803 | + with_loader_criteria(DbPrompt, DbPrompt.enabled.is_(True)), |
799 | 804 | selectinload(DbServer.a2a_agents), |
| 805 | + with_loader_criteria(DbA2AAgent, DbA2AAgent.enabled.is_(True)), |
800 | 806 | joinedload(DbServer.email_team), |
801 | 807 | ) |
802 | 808 | .order_by(desc(DbServer.created_at), desc(DbServer.id)) |
@@ -903,11 +909,16 @@ async def list_servers_for_user( |
903 | 909 | team_ids = [team.id for team in user_teams] |
904 | 910 |
|
905 | 911 | # Eager load relationships to avoid N+1 queries |
| 912 | + # Filter out deactivated tools, resources, prompts, and agents at query level |
906 | 913 | query = select(DbServer).options( |
907 | 914 | selectinload(DbServer.tools), |
| 915 | + with_loader_criteria(DbTool, DbTool.enabled.is_(True)), |
908 | 916 | selectinload(DbServer.resources), |
| 917 | + with_loader_criteria(DbResource, DbResource.enabled.is_(True)), |
909 | 918 | selectinload(DbServer.prompts), |
| 919 | + with_loader_criteria(DbPrompt, DbPrompt.enabled.is_(True)), |
910 | 920 | selectinload(DbServer.a2a_agents), |
| 921 | + with_loader_criteria(DbA2AAgent, DbA2AAgent.enabled.is_(True)), |
911 | 922 | joinedload(DbServer.email_team), |
912 | 923 | ) |
913 | 924 |
|
@@ -994,9 +1005,13 @@ async def get_server(self, db: Session, server_id: str) -> ServerRead: |
994 | 1005 | select(DbServer) |
995 | 1006 | .options( |
996 | 1007 | selectinload(DbServer.tools), |
| 1008 | + with_loader_criteria(DbTool, DbTool.enabled.is_(True)), |
997 | 1009 | selectinload(DbServer.resources), |
| 1010 | + with_loader_criteria(DbResource, DbResource.enabled.is_(True)), |
998 | 1011 | selectinload(DbServer.prompts), |
| 1012 | + with_loader_criteria(DbPrompt, DbPrompt.enabled.is_(True)), |
999 | 1013 | selectinload(DbServer.a2a_agents), |
| 1014 | + with_loader_criteria(DbA2AAgent, DbA2AAgent.enabled.is_(True)), |
1000 | 1015 | joinedload(DbServer.email_team), |
1001 | 1016 | ) |
1002 | 1017 | .where(DbServer.id == server_id) |
|
0 commit comments