Skip to content

Emit AzSubscriptionGuid telemetry tag in namespace tool loader#2725

Open
shrja-ms wants to merge 2 commits into
microsoft:mainfrom
shrja-ms:user/fix-namespace-subscription-telemetry
Open

Emit AzSubscriptionGuid telemetry tag in namespace tool loader#2725
shrja-ms wants to merge 2 commits into
microsoft:mainfrom
shrja-ms:user/fix-namespace-subscription-telemetry

Conversation

@shrja-ms

Copy link
Copy Markdown
Contributor

Summary

In namespace server mode (the default for the Azure MCP Server), McpRuntime.CallToolHandler only inspects the outer request.Params.Arguments for a top-level subscription key. But in namespace mode the MCP request envelope is {intent, command, parameters: {…}} — the real --subscription value lives one level deeper inside parameters. As a result, the AzSubscriptionGuid Activity tag is never emitted for namespace-mode tool calls, which made per-subscription telemetry empty for the entire Azure MCP Server tool surface.

Fix

NamespaceToolLoader.InvokeChildToolAsync now extracts the inner --subscription value from the parsed parameters dictionary and emits AzureTagName.SubscriptionGuid, matching the existing McpRuntime behavior for direct tool invocations.

The key match uses the same NameNormalization logic that the schema generator uses, so the lookup is case-insensitive and aligned with however the MCP client serialises the option name.

Tests

Adds 6 unit tests in NamespaceToolLoaderTests.cs:

  • String subscription value is emitted as the tag
  • Key match is case-insensitive
  • No tag when subscription parameter is absent
  • No tag when value is empty
  • No-op when Activity is null
  • No-op when parameters is null

All passing locally (dotnet test --filter "FullyQualifiedName~NamespaceToolLoaderTests.TryEmitSubscriptionTag" → 6/6).

Impact

After this lands, all Azure MCP Server namespace-mode tool calls will carry the AzSubscriptionGuid Activity tag → restores per-subscription telemetry for downstream reporting (e.g., Internal vs External customer classification via mabprod1.AzureBackup.GetInternalSubscriptions()).

Invoking Livetests

Copilot submitted PRs are not trustworthy by default. Users with write access to the repo need to validate the contents of this PR before leaving a comment with the text /azp run mcp - pullrequest - live. This will trigger the necessary livetest workflows to complete required validation.

In namespace mode, McpRuntime only sees the outer {intent, command, parameters} envelope and cannot find a top-level 'subscription' argument, so the AzSubscriptionGuid Activity tag is never set. This caused per-subscription telemetry to be empty for all namespace-mode tool calls (which is the default for the Azure MCP Server).

Fix: NamespaceToolLoader.InvokeChildToolAsync now extracts the inner --subscription value from the parsed parameters dictionary and emits the AzSubscriptionGuid tag, matching the behavior already implemented in McpRuntime for direct tool invocations.

Adds 6 unit tests covering: string subscription, case-insensitive key match, missing parameter, empty value, null activity, and null parameters.
Copilot AI review requested due to automatic review settings May 25, 2026 09:12
@shrja-ms shrja-ms requested review from a team as code owners May 25, 2026 09:12
@shrja-ms shrja-ms requested review from msalaman and srnagar May 25, 2026 09:12

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.

Pull request overview

Fixes missing per-subscription telemetry for Azure MCP Server namespace-mode tool calls by emitting the AzSubscriptionGuid Activity tag from the inner parameters object (since McpRuntime.CallToolHandler only inspects the outer arguments envelope in this mode).

Changes:

  • Emit AzureTagName.SubscriptionGuid during namespace child-tool invocation based on the parsed parameters dictionary.
  • Add NamespaceToolLoader.TryEmitSubscriptionTag helper to encapsulate the extraction/tagging logic.
  • Add unit tests covering tag emission and no-op scenarios (null activity, null parameters, empty/absent subscription).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ToolLoading/NamespaceToolLoader.cs Emits subscription telemetry tag for namespace-mode calls and adds the helper method.
core/Azure.Mcp.Core/tests/Azure.Mcp.Core.Tests/Areas/Server/Commands/ToolLoading/NamespaceToolLoaderTests.cs Adds unit tests for subscription-tag emission behavior.

Per review feedback on PR microsoft#2725: McpRuntime.CallToolHandler emits the AzSubscriptionGuid tag for any non-null string (including empty), but TryEmitSubscriptionTag was gating on !string.IsNullOrEmpty, which would produce different telemetry for direct-tool vs namespace-mode calls with the same input.

Change to a null-only check and update the unit test (now asserts the tag IS emitted as an empty string when the parameter value is empty) to lock in parity going forward.
@shrja-ms

Copy link
Copy Markdown
Contributor Author

Addressed in e4e91d6 — changed the guard from !string.IsNullOrEmpty(subscription) to subscription != null so the tag is emitted for any non-null string (including empty), matching McpRuntime.CallToolHandler. Updated the corresponding unit test to assert the empty-string tag is now emitted. Build + the 6 telemetry unit tests pass locally.

shrja-ms added a commit to shrja-ms/mcp that referenced this pull request May 27, 2026
Per reviewer feedback on microsoft#2725, set the subscription tag directly in each
AzureBackup tool alongside existing OperationScope/VaultType tags, instead
of relying on the central McpRuntime/NamespaceToolLoader emission path.
This restores per-subscription telemetry for AzureBackup tools in both
namespace and standard server modes.

- Add SubscriptionGuid constant + AddSubscriptionTag helper to
  AzureBackupTelemetryTags (duplicates internal AzureTagName.SubscriptionGuid
  literal so it can be referenced from the tool assembly).
- Insert AddSubscriptionTag call in 18 AzureBackup command ExecuteAsync
  methods.
- Add 5 unit tests covering tag emission and no-op scenarios.
shrja-ms added a commit that referenced this pull request May 27, 2026
)

Per reviewer feedback on #2725, set the subscription tag directly in each
AzureBackup tool alongside existing OperationScope/VaultType tags, instead
of relying on the central McpRuntime/NamespaceToolLoader emission path.
This restores per-subscription telemetry for AzureBackup tools in both
namespace and standard server modes.

- Add SubscriptionGuid constant + AddSubscriptionTag helper to
  AzureBackupTelemetryTags (duplicates internal AzureTagName.SubscriptionGuid
  literal so it can be referenced from the tool assembly).
- Insert AddSubscriptionTag call in 18 AzureBackup command ExecuteAsync
  methods.
- Add 5 unit tests covering tag emission and no-op scenarios.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

2 participants