Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 6, 2026

Why make this change?

MCP tool invocations lack observability. No spans are emitted for tool execution, making it impossible to trace performance, failures, or execution paths through the system.

What is this change?

Adds OpenTelemetry instrumentation at the MCP dispatcher level, wrapping all tool executions (built-in DML and custom stored-procedure tools) across both stdio and HTTP transports.

Span attributes:

  • mcp.tool.name - tool identifier
  • dab.entity - entity name (when applicable)
  • dab.operation - inferred operation type (read/create/update/delete/execute)
  • db.procedure - stored procedure name for custom tools (schema-qualified)

Implementation details:

  • Centralized in McpStdioServer.HandleCallToolAsync() and McpServerConfiguration.CallToolHandler
  • Exception recording with type-specific error codes (OPERATION_CANCELLED, AUTHENTICATION_FAILED, DATABASE_ERROR, INVALID_REQUEST, EXECUTION_FAILED)
  • Shared utility class McpTelemetryHelper eliminates duplication
  • Added DynamicCustomTool.EntityName public property to avoid reflection
// Telemetry span wraps tool execution
using Activity? activity = TelemetryTracesHelper.DABActivitySource.StartActivity("mcp.tool.execute");

activity?.TrackMcpToolExecutionStarted(
    toolName: "get_book",
    entityName: "GetBook",
    operation: "execute",
    dbProcedure: "dbo.GetBookById");

CallToolResult result = await tool.ExecuteAsync(arguments, serviceProvider, ct);

activity?.TrackMcpToolExecutionFinished();

How was this tested?

  • Unit Tests

Sample Request(s)

N/A - telemetry instrumentation is transparent to API consumers. Spans are emitted to configured OpenTelemetry exporters.

Original prompt

This section details on the original issue you should resolve

<issue_title>MCP Custom Tool Telemetry</issue_title>
<issue_description>This is to add telemetry for custom tools. Details are present in review comments from a previous PR- #3048 (comment)


// copied from review comments

Please add explicit OpenTelemetry tracing for custom stored-procedure MCP tools.

Scope: DynamicCustomTool.ExecuteAsync(...)

Requirements:

Create an Activity/span around each tool invocation (e.g., span name mcp.tool.call or dab.mcp.custom_tool.execute).
Add span attributes/tags at minimum:
mcp.tool.name = tool name
dab.entity = entity alias/name
dab.operation = execute
db.procedure (or equivalent) = stored procedure name / db object (schema-qualified if available)
Record outcome on the span:
mark success vs failure (ActivityStatusCode.Ok / Error)
on exceptions, record the exception on the span and include an error message/code where available.
Notes:

Logging via ILogger is not sufficient; the tool should emit tracing spans directly.
Ensure spans are created for both success and failure paths (including auth/validation failures).

Please implement OpenTelemetry tracing for MCP tool execution centrally to avoid duplicating instrumentation in every tool.

Goal: Every MCP tools/call invocation (built-in DML tools and dynamic custom stored-proc tools) emits a consistent span.

General idea:

Add instrumentation in the MCP dispatcher / tool execution entry point (the code path that resolves the tool by name and invokes IMcpTool.ExecuteAsync).
Start an Activity span for each tool call (e.g., mcp.tool.call / dab.mcp.tool.execute) and ensure it wraps the entire execution including auth/validation and query execution.
Apply standard tags (e.g., mcp.tool.name, dab.entity when applicable, dab.operation, db.procedure when applicable).
Set span status to Ok/Error and record exceptions.</issue_description>

Comments on the Issue (you are @copilot in this section)

@JerryNixon ## MCP Custom Tool Telemetry

Use Existing Infrastructure

The codebase already has telemetry patterns you should follow:

Centralize, Don't Duplicate

Instrument at the MCP dispatcher level (where tools are resolved and ExecuteAsync is invoked) — not inside each individual tool. This ensures consistent spans for all MCP tools without code duplication.

Required Span Attributes

Attribute Description
mcp.tool.name Tool name
dab.entity Entity alias/name (when applicable)
dab.operation Operation type (e.g., execute)
db.procedure Stored procedure name (schema-qualified if available)

Outcome Recording

  • Success: Set ActivityStatusCode.Ok
  • Failure: Set ActivityStatusCode.Error, call RecordException(), and include error.code/error.message tags

Coverage

Spans must cover all paths:

  • Successful execution
  • Auth/validation failures
  • Database/execution errors

Reference

Follow the pattern in ExecutionHelper where DABActivitySource.StartActivity() wraps query execution and then you can apply the same approach to MCP tool calls.</comment_new>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits February 6, 2026 08:11
Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
…EntityName property

Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
Copilot AI changed the title [WIP] Add OpenTelemetry tracing for custom tools Add OpenTelemetry tracing for MCP tool execution Feb 6, 2026
Copilot AI requested a review from souvikghosh04 February 6, 2026 08:29
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.

MCP Custom Tool Telemetry

2 participants