技能 编程开发 新增Azure备份工具命令流程

新增Azure备份工具命令流程

v20260608
azurebackup-add-tool
本指南为开发人员提供了将新的Azure备份命令集成到Azure Backup MCP工具集中的完整工作流程。它覆盖了整个开发生命周期,包括选项定义、服务层实现、命令逻辑、注册、输入校验、编写单元测试和执行模拟测试,确保提交PR的代码质量和规范性。
获取技能
299 次下载
概览

Add a New Tool to Azure Backup MCP

Purpose

Step-by-step workflow for adding a new command to the Azure Backup MCP toolset, ensuring it passes all validation gates before PR submission.

When to Use

  • Adding a new azmcp azurebackup <group> <operation> command
  • Extending an existing command group (vault, policy, protecteditem, etc.)
  • Adding a new command group (security, compliance, etc.)

Prerequisites

  • .NET 10 SDK installed (see global.json)
  • Azure authentication configured (az login / Connect-AzAccount)
  • Repository cloned with upstream remote pointing to microsoft/mcp
  • Branch created from upstream/main

Procedure

Phase 1: Implementation

Follow /servers/Azure.Mcp.Server/docs/new-command.md as the authoritative guide. The Azure Backup toolset lives in tools/Azure.Mcp.Tools.AzureBackup/.

1a. Create Option Definitions

File: src/Options/{Group}/{Resource}{Operation}Options.cs

// Inherit from the appropriate base options class
public class MyNewOptions : BaseAzureBackupOptions
{
    public string? MyParam { get; set; }
}
  • Use OptionDefinitions.Common.* for shared options (subscription, resourceGroup)
  • Use AzureBackupOptionDefinitions.Vault and AzureBackupOptionDefinitions.VaultType for vault options
  • Add new options to AzureBackupOptionDefinitions if reusable across commands
  • Use .AsRequired() / .AsOptional() extension methods

1b. Add Service Method

File: src/Services/IAzureBackupService.cs and src/Services/AzureBackupService.cs

  • Add the interface method first
  • Route to rsvOps or dppOps based on vault type using ResolveVaultTypeAsync
  • For RSV-only operations, add to IRsvBackupOperations / RsvBackupOperations
  • For DPP-only operations, add to IDppBackupOperations / DppBackupOperations

1c. Implement the Command

File: src/Commands/{Group}/{Resource}{Operation}Command.cs

Required patterns:

  • Use [CommandMetadata(...)] attribute (not property overrides)
  • Sealed class with primary constructor
  • Inject ILogger<T> and IAzureBackupService
  • Override RegisterOptions, BindOptions, ExecuteAsync
  • Add telemetry tags via AzureBackupTelemetryTags.AddVaultTags(context.Activity, ...)
  • Call HandleException(context, ex) in catch blocks

1d. Register the Command

File: src/AzureBackupSetup.cs

  • Add services.AddSingleton<MyNewCommand>() in ConfigureServices
  • Add group.AddCommand<MyNewCommand>(serviceProvider) in RegisterCommands
  • Create a new CommandGroup if needed for a new group

1e. Register JSON Serialization Context

File: src/Commands/AzureBackupJsonContext.cs

  • Add [JsonSerializable(typeof(MyNewCommand.MyResultType))] for AOT safety

Phase 2: Input Validation

Before writing tests, validate all inputs are handled correctly:

Checklist:

  • Required parameters throw ArgumentException with clear message when missing
  • Subscription format validated (GUID only) via ValidateSubscriptionFormat
  • Vault type normalized correctly (rsv/dpp case-insensitive)
  • Enum/string parameters validated against allowed values with helpful error listing
  • Null/empty strings handled with ArgumentException.ThrowIfNullOrWhiteSpace
  • ARM resource IDs parsed safely with try-catch on new ResourceIdentifier(...)
  • Error messages are actionable (tell user what to provide, not just what failed)

Phase 3: Unit Tests

File: tests/Azure.Mcp.Tools.AzureBackup.Tests/{Group}/{Resource}{Operation}CommandTests.cs

Required Test Methods

public sealed class MyNewCommandTests : CommandUnitTestsBase<MyNewCommand, IAzureBackupService>
{
    [Fact] public void Constructor_InitializesCommandCorrectly()
    [Fact] public void BindOptions_BindsOptionsCorrectly()
    [Fact] public async Task ExecuteAsync_ValidInput_ReturnsExpectedResult()
    [Fact] public async Task ExecuteAsync_HandlesServiceErrors()
    [Fact] public async Task ExecuteAsync_DeserializationValidation()

    // Add per-parameter validation tests:
    [Theory]
    [InlineData(null)]
    [InlineData("")]
    public async Task ExecuteAsync_InvalidVault_ThrowsArgumentException(string? vault)

