Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions core/Azure.Mcp.Core/src/Areas/Group/GroupSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var group = new CommandGroup(Name, "Resource group operations - Commands for listing and managing Azure resource groups and their resources in your subscriptions.", Title);

// Register Group commands
var listCommand = serviceProvider.GetRequiredService<GroupListCommand>();
group.AddCommand(listCommand.Name, listCommand);
group.AddCommand(serviceProvider.GetRequiredService<GroupListCommand>());

// Register Resource sub-group
var resource = new CommandGroup("resource", "Resource operations - Commands for listing resources within a resource group.");
group.AddSubGroup(resource);

var resourceListCommand = serviceProvider.GetRequiredService<ResourceListCommand>();
resource.AddCommand(resourceListCommand.Name, resourceListCommand);
resource.AddCommand(serviceProvider.GetRequiredService<ResourceListCommand>());

return group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var subscription = new CommandGroup(Name, "Azure subscription operations - Commands for listing and managing Azure subscriptions accessible to your account.", Title);

// Register Subscription commands
var subscriptionListCommand = serviceProvider.GetRequiredService<SubscriptionListCommand>();
subscription.AddCommand(subscriptionListCommand.Name, subscriptionListCommand);
subscription.AddCommand(serviceProvider.GetRequiredService<SubscriptionListCommand>());

return subscription;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ public async Task ListToolsHandler_WithReadOnlyOption_ReturnsOnlyReadOnlyTools()
var storageGroup = new CommandGroup("storage", "Storage commands");
var storageCommand = Substitute.For<IBaseCommand>();
storageCommand.Metadata.Returns(new ToolMetadata() { ReadOnly = true });
storageGroup.AddCommand("readonly", storageCommand);
storageGroup.Commands["readonly"] = storageCommand;
var keyvaultGroup = new CommandGroup("keyvault", "Key Vault commands");
var keyvaultCommand = Substitute.For<IBaseCommand>();
keyvaultCommand.Metadata.Returns(new ToolMetadata() { ReadOnly = false });
keyvaultGroup.AddCommand("notreadonly", keyvaultCommand);
keyvaultGroup.Commands["notreadonly"] = keyvaultCommand;
rootGroup.SubGroup.AddRange([storageGroup, keyvaultGroup]);
commandFactory.RootGroup.Returns(rootGroup);

Expand Down Expand Up @@ -182,11 +182,11 @@ public async Task ListToolsHandler_WithIsHttpOption_DoesNotReturnLocalRequiredTo
var stroageGroup = new CommandGroup("storage", "Storage commands");
var storageCommand = Substitute.For<IBaseCommand>();
storageCommand.Metadata.Returns(new ToolMetadata() { LocalRequired = true });
stroageGroup.AddCommand("localrequired", storageCommand);
stroageGroup.Commands["localrequired"] = storageCommand;
var keyvaultGroup = new CommandGroup("keyvault", "Key Vault commands");
var keyvaultCommand = Substitute.For<IBaseCommand>();
keyvaultCommand.Metadata.Returns(new ToolMetadata() { LocalRequired = false });
keyvaultGroup.AddCommand("notlocalrequired", keyvaultCommand);
keyvaultGroup.Commands["notlocalrequired"] = keyvaultCommand;
rootGroup.SubGroup.AddRange([stroageGroup, keyvaultGroup]);
commandFactory.RootGroup.Returns(rootGroup);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Reflection;
using Azure.Mcp.Core.Commands;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -253,7 +252,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
// Add all matching commands to this group
foreach (var cmd in _matchingCommands)
{
commandGroup.AddCommand(cmd.Key, cmd.Value);
commandGroup.AddCommand(cmd.Value);
}

// Set tool metadata from the consolidated tool definition
Expand Down
11 changes: 3 additions & 8 deletions core/Microsoft.Mcp.Core/src/Areas/Server/ServerSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,9 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var mcpServer = new CommandGroup(Name, "MCP Server operations - Commands for managing and interacting with the MCP Server.", Title);

// Register MCP Server commands
var startCommand = serviceProvider.GetRequiredService<ServiceStartCommand>();
mcpServer.AddCommand(startCommand.Name, startCommand);

var infoCommand = serviceProvider.GetRequiredService<ServiceInfoCommand>();
mcpServer.AddCommand(infoCommand.Name, infoCommand);

var pluginTelemetryCommand = serviceProvider.GetRequiredService<PluginTelemetryCommand>();
mcpServer.AddCommand(pluginTelemetryCommand.Name, pluginTelemetryCommand);
mcpServer.AddCommand(serviceProvider.GetRequiredService<ServiceStartCommand>());
mcpServer.AddCommand(serviceProvider.GetRequiredService<ServiceInfoCommand>());
mcpServer.AddCommand(serviceProvider.GetRequiredService<PluginTelemetryCommand>());

return mcpServer;
}
Expand Down
3 changes: 1 addition & 2 deletions core/Microsoft.Mcp.Core/src/Areas/Tools/ToolsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
// Create Tools command group
var tools = new CommandGroup(Name, "CLI tools operations - Commands for discovering and exploring the functionality available in this CLI tool.", Title);

var list = serviceProvider.GetRequiredService<ToolsListCommand>();
tools.AddCommand(list.Name, list);
tools.AddCommand(serviceProvider.GetRequiredService<ToolsListCommand>());

return tools;
}
Expand Down
21 changes: 1 addition & 20 deletions core/Microsoft.Mcp.Core/src/Commands/CommandGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,7 @@ public class CommandGroup(string name, string description, string? title = null)
public Command Command { get; } = new Command(name, description);
public ToolMetadata? ToolMetadata { get; set; }

public void AddCommand(string path, IBaseCommand command)
{
// Split on first dot to get group and remaining path
var parts = path.Split(['.'], 2);

if (parts.Length == 1)
{
// This is a direct command for this group
Commands[path] = command;
}
else
{
// Find or create the subgroup
var subGroup = SubGroup.FirstOrDefault(g => g.Name == parts[0]) ??
throw new InvalidOperationException($"Subgroup {parts[0]} not found. Group must be registered before commands.");

// Recursively add command to subgroup
subGroup.AddCommand(parts[1], command);
}
}
public void AddCommand(IBaseCommand command) => Commands[command.Name] = command;

public void AddSubGroup(CommandGroup subGroup)
{
Expand Down
12 changes: 6 additions & 6 deletions servers/Azure.Mcp.Server/docs/new-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -1383,20 +1383,20 @@ Guidelines:
### 9. Command Registration

```csharp
private void RegisterCommands(CommandGroup rootGroup, ILoggerFactory loggerFactory)
private CommandGroup RegisterCommands(IServiceProvider serviceProvider)
{
var service = new CommandGroup(
"{Toolset}",
"{Toolset} operations");
rootGroup.AddSubGroup(service);
"{Toolset} operations description");

var resource = new CommandGroup(
"{resource}",
"{Resource} operations");
"{Resource} operations description");
service.AddSubGroup(resource);

resource.AddCommand("{operation}", new {Resource}{Operation}Command(
loggerFactory.CreateLogger<{Resource}{Operation}Command>()));
resource.AddCommand(serviceProvider.GetRequiredService<{Resource}{Operation}Command>());

return service;
}
```

Expand Down
7 changes: 2 additions & 5 deletions tools/Azure.Mcp.Tools.Acr/src/AcrSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,12 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var registry = new CommandGroup("registry", "Container Registry resource operations - Commands for listing and managing Container Registry resources in your Azure subscription.");
acr.AddSubGroup(registry);

var registryList = serviceProvider.GetRequiredService<RegistryListCommand>();
registry.AddCommand(registryList.Name, registryList);
registry.AddCommand(serviceProvider.GetRequiredService<RegistryListCommand>());

var repository = new CommandGroup("repository", "Container Registry repository operations - Commands for listing and managing repositories within a Container Registry.");

registry.AddSubGroup(repository);

var repositoryList = serviceProvider.GetRequiredService<RegistryRepositoryListCommand>();
repository.AddCommand(repositoryList.Name, repositoryList);
repository.AddCommand(serviceProvider.GetRequiredService<RegistryRepositoryListCommand>());

return acr;
}
Expand Down
3 changes: 1 addition & 2 deletions tools/Azure.Mcp.Tools.Advisor/src/AdvisorSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
advisor.AddSubGroup(recommendation);

// Register Advisor commands
var recommendationList = serviceProvider.GetRequiredService<RecommendationListCommand>();
recommendation.AddCommand(recommendationList.Name, recommendationList);
recommendation.AddCommand(serviceProvider.GetRequiredService<RecommendationListCommand>());

return advisor;
}
Expand Down
7 changes: 2 additions & 5 deletions tools/Azure.Mcp.Tools.Aks/src/AksSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
aks.AddSubGroup(nodepool);

// Register AKS commands
var clusterGet = serviceProvider.GetRequiredService<ClusterGetCommand>();
cluster.AddCommand(clusterGet.Name, clusterGet);

var nodepoolGet = serviceProvider.GetRequiredService<NodepoolGetCommand>();
nodepool.AddCommand(nodepoolGet.Name, nodepoolGet);
cluster.AddCommand(serviceProvider.GetRequiredService<ClusterGetCommand>());
nodepool.AddCommand(serviceProvider.GetRequiredService<NodepoolGetCommand>());

return aks;
}
Expand Down
19 changes: 7 additions & 12 deletions tools/Azure.Mcp.Tools.AppConfig/src/AppConfigSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,13 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
keyValue.AddSubGroup(lockGroup);

