Skip to content

Export tool metadata after NuGet releases - #3867

Open
Connie Yau (conniey) wants to merge 22 commits into
mainfrom
conniey/ci-tool-metadata
Open

Connie Yau (conniey) wants to merge 22 commits into
mainfrom
conniey/ci-tool-metadata

Conversation

@conniey

@conniey Connie Yau (conniey) commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

What does this PR do?

  • Runs ToolMetadataExporter after Azure MCP NuGet releases and publishes generated tool-change metadata as a pipeline artifact.
  • Adds release configuration, historical-version export tooling, malformed JSON recovery, tests, and updated documentation.
  • Adds per server querying and ingestion
  • Adds support for "dry-run" when running with Template.Mcp.Server

Validation:

  • dotnet test -c Debug --project .\tests\ToolMetadataExporter.Tests\ToolMetadataExporter.Tests.csproj --filter-class "ToolMetadataExporter.Tests.UtilityTests" — passed (2 tests).
  • dotnet build .\src\ToolMetadataExporter.csproj --no-restore --nologo — passed with 0 warnings.

GitHub issue number?

https://github.com/microsoft/mcp-pr/issues/268

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide)
    • Added comprehensive tests for new/modified functionality
    • Created a changelog entry if required — N/A, engineering tooling only
  • For MCP tool changes: N/A
    • One tool per PR: N/A
    • Updated server documentation: N/A
    • Validated package README changes: N/A
    • Ran ToolDescriptionEvaluator: N/A
    • Updated consolidated-tools.json: N/A
    • Followed the tool rename checklist: N/A
    • Added public documentation links: N/A
  • Extra steps for Azure MCP Server tool changes: N/A
    • Updated azmcp-commands.md: N/A
    • Ran Update-AzCommandsMetadata.ps1: N/A
    • Updated e2eTestPrompts.md: N/A
    • Community security review and live tests: N/A
    • 👉 For Community (non-Microsoft team member) PRs:
      • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
      • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

JSON recovery remains incomplete, and the historical export script has unsafe defaults and misleading success behavior.

Review effort: Balanced
Findings: 4 Medium severity

Open (4)
What changed in this PR

Adds post-release Azure MCP tool metadata export and historical backfill support.

Changes:

  • Adds release pipeline export and artifact publication.
  • Adds historical-version processing and malformed JSON recovery.
  • Expands tests and documentation.
File Description
eng/​tools/​ToolMetadataExporter/​tests/​ToolMetadataExporter.Tests/​UtilityTests.cs Tests malformed JSON recovery.
eng/​tools/​ToolMetadataExporter/​src/​Utility.cs Escapes malformed JSON control characters.
eng/​tools/​ToolMetadataExporter/​src/​ToolMetadataExporter.csproj Enables user-secrets configuration.
eng/​tools/​ToolMetadataExporter/​src/​README.md Removes superseded nested documentation.
eng/​tools/​ToolMetadataExporter/​src/​Export-DownloadedVersions.ps1 Adds historical-version exports.
eng/​tools/​ToolMetadataExporter/​README.md Documents configuration and workflows.
eng/​scripts/​Invoke-ReleaseToolMetadataExport.ps1 Exports metadata from signed packages.
eng/​pipelines/​templates/​variables/​tool-metadata-exporter.yml Defines release datastore settings.
eng/​pipelines/​templates/​jobs/​release.yml Adds the metadata export release job.
eng/​pipelines/​templates/​common.yml Loads metadata exporter variables.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread eng/tools/ToolMetadataExporter/src/Export-DownloadedVersions.ps1 Outdated
Comment thread eng/tools/ToolMetadataExporter/src/Export-DownloadedVersions.ps1 Outdated
Comment thread eng/tools/ToolMetadataExporter/src/Export-DownloadedVersions.ps1
Comment thread eng/tools/ToolMetadataExporter/src/Utility.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The release path cannot locate the Windows executable or output directory and may corrupt metadata during non-Azure releases.

2 open findings
4 resolved since last review

🧠 Review effort: Balanced

Comment thread eng/pipelines/templates/jobs/release.yml Outdated
Comment thread eng/scripts/Invoke-ReleaseToolMetadataExport.ps1 Outdated
/// Escapes raw control characters inside JSON strings while preserving structural whitespace.
/// Historical azmcp versions emitted characters such as U+001A unescaped inside tool descriptions.
/// </summary>
private static string EscapeInvalidJsonStringControlCharacters(string json)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added because 3.0.0-beta.21 has control characters that are not escaped correctly when returning JSON resulting in a JSON parse exceptions.

Comment thread eng/pipelines/templates/jobs/export-tool-metadata.yml Outdated
ServerName: ${{ parameters.ServerName }}
DependsOn:
- TagRepository
- PublishNugetPackage

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PublishNugetPackage already depends on TagRepository, do we need to include it as a dependency here as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah. I just wanted to look the same as the other ones and then you'd see there's an additional stage it needed. ;P

Comment thread eng/scripts/Invoke-ReleaseToolMetadataExport.ps1 Outdated
Comment thread eng/scripts/Invoke-ReleaseToolMetadataExport.ps1 Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Higher level thought, not sure where to put it, but I'm going to put it here.

We do a lot of effort to build and run tool listing in quite a few places, I'm wondering if we'll be better off by having a source code parser that can get us this information. That'll also allow us to not worry about tools which require external applications to be installed (AZD, azqr, etc).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be nice and a future improvement but since a lot of our existing analyses use the tool at runtime to check tools, I kept it at that.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The release path can ingest without producing its artifact, and forced WhatIf previews incorrectly skip prior exports.

2 open findings
2 resolved since last review

🧠 Review effort: Balanced

throw "ToolMetadataExporter build failed with exit code $LASTEXITCODE."
}

$env:AppConfig__WorkDirectory = [System.IO.Path]::GetFullPath($ArtifactDirectory)
$successfulPaths = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::OrdinalIgnoreCase)

if (Test-Path -LiteralPath $SuccessfulPathsFile -PathType Leaf) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants