Skip to main content
Glama

Azure MCP Server

Official
MIT License
1,161
  • Linux
  • Apple
ResourceGroupOptionRefactor.md5.96 kB
# Resource Group Option Refactor (Final Design) ## Objective Provide a single, optional global `--resource-group` option and a simple declarative way for commands to express whether they merely accept it or logically require it. ## Final Design Summary 1. A single global option: `OptionDefinitions.Common.ResourceGroup` (always parser-optional). 2. Two helpers on `BaseCommand`: * `UseResourceGroup()` – register the option (optional semantics). * `RequireResourceGroup()` – register the option and mark it as logically required. 3. Central logical validation in `BaseCommand.ValidateLogicalRequirements` produces a uniform `400` error with message: `resource-group is required for this command.` when a required resource group is missing. 4. Commands bind the value via `GetResourceGroup(parseResult)` (returns `null` if not registered / not provided). 5. No area-specific optional variants; all previous `OptionalResourceGroup` definitions removed. ## Rationale * Eliminates duplicated option declarations and inconsistent help text. * Keeps parser configuration simple (no dynamic required flags or custom builders). * Shifts requirement enforcement to a business rule making optional cross-RG or subscription-scoped operations easy. * Produces uniform error messaging and lowers boilerplate. ## Helper API (Implemented) ```csharp // In BaseCommand protected void UseResourceGroup(); // adds global option if not yet added protected void RequireResourceGroup(); // adds and marks as logically required protected string? GetResourceGroup(ParseResult parseResult); // Central validation (excerpt) if (result.IsValid && _requiresResourceGroup) { var rg = commandResult.GetValueForOption(OptionDefinitions.Common.ResourceGroup); if (string.IsNullOrWhiteSpace(rg)) { /* set 400 + message */ } } ``` ## Command Usage Examples ```csharp protected override void RegisterOptions(Command command) { base.RegisterOptions(command); RequireResourceGroup(); // RG now logically required command.AddOption(_nameOption); // other options } protected override void RegisterOptions(Command command) { base.RegisterOptions(command); UseResourceGroup(); // RG optional filter command.AddOption(_filterOption); } protected override MyOptions BindOptions(ParseResult parseResult) { var o = base.BindOptions(parseResult); o.ResourceGroup = GetResourceGroup(parseResult); // null if omitted / not used return o; } ``` ## Current Implementation Status Implemented: * Global option made optional. * Helpers added to `BaseCommand`. * Central logical validation active. * Area-specific optional variants (ACR, Monitor Metrics, Extension Azqr) removed. * Migrated representative commands and base classes (AKS, Workbooks, ACR registry, Metrics, LoadTesting, Postgres, Redis, SQL, Storage create, Extension Azqr, Monitor health / tables, Foundry, AzureIsv). Pending / Follow‑ups (if desired): * Ensure every remaining command uses `UseResourceGroup()` / `RequireResourceGroup()` instead of direct `command.AddOption(_resourceGroupOption)`. * Update `docs/new-command.md` to reference helpers (remove any legacy guidance). * Add / adjust tests: - Required command without RG -> 400 + standard message. - Optional command without RG -> succeeds (or broader listing) and does not parse-fail. * Update CHANGELOG. ## Semantics Cheat Sheet | Scenario | Helper | Parser Requires? | Runtime Requires? | Behavior When Missing | |----------|--------|------------------|-------------------|-----------------------| | RG truly needed | `RequireResourceGroup()` | No | Yes | 400 + message | | RG optional filter | `UseResourceGroup()` | No | No | Command executes with broader scope | | RG irrelevant | (omit both) | No | No | Option not exposed | ## Error Message Contract Missing required RG always yields: `resource-group is required for this command.` (HTTP 400 in tool response). ## Testing Guidelines 1. Do not assert parser-level failures for missing RG; assert logical validation (response status/message). 2. Optional commands: omit RG and assert success + expected broader result set. 3. Include at least one negative test per area where RG is required. ## Extensibility Pattern If another option needs a conditional requirement (e.g., `--location`): introduce parallel helpers (`UseLocation()`, `RequireLocation()`) and replicate the minimal flag + central validation approach. Avoid generic abstraction until a second concrete need exists. **Note**: This approach provides an interim improvement to the design. A fully extensible solution for "included but conditionally required" options will be implemented as part of https://github.com/Azure/azure-mcp/issues/84. The current design addresses immediate maintainability concerns while establishing patterns that can be generalized in the future. ## Migration Summary Removed: All `OptionalResourceGroup` definitions and per-command duplicate validations. Added: Two helper methods + central validation branch. Modified: Commands now call a single declarative helper and bind via `GetResourceGroup` (or optional direct parse if already using it). ## Changelog (Planned Entry) ``` ### Changed * Made global --resource-group parser-optional. * Removed area-specific optional resource group option definitions (ACR, Monitor Metrics, Extension Azqr). * Added helper methods UseResourceGroup / RequireResourceGroup with centralized logical validation. ``` ## Contributor Guidance When adding a new command: 1. Decide if the command needs, optionally filters by, or ignores resource group. 2. Call exactly one of: `RequireResourceGroup()`, `UseResourceGroup()`, or neither. 3. Bind with `GetResourceGroup(parseResult)` if used. 4. Rely on central validation—do not add custom RG presence checks. This document reflects the final design; earlier exploratory approaches (builder patterns, marker interfaces) have been superseded and intentionally omitted.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Azure/azure-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server