feat: ensure unique connector names for MCP connectors

This commit is contained in:
Anish Sarkar 2026-03-18 16:09:35 +05:30
parent c343368456
commit 8baba0693d
2 changed files with 51 additions and 1 deletions

View file

@ -81,6 +81,7 @@ from app.utils.periodic_scheduler import (
delete_periodic_schedule,
update_periodic_schedule,
)
from app.utils.connector_naming import ensure_unique_connector_name
from app.utils.rbac import check_permission
# Set up logging
@ -189,6 +190,12 @@ async def create_search_source_connector(
# Prepare connector data
connector_data = connector.model_dump()
# MCP connectors support multiple instances — ensure unique name
if connector.connector_type == SearchSourceConnectorType.MCP_CONNECTOR:
connector_data["name"] = await ensure_unique_connector_name(
session, connector_data["name"], search_space_id, user.id
)
# Automatically set next_scheduled_at if periodic indexing is enabled
if (
connector.periodic_indexing_enabled
@ -2715,9 +2722,14 @@ async def create_mcp_connector(
"You don't have permission to create connectors in this search space",
)
# Ensure unique name across MCP connectors in this search space
unique_name = await ensure_unique_connector_name(
session, connector_data.name, search_space_id, user.id
)
# Create the connector with single server config
db_connector = SearchSourceConnector(
name=connector_data.name,
name=unique_name,
connector_type=SearchSourceConnectorType.MCP_CONNECTOR,
is_indexable=False, # MCP connectors are not indexable
config={"server_config": connector_data.server_config.model_dump()},

View file

@ -159,6 +159,44 @@ async def check_duplicate_connector(
return (result.scalar() or 0) > 0
async def ensure_unique_connector_name(
session: AsyncSession,
name: str,
search_space_id: int,
user_id: UUID,
) -> str:
"""
Ensure a connector name is unique within a user's search space.
If the name already exists, appends a counter suffix: (2), (3), etc.
Uses the same suffix format as generate_unique_connector_name.
Args:
session: Database session
name: Desired connector name
search_space_id: The search space ID
user_id: The user ID
Returns:
Unique name, either the original or with a counter suffix
"""
result = await session.execute(
select(SearchSourceConnector.name).where(
SearchSourceConnector.search_space_id == search_space_id,
SearchSourceConnector.user_id == user_id,
)
)
existing_names = {row[0] for row in result.all()}
if name not in existing_names:
return name
counter = 2
while f"{name} ({counter})" in existing_names:
counter += 1
return f"{name} ({counter})"
async def generate_unique_connector_name(
session: AsyncSession,
connector_type: SearchSourceConnectorType,