    // Add edge case tests specific to the command
}

Run Unit Tests

dotnet test tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests `
  /p:NuGetAudit=false `
  --filter "Category!=Live&FullyQualifiedName~MyNewCommandTests"

Verify all tests pass before proceeding.

Phase 4: Live Tests

File: tests/Azure.Mcp.Tools.AzureBackup.Tests/AzureBackupCommandTests.cs

4a. Add Test Methods

Azure Backup live tests use [Fact] on a RecordedCommandTestsBase subclass with CallToolAsync. There is no [RecordedTest] attribute in this toolset.

[Fact]
public async Task MyNewCommand_RsvVault()
{
    var result = await CallToolAsync(
        "azurebackup", "mygroup", "myop",
        new Dictionary<string, object>
        {
            ["subscription"] = SubscriptionId,
            ["resourceGroup"] = ResourceGroupName,
            ["vault"] = DeploymentOutputs["AZUREBACKUP_RSV_VAULT_NAME"],
            // add other params
        });

    Assert.NotNull(result);
    // assert on result content
}
  • Use [Fact] for all live tests (not [RecordedTest] — that attribute is not used in Azure Backup)
  • Use [LiveTestOnly] alongside [Fact] for long-running E2E tests that cannot reliably replay
  • Use test resource values from DeploymentOutputs (set in test-resources-post.ps1)

4b. Update Test Infrastructure (if needed)

If the new command requires new Azure resources:

  1. Edit tests/test-resources.bicep to add the resource
  2. Edit tests/test-resources-post.ps1 to output new deployment values
  3. Deploy: ./eng/scripts/Deploy-TestResources.ps1 -Paths AzureBackup

4c. Record Live Tests

# Set to Record mode
$settings = @{
    TestMode = "Record"
    SubscriptionId = "<your-sub>"
    TenantId = "<your-tenant>"
    ResourceGroupName = "<your-rg>"
    ResourceBaseName = "<your-base>"
} | ConvertTo-Json
$settings | Set-Content "tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests\.testsettings.json"

# Kill any stale proxy/server processes
Stop-Process -Name "Azure.Sdk.Tools.TestProxy","azmcp" -Force -ErrorAction SilentlyContinue

# Run tests in Record mode
dotnet test tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests `
  /p:NuGetAudit=false --filter "FullyQualifiedName~MyNewCommand"

4d. Push Recordings

# Push recorded sessions to azure-sdk-assets
.proxy\Azure.Sdk.Tools.TestProxy push `
  -a tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests\assets.json

This updates the Tag field in assets.json. Commit the updated assets.json.

4e. Verify Playback

# Switch to Playback mode
$settings = @{ TestMode = "Playback"; SubscriptionId = "..."; TenantId = "..."; ResourceGroupName = "..."; ResourceBaseName = "..." } | ConvertTo-Json
$settings | Set-Content "tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests\.testsettings.json"

Stop-Process -Name "Azure.Sdk.Tools.TestProxy","azmcp" -Force -ErrorAction SilentlyContinue

dotnet test tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests `
  /p:NuGetAudit=false --filter "FullyQualifiedName~MyNewCommand"

All recorded tests must pass in Playback mode.

Phase 5: CI Validation Gates

Run these checks in order. All must pass before creating a PR.

5a. Build

dotnet build tools\Azure.Mcp.Tools.AzureBackup\src\Azure.Mcp.Tools.AzureBackup.csproj /p:NuGetAudit=false

5b. Format Check

dotnet format Microsoft.Mcp.slnx --verify-no-changes `
  --include "tools/Azure.Mcp.Tools.AzureBackup/**" `
  --exclude-diagnostics IL2026 IL3050

If it fails, fix with:

dotnet format Microsoft.Mcp.slnx `
  --include "tools/Azure.Mcp.Tools.AzureBackup/**" `
  --exclude-diagnostics IL2026 IL3050

5c. Full Unit Tests

dotnet test tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests /p:NuGetAudit=false

5d. Full Live Tests (Playback)

dotnet test tools\Azure.Mcp.Tools.AzureBackup\tests\Azure.Mcp.Tools.AzureBackup.Tests /p:NuGetAudit=false

5e. Spell Check

.\eng\common\spelling\Invoke-Cspell.ps1

If new technical terms are flagged, add them to .vscode/cspell.json.

5f. Full Build Verification

./eng/scripts/Build-Local.ps1 -UsePaths -VerifyNpx

5g. AOT/Native Build Verification

Azure Backup is marked IsAotCompatible=true, so also validate native compilation:

./eng/scripts/Build-Local.ps1 -BuildNative

If this fails for a new Azure SDK dependency, the toolset may need to be excluded from native builds (see docs/aot-compatibility.md).

Phase 6: Tool Description Evaluation

Run the ToolDescriptionEvaluator to verify the new tool's description is discoverable by AI agents.

$env:AOAI_ENDPOINT = "<your-aoai-endpoint>"
$env:TEXT_EMBEDDING_API_KEY = "<your-key>"

dotnet run --project eng/tools/ToolDescriptionEvaluator/src/ToolDescriptionEvaluator.csproj `
  -- --tool-name "azurebackup_<group>_<operation>"

