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
JavaScript
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
};