diff --git a/src/Microsoft.Agents.A365.DevTools.Cli/Commands/DevelopMcpCommand.cs b/src/Microsoft.Agents.A365.DevTools.Cli/Commands/DevelopMcpCommand.cs index b5d7f916..3695ff7e 100644 --- a/src/Microsoft.Agents.A365.DevTools.Cli/Commands/DevelopMcpCommand.cs +++ b/src/Microsoft.Agents.A365.DevTools.Cli/Commands/DevelopMcpCommand.cs @@ -850,9 +850,6 @@ private static Command CreateRegisterExternalMcpServerSubcommand( var serviceTreeIdOption = new Option("--service-tree-id", description: "ServiceTree ID for Entra app registration (required in Microsoft corporate tenants)"); command.AddOption(serviceTreeIdOption); - var configOption = new Option(["-c", "--config"], getDefaultValue: () => "a365.config.json", description: "Configuration file path"); - command.AddOption(configOption); - var publisherOption = new Option("--publisher", description: "Publisher name (required, used in MOS package metadata)"); command.AddOption(publisherOption); diff --git a/src/Microsoft.Agents.A365.DevTools.Cli/Commands/RegisterCommandExecutor.cs b/src/Microsoft.Agents.A365.DevTools.Cli/Commands/RegisterCommandExecutor.cs index 59cf8d16..dacfc8a1 100644 --- a/src/Microsoft.Agents.A365.DevTools.Cli/Commands/RegisterCommandExecutor.cs +++ b/src/Microsoft.Agents.A365.DevTools.Cli/Commands/RegisterCommandExecutor.cs @@ -150,8 +150,25 @@ internal async Task ExecuteAsync(RawRegisterArgs args) if (addResponse is null || !addResponse.IsSuccess) { var errorMsg = addResponse?.Message ?? "No response received"; - _logger.LogError("Failed to add MCP server {ServerName}: {Error}", input.ServerName, errorMsg); + + if (errorMsg.Contains("violates a database constraint", StringComparison.OrdinalIgnoreCase) + || errorMsg.Contains("delete the existing record", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine(); + var prevColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"ERROR: A server named '{input.ServerName}' already exists. Please choose a different name."); + Console.ForegroundColor = prevColor; + _logger.LogError("A server named '{ServerName}' already exists. Please choose a different name.", input.ServerName); + _logger.LogDebug("Raw server error: {Error}", errorMsg); + } + else + { + _logger.LogError("Failed to add MCP server {ServerName}: {Error}", input.ServerName, errorMsg); + } + _logger.LogWarning("Entra app registrations were NOT rolled back. Delete them manually in the Azure portal if needed."); + Console.WriteLine($"Entra app registrations were NOT rolled back. Delete them manually in the Azure portal if needed."); return; } @@ -617,7 +634,7 @@ private void DisplayRegistrationSummary(ResolvedInput input) var copilotRedirectUri = $"ms-appx-web://Microsoft.AAD.BrokerPlugin/{publicClientsClientId}"; try { - await _graphApiService.UpdateAppPublicClientRedirectUrisAsync(tenantId, publicClientsObjectId, new[] { copilotRedirectUri, "http://localhost:8080/callback" }); + await _graphApiService.UpdateAppPublicClientRedirectUrisAsync(tenantId, publicClientsObjectId, new[] { copilotRedirectUri, "http://localhost:8080/callback", "https://vscode.dev/redirect", "http://localhost" }); _logger.LogDebug("Set redirect URI on '{AppName}' ({ObjectId}): {Uri}", publicClientsAppName, publicClientsObjectId, copilotRedirectUri); } catch (Exception ex) diff --git a/src/Microsoft.Agents.A365.DevTools.Cli/Services/Agent365ToolingService.cs b/src/Microsoft.Agents.A365.DevTools.Cli/Services/Agent365ToolingService.cs index 462b6606..374357e9 100644 --- a/src/Microsoft.Agents.A365.DevTools.Cli/Services/Agent365ToolingService.cs +++ b/src/Microsoft.Agents.A365.DevTools.Cli/Services/Agent365ToolingService.cs @@ -97,10 +97,10 @@ public Agent365ToolingService( errorMessage += $" - {statusResponse.Error}"; } - _logger.LogError("{Operation} failed: {Message}", operationName, errorMessage); + _logger.LogDebug("{Operation} failed: {Message}", operationName, errorMessage); if (!string.IsNullOrWhiteSpace(serverCorrelationId)) { - _logger.LogError("Server correlation ID (x-ms-correlation-id): {CorrelationId}", serverCorrelationId); + _logger.LogWarning("Server correlation ID (x-ms-correlation-id): {CorrelationId}", serverCorrelationId); } return (false, responseContent); } diff --git a/src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/DevelopMcpCommandTests.cs b/src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/DevelopMcpCommandTests.cs index 7980cd6a..9e1d2416 100644 --- a/src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/DevelopMcpCommandTests.cs +++ b/src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/DevelopMcpCommandTests.cs @@ -249,20 +249,6 @@ public void AllSubcommands_SupportDryRunOption() } } - [Theory] - [InlineData("register-external-mcp-server")] - public void ConfigDependentSubcommands_SupportConfigOption(string subcommandName) - { - // Act - var command = DevelopMcpCommand.CreateCommand(_mockLogger, _mockToolingService); - var subcommand = command.Subcommands.First(sc => sc.Name == subcommandName); - - // Assert - var configOption = subcommand.Options.FirstOrDefault(o => o.Name == "config"); - configOption.Should().NotBeNull($"Subcommand '{subcommandName}' should have --config option"); - configOption!.Aliases.Should().Contain("-c", $"Config option should have -c alias in '{subcommandName}'"); - } - [Fact] public void RegisterExternalMcpServerSubcommand_HasAllExpectedOptions() { @@ -291,11 +277,11 @@ public void RegisterExternalMcpServerSubcommand_HasAllExpectedOptions() optionNames.Should().Contain("remote-scopes"); optionNames.Should().Contain("tenant-id"); optionNames.Should().Contain("service-tree-id"); - optionNames.Should().Contain("config"); optionNames.Should().Contain("publisher"); optionNames.Should().Contain("description"); optionNames.Should().Contain("dry-run"); optionNames.Should().Contain("verbose"); + optionNames.Should().NotContain("config"); // Verify critical aliases var serverNameOption = options.First(o => o.Name == "server-name"); @@ -314,9 +300,6 @@ public void RegisterExternalMcpServerSubcommand_HasAllExpectedOptions() var tenantIdOption = options.First(o => o.Name == "tenant-id"); tenantIdOption.Aliases.Should().Contain("-t"); - var configOption = options.First(o => o.Name == "config"); - configOption.Aliases.Should().Contain("-c"); - var verboseOption = options.First(o => o.Name == "verbose"); verboseOption.Aliases.Should().Contain("-v"); }