Skip to main content
Glama
cameronsjo

MCP Server Template

by cameronsjo
instrumentation.ts3.18 kB
/** * Observability instrumentation (Sentry + OpenTelemetry) * * MUST be imported before any other modules to ensure proper instrumentation. * Initializes Sentry for error tracking and OpenTelemetry for distributed tracing. */ import * as Sentry from '@sentry/node'; import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { Resource } from '@opentelemetry/resources'; import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions'; import { getConfig } from './config/index.js'; import { sanitizePii } from './shared/pii-sanitizer.js'; const config = getConfig(); /** * Initialize Sentry error tracking */ function initSentry(): void { if (!config.sentryDsn) { return; } Sentry.init({ dsn: config.sentryDsn, environment: process.env['NODE_ENV'] ?? 'development', release: config.serverVersion, // Performance monitoring tracesSampleRate: config.debugMode ? 1.0 : 0.1, // PII filtering beforeSend(event) { // Sanitize error messages if (event.message) { event.message = sanitizePii(event.message); } // Sanitize breadcrumbs if (event.breadcrumbs) { for (const breadcrumb of event.breadcrumbs) { if (breadcrumb.message) { breadcrumb.message = sanitizePii(breadcrumb.message); } } } return event; }, // Filter sensitive data beforeSendTransaction(event) { // Remove sensitive headers if (event.request?.headers) { const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key']; for (const header of sensitiveHeaders) { if (header in event.request.headers) { event.request.headers[header] = '[REDACTED]'; } } } return event; }, }); console.error(`[instrumentation] Sentry initialized`); } /** * Initialize OpenTelemetry tracing */ let otelSdk: NodeSDK | null = null; function initOpenTelemetry(): void { if (!config.otelEnabled) { return; } const resource = new Resource({ [ATTR_SERVICE_NAME]: config.serverName, [ATTR_SERVICE_VERSION]: config.serverVersion, }); const traceExporter = config.otelEndpoint ? new OTLPTraceExporter({ url: config.otelEndpoint }) : undefined; otelSdk = new NodeSDK({ resource, traceExporter, instrumentations: [ getNodeAutoInstrumentations({ // Disable fs instrumentation (too noisy) '@opentelemetry/instrumentation-fs': { enabled: false }, }), ], }); otelSdk.start(); console.error(`[instrumentation] OpenTelemetry initialized`); } /** * Shutdown observability (for graceful exit) */ export async function shutdownObservability(): Promise<void> { const promises: Promise<void>[] = []; if (otelSdk) { promises.push(otelSdk.shutdown()); } promises.push(Sentry.close(2000).then(() => undefined)); await Promise.all(promises); } // Initialize on import initSentry(); initOpenTelemetry();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cameronsjo/mcp-server-template'

If you have feedback or need assistance with the MCP directory API, please join our Discord server