// Register AppConfig commands
var accountList = serviceProvider.GetRequiredService<AccountListCommand>();
accounts.AddCommand(accountList.Name, accountList);

var keyValueDelete = serviceProvider.GetRequiredService<KeyValueDeleteCommand>();
keyValue.AddCommand(keyValueDelete.Name, keyValueDelete);
var keyValueGet = serviceProvider.GetRequiredService<KeyValueGetCommand>();
keyValue.AddCommand(keyValueGet.Name, keyValueGet);
var keyValueSet = serviceProvider.GetRequiredService<KeyValueSetCommand>();
keyValue.AddCommand(keyValueSet.Name, keyValueSet);

var keyValueLockSet = serviceProvider.GetRequiredService<KeyValueLockSetCommand>();
lockGroup.AddCommand(keyValueLockSet.Name, keyValueLockSet);
accounts.AddCommand(serviceProvider.GetRequiredService<AccountListCommand>());

keyValue.AddCommand(serviceProvider.GetRequiredService<KeyValueDeleteCommand>());
keyValue.AddCommand(serviceProvider.GetRequiredService<KeyValueGetCommand>());
keyValue.AddCommand(serviceProvider.GetRequiredService<KeyValueSetCommand>());

lockGroup.AddCommand(serviceProvider.GetRequiredService<KeyValueLockSetCommand>());

return appConfig;
}
Expand Down
3 changes: 1 addition & 2 deletions tools/Azure.Mcp.Tools.AppLens/src/AppLensSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
// Resource commands
var resourceGroup = new CommandGroup("resource", "Resource operations - Commands for diagnosing specific Azure resources.");

var diagnose = serviceProvider.GetRequiredService<ResourceDiagnoseCommand>();
resourceGroup.AddCommand(diagnose.Name, diagnose);
resourceGroup.AddCommand(serviceProvider.GetRequiredService<ResourceDiagnoseCommand>());

applens.AddSubGroup(resourceGroup);

Expand Down
23 changes: 7 additions & 16 deletions tools/Azure.Mcp.Tools.AppService/src/AppServiceSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,46 +42,37 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)

// Add database commands
// Register the 'add' command for database connections, allowing users to configure a new database connection for an App Service web app.
var databaseAdd = serviceProvider.GetRequiredService<DatabaseAddCommand>();
database.AddCommand(databaseAdd.Name, databaseAdd);
database.AddCommand(serviceProvider.GetRequiredService<DatabaseAddCommand>());

// Create webapp subgroup
var webapp = new CommandGroup("webapp", "Operations for managing Azure App Service web apps");
appService.AddSubGroup(webapp);

// Add webapp commands
var webappGet = serviceProvider.GetRequiredService<WebappGetCommand>();
webapp.AddCommand(webappGet.Name, webappGet);
webapp.AddCommand(serviceProvider.GetRequiredService<WebappGetCommand>());

// Add deployment subgroup
var deployment = new CommandGroup("deployment", "Operations for managing Azure App Service web app deployments");
webapp.AddSubGroup(deployment);

// Add deployment commands
var deploymentGet = serviceProvider.GetRequiredService<DeploymentGetCommand>();
deployment.AddCommand(deploymentGet.Name, deploymentGet);
deployment.AddCommand(serviceProvider.GetRequiredService<DeploymentGetCommand>());

// Add diagnostic subgroup under webapp
var diagnostic = new CommandGroup("diagnostic", "Operations for diagnosing Azure App Service web apps");
webapp.AddSubGroup(diagnostic);

// Add diagnostic commands
var detectorDiagnose = serviceProvider.GetRequiredService<DetectorDiagnoseCommand>();
diagnostic.AddCommand(detectorDiagnose.Name, detectorDiagnose);

var detectorList = serviceProvider.GetRequiredService<DetectorListCommand>();
diagnostic.AddCommand(detectorList.Name, detectorList);
diagnostic.AddCommand(serviceProvider.GetRequiredService<DetectorDiagnoseCommand>());
diagnostic.AddCommand(serviceProvider.GetRequiredService<DetectorListCommand>());

// Add settings subgroup under webapp
var settings = new CommandGroup("settings", "Operations for managing Azure App Service web settings");
webapp.AddSubGroup(settings);

// Add settings commands
var appSettingsGet = serviceProvider.GetRequiredService<AppSettingsGetCommand>();
settings.AddCommand(appSettingsGet.Name, appSettingsGet);

var appSettingsUpdate = serviceProvider.GetRequiredService<AppSettingsUpdateCommand>();
settings.AddCommand(appSettingsUpdate.Name, appSettingsUpdate);
settings.AddCommand(serviceProvider.GetRequiredService<AppSettingsGetCommand>());
settings.AddCommand(serviceProvider.GetRequiredService<AppSettingsUpdateCommand>());

