UNPKG

mcp-use

Version:

Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents and Clients + MCP Servers with support for MCP-UI.

251 lines (248 loc) 8.7 kB
import { logger } from "./chunk-34R6SIER.js"; import { __name } from "./chunk-3GQAWCBQ.js"; // src/observability/langfuse.ts import { config } from "dotenv"; config(); var langfuseDisabled = process.env.MCP_USE_LANGFUSE?.toLowerCase() === "false"; var langfuseState = { handler: null, client: null, initPromise: null }; async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvider) { try { const langfuseModule = await import("langfuse-langchain").catch(() => null); if (!langfuseModule) { logger.debug( "Langfuse package not installed - tracing disabled. Install with: npm install @langfuse/langchain" ); return; } const { CallbackHandler } = langfuseModule; class LoggingCallbackHandler extends CallbackHandler { static { __name(this, "LoggingCallbackHandler"); } agentId; metadata; metadataProvider; tagsProvider; verbose; constructor(config3, agentId2, metadata2, metadataProvider2, tagsProvider2) { super(config3); this.agentId = agentId2; this.metadata = metadata2; this.metadataProvider = metadataProvider2; this.tagsProvider = tagsProvider2; this.verbose = config3?.verbose ?? false; } // Override to add custom metadata to traces async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata2, name, kwargs) { logger.debug("Langfuse: Chain start intercepted"); const customTags = this.getCustomTags(); const metadataToAdd = this.getMetadata(); const enhancedTags = [...tags || [], ...customTags]; const enhancedMetadata = { ...metadata2 || {}, ...metadataToAdd }; if (this.verbose) { logger.debug( `Langfuse: Chain start with custom tags: ${JSON.stringify(enhancedTags)}` ); logger.debug( `Langfuse: Chain start with metadata: ${JSON.stringify(enhancedMetadata)}` ); } return super.handleChainStart( chain, inputs, runId, parentRunId, enhancedTags, enhancedMetadata, name, kwargs ); } // Get custom tags based on environment and agent configuration getCustomTags() { const tags = []; const env = this.getEnvironmentTag(); if (env) { tags.push(`env:${env}`); } if (this.agentId) { tags.push(`agent_id:${this.agentId}`); } if (this.tagsProvider) { const providerTags = this.tagsProvider(); if (providerTags && providerTags.length > 0) { tags.push(...providerTags); } } return tags; } // Get metadata getMetadata() { const metadata2 = {}; const env = this.getEnvironmentTag(); if (env) { metadata2.env = env; } if (this.agentId) { metadata2.agent_id = this.agentId; } if (this.metadata) { Object.assign(metadata2, this.metadata); } if (this.metadataProvider) { const dynamicMetadata = this.metadataProvider(); if (dynamicMetadata) { Object.assign(metadata2, dynamicMetadata); } } return metadata2; } // Determine environment tag based on MCP_USE_AGENT_ENV getEnvironmentTag() { const agentEnv = process.env.MCP_USE_AGENT_ENV; if (!agentEnv) { return "unknown"; } const envLower = agentEnv.toLowerCase(); if (envLower === "local" || envLower === "development") { return "local"; } else if (envLower === "production" || envLower === "prod") { return "production"; } else if (envLower === "staging" || envLower === "stage") { return "staging"; } else if (envLower === "hosted" || envLower === "cloud") { return "hosted"; } return envLower.replace(/[^a-z0-9_-]/g, "_"); } async handleLLMStart(...args) { logger.debug("Langfuse: LLM start intercepted"); if (this.verbose) { logger.debug(`Langfuse: LLM start args: ${JSON.stringify(args)}`); } return super.handleLLMStart(...args); } async handleToolStart(...args) { logger.debug("Langfuse: Tool start intercepted"); if (this.verbose) { logger.debug(`Langfuse: Tool start args: ${JSON.stringify(args)}`); } return super.handleToolStart(...args); } async handleRetrieverStart(...args) { logger.debug("Langfuse: Retriever start intercepted"); if (this.verbose) { logger.debug( `Langfuse: Retriever start args: ${JSON.stringify(args)}` ); } return super.handleRetrieverStart(...args); } async handleAgentAction(...args) { logger.debug("Langfuse: Agent action intercepted"); if (this.verbose) { logger.debug(`Langfuse: Agent action args: ${JSON.stringify(args)}`); } return super.handleAgentAction(...args); } async handleAgentEnd(...args) { logger.debug("Langfuse: Agent end intercepted"); if (this.verbose) { logger.debug(`Langfuse: Agent end args: ${JSON.stringify(args)}`); } return super.handleAgentEnd(...args); } } const initialMetadata = metadata || (metadataProvider ? metadataProvider() : {}); const initialTags = tagsProvider ? tagsProvider() : []; const config2 = { publicKey: process.env.LANGFUSE_PUBLIC_KEY, secretKey: process.env.LANGFUSE_SECRET_KEY, baseUrl: process.env.LANGFUSE_HOST || process.env.LANGFUSE_BASEURL || "https://cloud.langfuse.com", flushAt: Number.parseInt(process.env.LANGFUSE_FLUSH_AT || "15"), flushInterval: Number.parseInt( process.env.LANGFUSE_FLUSH_INTERVAL || "10000" ), release: process.env.LANGFUSE_RELEASE, requestTimeout: Number.parseInt( process.env.LANGFUSE_REQUEST_TIMEOUT || "10000" ), enabled: process.env.LANGFUSE_ENABLED !== "false", // Set trace name - can be customized via metadata.trace_name or defaults to 'mcp-use-agent' traceName: initialMetadata.trace_name || process.env.LANGFUSE_TRACE_NAME || "mcp-use-agent", // Pass sessionId, userId, and tags to the handler sessionId: initialMetadata.session_id || void 0, userId: initialMetadata.user_id || void 0, tags: initialTags.length > 0 ? initialTags : void 0, metadata: initialMetadata || void 0 }; logger.debug( "Langfuse handler config:", JSON.stringify( { traceName: config2.traceName, sessionId: config2.sessionId, userId: config2.userId, tags: config2.tags }, null, 2 ) ); langfuseState.handler = new LoggingCallbackHandler( config2, agentId, metadata, metadataProvider, tagsProvider ); logger.debug( "Langfuse observability initialized successfully with logging enabled" ); try { const langfuseCore = await import("langfuse").catch(() => null); if (langfuseCore) { const { Langfuse } = langfuseCore; langfuseState.client = new Langfuse({ publicKey: process.env.LANGFUSE_PUBLIC_KEY, secretKey: process.env.LANGFUSE_SECRET_KEY, baseUrl: process.env.LANGFUSE_HOST || "https://cloud.langfuse.com" }); logger.debug("Langfuse client initialized"); } } catch (error) { logger.debug(`Langfuse client initialization failed: ${error}`); } } catch (error) { logger.debug(`Langfuse initialization error: ${error}`); } } __name(initializeLangfuse, "initializeLangfuse"); if (langfuseDisabled) { logger.debug( "Langfuse tracing disabled via MCP_USE_LANGFUSE environment variable" ); } else if (!process.env.LANGFUSE_PUBLIC_KEY || !process.env.LANGFUSE_SECRET_KEY) { logger.debug( "Langfuse API keys not found - tracing disabled. Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY to enable" ); } else { langfuseState.initPromise = initializeLangfuse(); } var langfuseHandler = /* @__PURE__ */ __name(() => langfuseState.handler, "langfuseHandler"); var langfuseClient = /* @__PURE__ */ __name(() => langfuseState.client, "langfuseClient"); var langfuseInitPromise = /* @__PURE__ */ __name(() => langfuseState.initPromise, "langfuseInitPromise"); export { initializeLangfuse, langfuseHandler, langfuseClient, langfuseInitPromise };