From 64041e885f7eb0aad5db023d4868e153bfbb7459 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:29:36 +0800 Subject: [PATCH] fix(go-api): reject duplicated MCP server name on update (#17776) --- internal/service/mcp.go | 9 +++++++ internal/service/mcp_test.go | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/internal/service/mcp.go b/internal/service/mcp.go index f1c75b6be3..a28ca6e83d 100644 --- a/internal/service/mcp.go +++ b/internal/service/mcp.go @@ -316,6 +316,15 @@ func (s *MCPService) UpdateMCPServer(ctx context.Context, tenantID, mcpID string if serverName != "" && len([]byte(serverName)) > mcpServerNameLimit { return nil, common.CodeDataError, fmt.Errorf("Invalid MCP name or length is %d which is large than 255.", len([]byte(serverName))) } + if serverNameProvided && serverName != server.Name { + exists, err := s.mcpServerDAO.ExistsByNameAndTenant(ctx, dao.DB, serverName, tenantID) + if err != nil { + return nil, common.CodeServerError, err + } + if exists { + return nil, common.CodeDataError, errors.New("duplicated MCP server name") + } + } serverURL := server.URL serverURLProvided := false diff --git a/internal/service/mcp_test.go b/internal/service/mcp_test.go index b6135d4787..89a924c402 100644 --- a/internal/service/mcp_test.go +++ b/internal/service/mcp_test.go @@ -23,6 +23,7 @@ import ( "strings" "testing" + "ragflow/internal/common" "ragflow/internal/entity" ) @@ -39,6 +40,54 @@ func TestIsValidMCPServerType(t *testing.T) { } } +func TestUpdateMCPServerRejectsDuplicatedName(t *testing.T) { + testDB := setupServiceTestDB(t) + if err := testDB.AutoMigrate(&entity.MCPServer{}); err != nil { + t.Fatalf("migrate: %v", err) + } + pushServiceDB(t, testDB) + + const tenantID = "tenant-1" + for _, srv := range []*entity.MCPServer{ + {ID: "mcp-1", Name: "alpha", TenantID: tenantID, URL: "http://example.com/sse", ServerType: mcpServerTypeSSE}, + {ID: "mcp-2", Name: "beta", TenantID: tenantID, URL: "http://example.com/sse", ServerType: mcpServerTypeSSE}, + } { + if err := testDB.Create(srv).Error; err != nil { + t.Fatalf("create mcp server: %v", err) + } + } + + s := NewMCPService() + ctx := t.Context() + + nameReq := func(name string) UpdateMCPServerRequest { + raw, err := json.Marshal(name) + if err != nil { + t.Fatalf("marshal name: %v", err) + } + return UpdateMCPServerRequest{"name": raw} + } + + // Renaming to an existing server name of the same tenant is rejected. + if _, code, err := s.UpdateMCPServer(ctx, tenantID, "mcp-1", nameReq("beta")); err == nil || code != common.CodeDataError { + t.Errorf("expected duplicated name data error, got code=%v err=%v", code, err) + } + + // Keeping the current name is allowed. + if _, code, err := s.UpdateMCPServer(ctx, tenantID, "mcp-1", nameReq("alpha")); err != nil || code != common.CodeSuccess { + t.Errorf("expected success keeping current name, got code=%v err=%v", code, err) + } + + // Renaming to a fresh name is allowed. + updated, code, err := s.UpdateMCPServer(ctx, tenantID, "mcp-1", nameReq("gamma")) + if err != nil || code != common.CodeSuccess { + t.Fatalf("expected success renaming to fresh name, got code=%v err=%v", code, err) + } + if updated.Name != "gamma" { + t.Errorf("expected renamed server name %q, got %q", "gamma", updated.Name) + } +} + func TestServerInputValidation(t *testing.T) { s := &MCPService{}