return appService;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var recommendation = new CommandGroup("recommendation", "Application Insights recommendation operations - list recommendation targets (components).");
group.AddSubGroup(recommendation);

var recommendationList = serviceProvider.GetRequiredService<RecommendationListCommand>();
recommendation.AddCommand(recommendationList.Name, recommendationList);
recommendation.AddCommand(serviceProvider.GetRequiredService<RecommendationListCommand>());

return group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
authorization.AddSubGroup(roleAssignment);

// Register role assignment commands
var command = serviceProvider.GetRequiredService<RoleAssignmentListCommand>();
roleAssignment.AddCommand(command.Name, command);
roleAssignment.AddCommand(serviceProvider.GetRequiredService<RoleAssignmentListCommand>());

return authorization;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,8 @@ Only call this function when you are confident the user is discussing Azure (inc
Title
);

var bestPracticesCommand = serviceProvider.GetRequiredService<BestPracticesCommand>();
var aiAppBestPracticesCommand = serviceProvider.GetRequiredService<AIAppBestPracticesCommand>();

bestPractices.AddCommand(bestPracticesCommand.Name, bestPracticesCommand);
bestPractices.AddCommand(aiAppBestPracticesCommand.Name, aiAppBestPracticesCommand);
bestPractices.AddCommand(serviceProvider.GetRequiredService<BestPracticesCommand>());
bestPractices.AddCommand(serviceProvider.GetRequiredService<AIAppBestPracticesCommand>());

return bestPractices;
}
Expand Down
3 changes: 1 addition & 2 deletions tools/Azure.Mcp.Tools.AzureIsv/src/AzureIsvSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var monitoredResources = new CommandGroup("monitoredresources", "Datadog monitored resources operations - Commands for listing monitored resources in a specific Datadog monitor.");
datadog.AddSubGroup(monitoredResources);

var monitoredResourcesList = serviceProvider.GetRequiredService<MonitoredResourcesListCommand>();
monitoredResources.AddCommand(monitoredResourcesList.Name, monitoredResourcesList);
monitoredResources.AddCommand(serviceProvider.GetRequiredService<MonitoredResourcesListCommand>());

return datadog;
}
Expand Down
7 changes: 2 additions & 5 deletions tools/Azure.Mcp.Tools.AzureMigrate/src/AzureMigrateSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
azureMigrate.AddSubGroup(platformLandingZone);

// Register platform landing zone commands
var platformLandingZoneGetGuidance = serviceProvider.GetRequiredService<GetGuidanceCommand>();
platformLandingZone.AddCommand(platformLandingZoneGetGuidance.Name, platformLandingZoneGetGuidance);

var platformLandingZoneRequest = serviceProvider.GetRequiredService<RequestCommand>();
platformLandingZone.AddCommand(platformLandingZoneRequest.Name, platformLandingZoneRequest);
platformLandingZone.AddCommand(serviceProvider.GetRequiredService<GetGuidanceCommand>());
platformLandingZone.AddCommand(serviceProvider.GetRequiredService<RequestCommand>());

return azureMigrate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
If this tool needs to be categorized, it belongs to the Azure Best Practices category.", Title
);

var practices = serviceProvider.GetRequiredService<AzureTerraformBestPracticesGetCommand>();
azureTerraformBestPractices.AddCommand(practices.Name, practices);
azureTerraformBestPractices.AddCommand(serviceProvider.GetRequiredService<AzureTerraformBestPracticesGetCommand>());

return azureTerraformBestPractices;
}
Expand Down
4 changes: 1 addition & 3 deletions tools/Azure.Mcp.Tools.BicepSchema/src/BicepSchemaSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var bicepschema = new CommandGroup(Name, "Bicep schema operations - Commands for working with Azure Bicep Infrastructure as Code (IaC) generation and schema management. Includes operations for retrieving Bicep schemas, templates, and resource definitions to support infrastructure deployment automation.", Title);

// Register Bicep Schema command

var bicepSchemaGet = serviceProvider.GetRequiredService<BicepSchemaGetCommand>();
bicepschema.AddCommand(bicepSchemaGet.Name, bicepSchemaGet);
bicepschema.AddCommand(serviceProvider.GetRequiredService<BicepSchemaGetCommand>());

return bicepschema;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var cloudArchitect = new CommandGroup(Name, "Cloud Architecture operations - Commands for generating Azure architecture designs and recommendations based on requirements.", Title);

// Register CloudArchitect commands
var design = serviceProvider.GetRequiredService<DesignCommand>();
cloudArchitect.AddCommand(design.Name, design);
cloudArchitect.AddCommand(serviceProvider.GetRequiredService<DesignCommand>());

return cloudArchitect;
}
Expand Down
Loading
Loading