Initial implementation of opentelemetry-llm tool

This commit is contained in:
2025-07-14 16:27:29 -05:00
parent 63cf87a6c6
commit 1f201a093f
14 changed files with 3191 additions and 61 deletions

View File

@@ -0,0 +1,91 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { Logger } from '../utils/logger.util.js';
import { formatErrorForMcpTool } from '../utils/error.util.js';
import { OpenTelemetryService } from '../services/opentelemetry-llm.service.js';
import { OpenTelemetryController } from '../controllers/opentelemetry-llm.controller.js';
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import {
OpenTelemetryLlmInputSchema,
OpenTelemetryLlmInputSchemaType,
} from '../types/opentelemetry-llm.types.js';
import { OpenTelemetryConfig } from '../config/opentelemetry-llm.config.js';
/**
* @function captureOpenTelemetryLlmObservability
* @description MCP Tool handler to capture LLM observability events using OpenTelemetry.
* It records metrics, traces, and spans for LLM requests that can be sent to any OpenTelemetry-compatible backend.
* @param {OpenTelemetryLlmInputSchemaType} args - Arguments provided to the tool.
* @returns {Promise<CallToolResult>} Formatted response for the MCP.
* @throws {McpError} Formatted error if the controller or service layer encounters an issue.
*/
async function captureOpenTelemetryLlmObservability(
args: OpenTelemetryLlmInputSchemaType,
): Promise<CallToolResult> {
const methodLogger = Logger.forContext(
'opentelemetry.tool',
'captureOpenTelemetryLlmObservability',
);
methodLogger.debug('Capture LLM Observability with OpenTelemetry...', args);
try {
// Parse and validate arguments
const validatedArgs = OpenTelemetryLlmInputSchema.parse(args);
// Ensure OpenTelemetry is configured
const config = OpenTelemetryConfig.fromEnv();
const service = OpenTelemetryService.getInstance(config);
// Initialize if not already done
service.initialize();
// Create controller with the service
const controller = new OpenTelemetryController(service);
// Pass validated args to the controller
const result = await controller.captureLlmObservability(validatedArgs);
methodLogger.debug('Got response from controller', result);
// Format the response for the MCP tool
return {
content: [
{
type: 'text' as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error(
'Error tracking LLM generation with OpenTelemetry',
error,
);
return formatErrorForMcpTool(error);
}
}
/**
* @function registerTools
* @description Registers the OpenTelemetry LLM observability tool with the MCP server.
*
* @param {McpServer} server - The MCP server instance.
*/
function registerTools(server: McpServer) {
const methodLogger = Logger.forContext(
'opentelemetry.tool',
'registerTools',
);
methodLogger.debug('Registering OpenTelemetry LLM observability tools...');
server.tool(
'capture_llm_observability_opentelemetry',
`Captures LLM usage using OpenTelemetry for observability, including requests, responses, and performance metrics. Works with any OpenTelemetry-compatible backend like Jaeger, New Relic, Grafana, etc.`,
OpenTelemetryLlmInputSchema.shape,
captureOpenTelemetryLlmObservability,
);
methodLogger.debug(
'Successfully registered capture_llm_observability_opentelemetry tool.',
);
}
export default { registerTools };