Target: Top 3 ranking with confidence score >= 0.4.

If the score is low, improve the command's Description in the [CommandMetadata] attribute:

  • Include key verbs users would say ("configure", "enable", "list", "show")
  • Mention specific resource types ("vault", "policy", "protected item")
  • Describe what the output looks like
  • Re-run until the score meets the threshold

Phase 7: Documentation

7a. Update Command Reference

File: servers/Azure.Mcp.Server/docs/azmcp-commands.md

Add the new command in alphabetical order within the azurebackup section.

Then regenerate the commands metadata:

./eng/scripts/Update-AzCommandsMetadata.ps1

This is required for CI validation.

7b. Add Test Prompts

File: servers/Azure.Mcp.Server/docs/e2eTestPrompts.md

Add 2-3 natural language prompts that should trigger the new tool, in alphabetical order.

7c. Create Changelog Entry

Follow docs/changelog-entries.md instructions. Use the -ChangelogPath parameter pointing to servers/Azure.Mcp.Server/CHANGELOG.md.

Phase 8: PR Submission

Final Checklist

Before creating the PR, verify:

  • Build passes: dotnet build succeeds with 0 errors
  • Format clean: dotnet format --verify-no-changes passes
  • All unit tests pass (including existing ones — no regressions)
  • All live tests pass in Playback mode
  • Recordings pushed and assets.json updated
  • Spell check passes: Invoke-Cspell.ps1 clean
  • ToolDescriptionEvaluator: Score >= 0.4, top 3 ranking
  • Command registered in AzureBackupSetup.cs
  • JSON context registered for AOT safety
  • Telemetry tags added via AzureBackupTelemetryTags
  • Documentation updated (commands.md, e2eTestPrompts.md, changelog, README.md, eng/vscode/README.md)
  • Commands metadata regenerated via Update-AzCommandsMetadata.ps1
  • AOT/native build passes (Build-Local.ps1 -BuildNative)
  • One tool per PR (don't bundle unrelated changes)

Create the PR

git add tools/Azure.Mcp.Tools.AzureBackup/ servers/Azure.Mcp.Server/ README.md eng/vscode/README.md
git commit -m "feat(azurebackup): Add <group> <operation> command

<description of what the command does>"
git push origin <branch-name>

Reference: File Locations

tools/Azure.Mcp.Tools.AzureBackup/
├── src/
│   ├── AzureBackupSetup.cs                           # Register here
│   ├── Commands/
│   │   ├── AzureBackupJsonContext.cs                  # AOT registration
│   │   └── {Group}/{Resource}{Operation}Command.cs    # Command impl
│   ├── Options/
│   │   ├── AzureBackupOptionDefinitions.cs            # Shared options
│   │   └── {Group}/{Resource}{Operation}Options.cs    # Command options
│   ├── Services/
│   │   ├── IAzureBackupService.cs                     # Interface
│   │   ├── AzureBackupService.cs                      # Routing
│   │   ├── RsvBackupOperations.cs                     # RSV impl
│   │   └── DppBackupOperations.cs                     # DPP impl
│   └── Models/
│       └── AzureBackupTelemetryTags.cs                # Telemetry
└── tests/
    ├── Azure.Mcp.Tools.AzureBackup.Tests/
    │   ├── {Group}/{Resource}{Operation}CommandTests.cs
    │   ├── AzureBackupCommandTests.cs                 # Add tests here
    │   └── assets.json                                # Recording tag
    ├── test-resources.bicep                           # Azure infra
    └── test-resources-post.ps1                        # Post-deploy

Reference: Good Examples

Study these existing implementations as templates:

  • Simple get/list: Commands/Vault/VaultGetCommand.cs
  • Create with validation: Commands/Policy/PolicyCreateCommand.cs
  • Governance toggle: Commands/Governance/GovernanceSoftDeleteCommand.cs
  • Security command: Commands/Security/SecurityConfigureMuaCommand.cs
  • Unit tests: tests/Azure.Mcp.Tools.AzureBackup.Tests/Policy/PolicyCreateCommandTests.cs
信息
Category 编程开发
Name azurebackup-add-tool
版本 v20260608
大小 14.01KB
更新时间 2026-06-10
语言