Introduce the new options pattern#2637
Conversation
1da22c4 to
1a5225c
Compare
2b56c66 to
534b462
Compare
534b462 to
d74dad9
Compare
7b6a3f0 to
b64f194
Compare
b64f194 to
75de5fc
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run mcp - pullrequest - live |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Change ResolveSubscription to take a string? subscription parameter instead of ParseResult, making it easier to mock in unit tests. Update KeyValueLockSetCommandTests to use NSubstitute mock that returns the input value, eliminating environment/CLI profile leakage in tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new attribute-driven options binding pattern for MCP commands. Public properties on a typed TOptions POCO are reflected into System.CommandLine Option<T> instances via the new OptionBinder/OptionDescriptor/OptionAttribute/OptionNameConvention pieces, removing the need for hand-written RegisterOptions/BindOptions overrides per command. Alongside this, RetryPolicyOptions is reshaped so all values are nullable (with Has* flags now derived rather than stored), retry configuration is centralized in a ConfigureRetryOptions extension, and a new ISubscriptionResolver abstraction replaces direct calls to CommandHelper in commands that derive from a new SubscriptionCommand<,>/AuthenticatedCommand<,>/BaseCommand<,> hierarchy. The KeyValueLockSetCommand is migrated as the first concrete consumer of the new pattern.
Changes:
- New options-binding infrastructure (
OptionAttribute,OptionDescriptor,OptionBinder,OptionNameConvention,BaseCommand<TOptions,TResult>,AuthenticatedCommand<,>,SubscriptionCommand<,>) andISubscriptionResolver/SubscriptionResolver. RetryPolicyOptionsswitched to nullable scalars with derivedHas*flags;BaseAzureService.ConfigureRetryPolicy,MonitorService,CosmosService, andSearchServiceupdated; newRetryOptionsExtensions.ConfigureRetryOptionsextension added.KeyValueLockSetCommand/KeyValueLockSetOptionsmigrated to the new pattern; tests/DI updated to registerISubscriptionResolver.
Show a summary per file
| File | Description |
|---|---|
| core/Microsoft.Mcp.Core/src/Options/OptionAttribute.cs | New attribute declaring CLI option metadata on POCO properties. |
| core/Microsoft.Mcp.Core/src/Options/OptionDescriptor.cs | Reflects POCO properties (with nullability/nesting) into descriptor list. |
| core/Microsoft.Mcp.Core/src/Options/OptionBinder.cs | Registers Option<T> on commands and binds parse results back to instances. |
| core/Microsoft.Mcp.Core/src/Options/OptionNameConvention.cs | Kebab-case conversion for property→option names. |
| core/Microsoft.Mcp.Core/src/Options/RetryPolicyOptions.cs | Switched to nullable scalars; Has* are now derived properties. |
| core/Microsoft.Mcp.Core/src/Commands/GlobalCommand.cs | Updated retry binding to write only when value present. |
| core/Microsoft.Mcp.Core/src/Commands/BaseCommand`2.cs | New typed-options base command with binding/validation pipeline. |
| core/Microsoft.Mcp.Core/src/Commands/AuthenticatedCommand`2.cs | Authenticated typed-options base command with auth-aware error mapping. |
| core/Microsoft.Mcp.Core/src/Helpers/CommandHelper.cs | Adds GetSubscription(string?) overload reused by the resolver. |
| core/Azure.Mcp.Core/src/Services/Azure/Subscription/ISubscriptionResolver.cs | New abstraction over subscription resolution. |
| core/Azure.Mcp.Core/src/Services/Azure/Subscription/SubscriptionResolver.cs | Default implementation delegating to CommandHelper. |
| core/Azure.Mcp.Core/src/Commands/Subscription/SubscriptionCommand`2.cs | Adds subscription option resolution + validation for typed commands. |
| core/Azure.Mcp.Core/src/Options/ISubscriptionOption.cs | Marker interface used by SubscriptionCommand<,>. |
| core/Azure.Mcp.Core/src/Options/OptionDescriptions.cs | Description constants for shared global options. |
| core/Azure.Mcp.Core/src/Options/RetryOptionsExtensions.cs | ConfigureRetryOptions extension on ClientOptions. |
| core/Azure.Mcp.Core/src/Services/Azure/BaseAzureService.cs | Updated to use nullable retry pattern with clamping preserved. |
| core/Azure.Mcp.Core/tests/.../BaseAzureServiceTests.cs | Test data adjusted for nullable RetryPolicyOptions. |
| core/Azure.Mcp.Core/tests/.../BaseAzureServiceRetryLimitsTests.cs | Removed Has* flags from test fixtures. |
| core/Azure.Mcp.Core/tests/.../RetryPolicyOptionsTests.cs | Equality tests updated for nullable semantics. |
| core/Azure.Mcp.Core/tests/.../CommandFactoryHelpers.cs | Registers ISubscriptionResolver substitute in test DI. |
| servers/Azure.Mcp.Server/src/Program.cs | Registers SubscriptionResolver in DI. |
| tools/Azure.Mcp.Tools.AppConfig/src/AppConfigSetup.cs | Adds DI extensions namespace for new registrations. |
| tools/Azure.Mcp.Tools.AppConfig/src/Commands/KeyValue/Lock/KeyValueLockSetCommand.cs | Migrated to SubscriptionCommand<,> and typed-options pipeline. |
| tools/Azure.Mcp.Tools.AppConfig/src/Options/KeyValue/Lock/KeyValueLockSetOptions.cs | Rewritten to use [Option] attributes and nullable retry. |
| tools/Azure.Mcp.Tools.AppConfig/tests/.../KeyValueLockSetCommandTests.cs | Wires ISubscriptionResolver substitute into test services. |
| tools/Azure.Mcp.Tools.Cosmos/src/Services/CosmosService.cs | Uses nullable pattern for retry options. |
| tools/Azure.Mcp.Tools.Monitor/src/Services/MonitorService.cs | Replaces inline retry config with ConfigureRetryOptions. |
| tools/Azure.Mcp.Tools.Search/src/Services/SearchService.cs | Removes obsolete local retry helper. |
| tools/Azure.Mcp.Tools.Workbooks/tests/.../UpdateWorkbooksCommandTests.cs | Updates test assertion for nullable DelaySeconds. |
Copilot's findings
- Files reviewed: 29/29 changed files
- Comments generated: 3
jongio
left a comment
There was a problem hiding this comment.
Clean refactoring of the options binding infrastructure. The attribute-driven pattern via OptionBinder/OptionDescriptor is a solid replacement for the manual RegisterOptions/BindOptions overrides, and the nullable RetryPolicyOptions simplification removes a lot of boilerplate.
A few things I noticed that existing reviewers haven't covered:
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
What does this PR do?
This pull request introduces significant refactoring to the Azure MCP command and options infrastructure, primarily to simplify option binding and validation, and to improve consistency across commands. The changes also include updates to retry policy configuration, test adjustments, and new project references.
GitHub issue number?
[Link to the GitHub issue this PR addresses]Pre-merge Checklist
servers/Azure.Mcp.Server/README.mdand/orservers/Fabric.Mcp.Server/README.mddocumentationREADME.mdchanges running the script./eng/scripts/Process-PackageReadMe.ps1. See Package READMEToolDescriptionEvaluatorand obtained a score of0.4or more and a top 3 ranking for all related test promptsconsolidated-tools.jsonbreaking-changelabelservers/Azure.Mcp.Server/docs/azmcp-commands.md./eng/scripts/Update-AzCommandsMetadata.ps1to update tool metadata inazmcp-commands.md(required for CI)servers/Azure.Mcp.Server/docs/e2eTestPrompts.mdcrypto mining, spam, data exfiltration, etc.)/azp run mcp - pullrequest - liveto run Live Test Pipeline