Context
Instrument the 3 MCP tool handlers with invocation count, duration, and error metrics. This enables use cases B1 (error rate alerting) and C1 (latency monitoring).
Scope
Declare shared metric instruments
In internal/mcp/tools/ (e.g., in a new metrics.go or in get_processed_document.go alongside the existing shared errOAuthTokenNotFound constant):
unstructured_data_mcp_tool_invocations_total — Counter — attributes: tool_name, status
unstructured_data_mcp_tool_duration_seconds — Histogram — attributes: tool_name
unstructured_data_mcp_tool_errors_total — Counter — attributes: tool_name, error_type
Using otel.Meter("mcp.tools") — no-op if telemetry is disabled.
Instrument each tool handler
Files: list_pipelines.go, get_chunks.go, get_processed_document.go
Pattern — named return values + defer (Go equivalent of Python's @instrument_mcp_tool):
func(ctx context.Context, ...) (result *mcp.CallToolResult, aux any, retErr error) {
start := time.Now()
defer func() {
status := "success"
if result != nil && result.IsError { status = "error" }
toolInvocations.Add(ctx, 1, metric.WithAttributes(
attribute.String("tool_name", "..."),
attribute.String("status", status),
))
toolDuration.Record(ctx, time.Since(start).Seconds(), metric.WithAttributes(
attribute.String("tool_name", "..."),
))
}()
// ... existing handler code unchanged ...
}
Existing handler logic is not modified — only the function signature changes to named returns and a defer block is added.
Verification
make lint passes
make test passes
- With
ENABLE_OTEL=true OTEL_METRICS_EXPORTER=console, call a tool → see unstructured_data_mcp_tool_invocations_total and unstructured_data_mcp_tool_duration_seconds in terminal output
Depends on
Context
Instrument the 3 MCP tool handlers with invocation count, duration, and error metrics. This enables use cases B1 (error rate alerting) and C1 (latency monitoring).
Scope
Declare shared metric instruments
In
internal/mcp/tools/(e.g., in a newmetrics.goor inget_processed_document.goalongside the existing sharederrOAuthTokenNotFoundconstant):Using
otel.Meter("mcp.tools")— no-op if telemetry is disabled.Instrument each tool handler
Files:
list_pipelines.go,get_chunks.go,get_processed_document.goPattern — named return values + defer (Go equivalent of Python's
@instrument_mcp_tool):Existing handler logic is not modified — only the function signature changes to named returns and a defer block is added.
Verification
make lintpassesmake testpassesENABLE_OTEL=true OTEL_METRICS_EXPORTER=console, call a tool → seeunstructured_data_mcp_tool_invocations_totalandunstructured_data_mcp_tool_duration_secondsin terminal outputDepends on