mcp-use 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/src/agents/index.d.ts +1 -0
- package/dist/src/agents/index.d.ts.map +1 -1
- package/dist/src/agents/index.js +1 -0
- package/dist/src/agents/mcp_agent.d.ts +11 -2
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/mcp_agent.js +120 -13
- package/dist/src/agents/remote.d.ts +23 -0
- package/dist/src/agents/remote.d.ts.map +1 -0
- package/dist/src/agents/remote.js +264 -0
- package/dist/src/observability/index.d.ts +10 -0
- package/dist/src/observability/index.d.ts.map +1 -0
- package/dist/src/observability/index.js +12 -0
- package/dist/src/observability/langfuse.d.ts +11 -0
- package/dist/src/observability/langfuse.d.ts.map +1 -0
- package/dist/src/observability/langfuse.js +123 -0
- package/dist/src/observability/manager.d.ts +74 -0
- package/dist/src/observability/manager.d.ts.map +1 -0
- package/dist/src/observability/manager.js +167 -0
- package/dist/src/observability/types.d.ts +42 -0
- package/dist/src/observability/types.d.ts.map +1 -0
- package/dist/src/observability/types.js +4 -0
- package/package.json +15 -5
package/README.md
CHANGED
@@ -61,6 +61,9 @@
|
|
61
61
|
npm install mcp-use
|
62
62
|
# LangChain.js and your LLM provider (e.g., OpenAI)
|
63
63
|
npm install langchain @langchain/openai dotenv
|
64
|
+
|
65
|
+
# Optional: Install observability packages for monitoring
|
66
|
+
npm install langfuse langfuse-langchain # For Langfuse observability
|
64
67
|
```
|
65
68
|
|
66
69
|
Create a `.env`:
|
package/dist/index.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { MCPAgent } from './src/agents/mcp_agent.js';
|
2
|
+
import { RemoteAgent } from './src/agents/remote.js';
|
2
3
|
import { MCPClient } from './src/client.js';
|
3
4
|
import { loadConfigFile } from './src/config.js';
|
4
5
|
import { BaseConnector } from './src/connectors/base.js';
|
@@ -14,5 +15,5 @@ export * from './src/managers/tools/index.js';
|
|
14
15
|
export { setTelemetrySource, Telemetry } from './src/telemetry/index.js';
|
15
16
|
export { AIMessage, BaseMessage, HumanMessage, SystemMessage, ToolMessage } from '@langchain/core/messages';
|
16
17
|
export type { StreamEvent } from '@langchain/core/tracers/log_stream';
|
17
|
-
export { BaseConnector, HttpConnector, loadConfigFile, Logger, logger, MCPAgent, MCPClient, MCPSession, StdioConnector, WebSocketConnector };
|
18
|
+
export { BaseConnector, HttpConnector, loadConfigFile, Logger, logger, MCPAgent, MCPClient, MCPSession, RemoteAgent, StdioConnector, WebSocketConnector };
|
18
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAEvE,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAEhE,cAAc,+BAA+B,CAAA;AAG7C,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGxE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3G,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAA"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAEvE,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAEhE,cAAc,+BAA+B,CAAA;AAG7C,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGxE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3G,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAA"}
|
package/dist/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { MCPAgent } from './src/agents/mcp_agent.js';
|
2
|
+
import { RemoteAgent } from './src/agents/remote.js';
|
2
3
|
import { MCPClient } from './src/client.js';
|
3
4
|
import { loadConfigFile } from './src/config.js';
|
4
5
|
import { BaseConnector } from './src/connectors/base.js';
|
@@ -16,4 +17,4 @@ export * from './src/managers/tools/index.js';
|
|
16
17
|
export { setTelemetrySource, Telemetry } from './src/telemetry/index.js';
|
17
18
|
// Re-export message classes to ensure a single constructor instance is shared by consumers
|
18
19
|
export { AIMessage, BaseMessage, HumanMessage, SystemMessage, ToolMessage } from '@langchain/core/messages';
|
19
|
-
export { BaseConnector, HttpConnector, loadConfigFile, Logger, logger, MCPAgent, MCPClient, MCPSession, StdioConnector, WebSocketConnector };
|
20
|
+
export { BaseConnector, HttpConnector, loadConfigFile, Logger, logger, MCPAgent, MCPClient, MCPSession, RemoteAgent, StdioConnector, WebSocketConnector };
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/src/agents/index.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
1
2
|
import type { BaseLanguageModelInterface } from '@langchain/core/language_models/base';
|
2
3
|
import type { BaseMessage } from '@langchain/core/messages';
|
3
4
|
import type { StructuredToolInterface } from '@langchain/core/tools';
|
@@ -10,7 +11,7 @@ import { SystemMessage } from '@langchain/core/messages';
|
|
10
11
|
import { LangChainAdapter } from '../adapters/langchain_adapter.js';
|
11
12
|
import { ServerManager } from '../managers/server_manager.js';
|
12
13
|
export declare class MCPAgent {
|
13
|
-
private llm
|
14
|
+
private llm?;
|
14
15
|
private client?;
|
15
16
|
private connectors;
|
16
17
|
private maxSteps;
|
@@ -34,8 +35,12 @@ export declare class MCPAgent {
|
|
34
35
|
private telemetry;
|
35
36
|
private modelProvider;
|
36
37
|
private modelName;
|
38
|
+
private observabilityManager;
|
39
|
+
private callbacks;
|
40
|
+
private isRemote;
|
41
|
+
private remoteAgent;
|
37
42
|
constructor(options: {
|
38
|
-
llm
|
43
|
+
llm?: BaseLanguageModelInterface;
|
39
44
|
client?: MCPClient;
|
40
45
|
connectors?: BaseConnector[];
|
41
46
|
maxSteps?: number;
|
@@ -50,6 +55,10 @@ export declare class MCPAgent {
|
|
50
55
|
verbose?: boolean;
|
51
56
|
adapter?: LangChainAdapter;
|
52
57
|
serverManagerFactory?: (client: MCPClient) => ServerManager;
|
58
|
+
callbacks?: BaseCallbackHandler[];
|
59
|
+
agentId?: string;
|
60
|
+
apiKey?: string;
|
61
|
+
baseUrl?: string;
|
53
62
|
});
|
54
63
|
initialize(): Promise<void>;
|
55
64
|
private createSystemMessageFromTools;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAqB,MAAM,sCAAsC,CAAA;
|
1
|
+
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
|
@@ -1,14 +1,17 @@
|
|
1
|
+
import { CallbackManager } from '@langchain/core/callbacks/manager';
|
1
2
|
import { AIMessage, HumanMessage, SystemMessage, ToolMessage, } from '@langchain/core/messages';
|
2
3
|
import { OutputParserException } from '@langchain/core/output_parsers';
|
3
4
|
import { ChatPromptTemplate, MessagesPlaceholder, } from '@langchain/core/prompts';
|
4
|
-
import { AgentExecutor, createToolCallingAgent
|
5
|
+
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents';
|
5
6
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
6
7
|
import { LangChainAdapter } from '../adapters/langchain_adapter.js';
|
7
8
|
import { logger } from '../logging.js';
|
8
9
|
import { ServerManager } from '../managers/server_manager.js';
|
10
|
+
import { ObservabilityManager } from '../observability/index.js';
|
9
11
|
import { extractModelInfo, Telemetry } from '../telemetry/index.js';
|
10
12
|
import { createSystemMessage } from './prompts/system_prompt_builder.js';
|
11
13
|
import { DEFAULT_SYSTEM_PROMPT_TEMPLATE, SERVER_MANAGER_SYSTEM_PROMPT_TEMPLATE } from './prompts/templates.js';
|
14
|
+
import { RemoteAgent } from './remote.js';
|
12
15
|
export class MCPAgent {
|
13
16
|
llm;
|
14
17
|
client;
|
@@ -34,7 +37,42 @@ export class MCPAgent {
|
|
34
37
|
telemetry;
|
35
38
|
modelProvider;
|
36
39
|
modelName;
|
40
|
+
// Observability support
|
41
|
+
observabilityManager;
|
42
|
+
callbacks = [];
|
43
|
+
// Remote agent support
|
44
|
+
isRemote = false;
|
45
|
+
remoteAgent = null;
|
37
46
|
constructor(options) {
|
47
|
+
// Handle remote execution
|
48
|
+
if (options.agentId) {
|
49
|
+
this.isRemote = true;
|
50
|
+
this.remoteAgent = new RemoteAgent({
|
51
|
+
agentId: options.agentId,
|
52
|
+
apiKey: options.apiKey,
|
53
|
+
baseUrl: options.baseUrl,
|
54
|
+
});
|
55
|
+
// Set default values for remote agent
|
56
|
+
this.maxSteps = options.maxSteps ?? 5;
|
57
|
+
this.memoryEnabled = options.memoryEnabled ?? true;
|
58
|
+
this.autoInitialize = options.autoInitialize ?? false;
|
59
|
+
this.verbose = options.verbose ?? false;
|
60
|
+
this.connectors = [];
|
61
|
+
this.disallowedTools = [];
|
62
|
+
this.additionalTools = [];
|
63
|
+
this.useServerManager = false;
|
64
|
+
this.adapter = new LangChainAdapter();
|
65
|
+
this.telemetry = Telemetry.getInstance();
|
66
|
+
this.modelProvider = 'remote';
|
67
|
+
this.modelName = 'remote-agent';
|
68
|
+
this.observabilityManager = new ObservabilityManager({ customCallbacks: options.callbacks });
|
69
|
+
this.callbacks = [];
|
70
|
+
return;
|
71
|
+
}
|
72
|
+
// Validate requirements for local execution
|
73
|
+
if (!options.llm) {
|
74
|
+
throw new Error('llm is required for local execution. For remote execution, provide agentId instead.');
|
75
|
+
}
|
38
76
|
this.llm = options.llm;
|
39
77
|
this.client = options.client;
|
40
78
|
this.connectors = options.connectors ?? [];
|
@@ -65,9 +103,20 @@ export class MCPAgent {
|
|
65
103
|
// Initialize telemetry
|
66
104
|
this.telemetry = Telemetry.getInstance();
|
67
105
|
// Track model info for telemetry
|
68
|
-
|
69
|
-
|
70
|
-
|
106
|
+
if (this.llm) {
|
107
|
+
const [provider, name] = extractModelInfo(this.llm);
|
108
|
+
this.modelProvider = provider;
|
109
|
+
this.modelName = name;
|
110
|
+
}
|
111
|
+
else {
|
112
|
+
this.modelProvider = 'unknown';
|
113
|
+
this.modelName = 'unknown';
|
114
|
+
}
|
115
|
+
// Set up observability callbacks using the ObservabilityManager
|
116
|
+
this.observabilityManager = new ObservabilityManager({
|
117
|
+
customCallbacks: options.callbacks,
|
118
|
+
verbose: this.verbose,
|
119
|
+
});
|
71
120
|
// Make getters configurable for test mocking
|
72
121
|
Object.defineProperty(this, 'agentExecutor', {
|
73
122
|
get: () => this._agentExecutor,
|
@@ -83,7 +132,18 @@ export class MCPAgent {
|
|
83
132
|
});
|
84
133
|
}
|
85
134
|
async initialize() {
|
135
|
+
// Skip initialization for remote agents
|
136
|
+
if (this.isRemote) {
|
137
|
+
this._initialized = true;
|
138
|
+
return;
|
139
|
+
}
|
86
140
|
logger.info('🚀 Initializing MCP agent and connecting to services...');
|
141
|
+
// Initialize observability callbacks
|
142
|
+
this.callbacks = await this.observabilityManager.getCallbacks();
|
143
|
+
const handlerNames = await this.observabilityManager.getHandlerNames();
|
144
|
+
if (handlerNames.length > 0) {
|
145
|
+
logger.info(`📊 Observability enabled with: ${handlerNames.join(', ')}`);
|
146
|
+
}
|
87
147
|
// If using server manager, initialize it
|
88
148
|
if (this.useServerManager && this.serverManager) {
|
89
149
|
await this.serverManager.initialize();
|
@@ -99,7 +159,7 @@ export class MCPAgent {
|
|
99
159
|
// Standard initialization - if using client, get or create sessions
|
100
160
|
if (this.client) {
|
101
161
|
// First try to get existing sessions
|
102
|
-
this.sessions =
|
162
|
+
this.sessions = this.client.getAllActiveSessions();
|
103
163
|
logger.info(`🔌 Found ${Object.keys(this.sessions).length} existing sessions`);
|
104
164
|
// If no active sessions exist, create new ones
|
105
165
|
if (Object.keys(this.sessions).length === 0) {
|
@@ -147,6 +207,9 @@ export class MCPAgent {
|
|
147
207
|
}
|
148
208
|
}
|
149
209
|
createAgent() {
|
210
|
+
if (!this.llm) {
|
211
|
+
throw new Error('LLM is required to create agent');
|
212
|
+
}
|
150
213
|
const systemContent = this.systemMessage?.content ?? 'You are a helpful assistant.';
|
151
214
|
const prompt = ChatPromptTemplate.fromMessages([
|
152
215
|
['system', systemContent],
|
@@ -165,6 +228,7 @@ export class MCPAgent {
|
|
165
228
|
maxIterations: this.maxSteps,
|
166
229
|
verbose: this.verbose,
|
167
230
|
returnIntermediateSteps: true,
|
231
|
+
callbacks: this.callbacks,
|
168
232
|
});
|
169
233
|
}
|
170
234
|
getConversationHistory() {
|
@@ -213,6 +277,10 @@ export class MCPAgent {
|
|
213
277
|
}
|
214
278
|
}
|
215
279
|
async run(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
280
|
+
// Delegate to remote agent if in remote mode
|
281
|
+
if (this.isRemote && this.remoteAgent) {
|
282
|
+
return this.remoteAgent.run(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
283
|
+
}
|
216
284
|
const generator = this.stream(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
217
285
|
return this._consumeAndReturn(generator);
|
218
286
|
}
|
@@ -221,6 +289,11 @@ export class MCPAgent {
|
|
221
289
|
* If outputSchema is provided, returns structured output of type T.
|
222
290
|
*/
|
223
291
|
async *stream(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
|
292
|
+
// Delegate to remote agent if in remote mode
|
293
|
+
if (this.isRemote && this.remoteAgent) {
|
294
|
+
const result = await this.remoteAgent.run(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
295
|
+
return result;
|
296
|
+
}
|
224
297
|
let result = '';
|
225
298
|
let initializedHere = false;
|
226
299
|
const startTime = Date.now();
|
@@ -234,13 +307,16 @@ export class MCPAgent {
|
|
234
307
|
query = this._enhanceQueryWithSchema(query, outputSchema);
|
235
308
|
logger.debug(`🔄 Structured output requested, schema: ${JSON.stringify(zodToJsonSchema(outputSchema), null, 2)}`);
|
236
309
|
// Check if withStructuredOutput method exists
|
237
|
-
if ('withStructuredOutput' in this.llm && typeof this.llm.withStructuredOutput === 'function') {
|
310
|
+
if (this.llm && 'withStructuredOutput' in this.llm && typeof this.llm.withStructuredOutput === 'function') {
|
238
311
|
structuredLlm = this.llm.withStructuredOutput(outputSchema);
|
239
312
|
}
|
240
|
-
else {
|
313
|
+
else if (this.llm) {
|
241
314
|
// Fallback: use the same LLM but we'll handle structure in our helper method
|
242
315
|
structuredLlm = this.llm;
|
243
316
|
}
|
317
|
+
else {
|
318
|
+
throw new Error('LLM is required for structured output');
|
319
|
+
}
|
244
320
|
schemaDescription = JSON.stringify(zodToJsonSchema(outputSchema), null, 2);
|
245
321
|
}
|
246
322
|
try {
|
@@ -274,6 +350,22 @@ export class MCPAgent {
|
|
274
350
|
const inputs = { input: query, chat_history: langchainHistory };
|
275
351
|
let nameToToolMap = Object.fromEntries(this._tools.map(t => [t.name, t]));
|
276
352
|
logger.info(`🏁 Starting agent execution with max_steps=${steps}`);
|
353
|
+
// Create a run manager with our callbacks if we have any - ONCE for the entire execution
|
354
|
+
let runManager;
|
355
|
+
if (this.callbacks?.length > 0) {
|
356
|
+
// Create an async callback manager with our callbacks
|
357
|
+
const callbackManager = new CallbackManager(undefined, {
|
358
|
+
handlers: this.callbacks,
|
359
|
+
inheritableHandlers: this.callbacks,
|
360
|
+
});
|
361
|
+
// Create a run manager for this chain execution
|
362
|
+
runManager = await callbackManager.handleChainStart({
|
363
|
+
name: 'MCPAgent (mcp-use)',
|
364
|
+
id: ['MCPAgent (mcp-use)'],
|
365
|
+
lc: 1,
|
366
|
+
type: 'not_implemented',
|
367
|
+
}, inputs);
|
368
|
+
}
|
277
369
|
for (let stepNum = 0; stepNum < steps; stepNum++) {
|
278
370
|
stepsTaken = stepNum + 1;
|
279
371
|
if (this.useServerManager && this.serverManager) {
|
@@ -295,11 +387,12 @@ export class MCPAgent {
|
|
295
387
|
logger.info(`👣 Step ${stepNum + 1}/${steps}`);
|
296
388
|
try {
|
297
389
|
logger.debug('Starting agent step execution');
|
298
|
-
const nextStepOutput = await this._agentExecutor._takeNextStep(nameToToolMap, inputs, intermediateSteps);
|
299
|
-
// Agent finish handling
|
300
|
-
if (nextStepOutput
|
390
|
+
const nextStepOutput = await this._agentExecutor._takeNextStep(nameToToolMap, inputs, intermediateSteps, runManager);
|
391
|
+
// Agent finish handling (AgentFinish contains returnValues property)
|
392
|
+
if ('returnValues' in nextStepOutput) {
|
301
393
|
logger.info(`✅ Agent finished at step ${stepNum + 1}`);
|
302
394
|
result = nextStepOutput.returnValues?.output ?? 'No output generated';
|
395
|
+
runManager?.handleChainEnd({ output: result });
|
303
396
|
// If structured output is requested, attempt to create it
|
304
397
|
if (outputSchema && structuredLlm) {
|
305
398
|
try {
|
@@ -376,11 +469,13 @@ export class MCPAgent {
|
|
376
469
|
if (e instanceof OutputParserException) {
|
377
470
|
logger.error(`❌ Output parsing error during step ${stepNum + 1}: ${e}`);
|
378
471
|
result = `Agent stopped due to a parsing error: ${e}`;
|
472
|
+
runManager?.handleChainError(result);
|
379
473
|
break;
|
380
474
|
}
|
381
475
|
logger.error(`❌ Error during agent execution step ${stepNum + 1}: ${e}`);
|
382
476
|
console.error(e);
|
383
477
|
result = `Agent stopped due to an error: ${e}`;
|
478
|
+
runManager?.handleChainError(result);
|
384
479
|
break;
|
385
480
|
}
|
386
481
|
}
|
@@ -388,6 +483,7 @@ export class MCPAgent {
|
|
388
483
|
if (!result) {
|
389
484
|
logger.warn(`⚠️ Agent stopped after reaching max iterations (${steps})`);
|
390
485
|
result = `Agent stopped after reaching the maximum number of steps (${steps}).`;
|
486
|
+
runManager?.handleChainEnd({ output: result });
|
391
487
|
}
|
392
488
|
logger.info('🎉 Agent execution complete');
|
393
489
|
success = true;
|
@@ -407,7 +503,7 @@ export class MCPAgent {
|
|
407
503
|
const executionTimeMs = Date.now() - startTime;
|
408
504
|
let serverCount = 0;
|
409
505
|
if (this.client) {
|
410
|
-
serverCount = Object.keys(
|
506
|
+
serverCount = Object.keys(this.client.getAllActiveSessions()).length;
|
411
507
|
}
|
412
508
|
else if (this.connectors) {
|
413
509
|
serverCount = this.connectors.length;
|
@@ -444,7 +540,14 @@ export class MCPAgent {
|
|
444
540
|
}
|
445
541
|
}
|
446
542
|
async close() {
|
543
|
+
// Delegate to remote agent if in remote mode
|
544
|
+
if (this.isRemote && this.remoteAgent) {
|
545
|
+
await this.remoteAgent.close();
|
546
|
+
return;
|
547
|
+
}
|
447
548
|
logger.info('🔌 Closing MCPAgent resources…');
|
549
|
+
// Shutdown observability handlers (important for serverless)
|
550
|
+
await this.observabilityManager.shutdown();
|
448
551
|
try {
|
449
552
|
this._agentExecutor = null;
|
450
553
|
this._tools = [];
|
@@ -516,8 +619,12 @@ export class MCPAgent {
|
|
516
619
|
}
|
517
620
|
// Prepare inputs
|
518
621
|
const inputs = { input: query, chat_history: langchainHistory };
|
622
|
+
logger.info('callbacks', this.callbacks);
|
519
623
|
// Stream events from the agent executor
|
520
|
-
const eventStream = agentExecutor.streamEvents(inputs, {
|
624
|
+
const eventStream = agentExecutor.streamEvents(inputs, {
|
625
|
+
version: 'v2',
|
626
|
+
callbacks: this.callbacks.length > 0 ? this.callbacks : undefined,
|
627
|
+
});
|
521
628
|
// Yield each event
|
522
629
|
for await (const event of eventStream) {
|
523
630
|
eventCount++;
|
@@ -558,7 +665,7 @@ export class MCPAgent {
|
|
558
665
|
const executionTimeMs = Date.now() - startTime;
|
559
666
|
let serverCount = 0;
|
560
667
|
if (this.client) {
|
561
|
-
serverCount = Object.keys(
|
668
|
+
serverCount = Object.keys(this.client.getAllActiveSessions()).length;
|
562
669
|
}
|
563
670
|
else if (this.connectors) {
|
564
671
|
serverCount = this.connectors.length;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/**
|
2
|
+
* Remote agent implementation for executing agents via API.
|
3
|
+
*/
|
4
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
5
|
+
import type { ZodSchema } from 'zod';
|
6
|
+
export declare class RemoteAgent {
|
7
|
+
private agentId;
|
8
|
+
private apiKey;
|
9
|
+
private baseUrl;
|
10
|
+
private chatId;
|
11
|
+
constructor(options: {
|
12
|
+
agentId: string;
|
13
|
+
apiKey?: string;
|
14
|
+
baseUrl?: string;
|
15
|
+
});
|
16
|
+
private pydanticToJsonSchema;
|
17
|
+
private parseStructuredResponse;
|
18
|
+
private createChatSession;
|
19
|
+
run<T = string>(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[], outputSchema?: ZodSchema<T>): Promise<T>;
|
20
|
+
stream<T = string>(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[], outputSchema?: ZodSchema<T>): AsyncGenerator<any, T, void>;
|
21
|
+
close(): Promise<void>;
|
22
|
+
}
|
23
|
+
//# sourceMappingURL=remote.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../../src/agents/remote.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAQpC,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAsB;gBAExB,OAAO,EAAE;QACnB,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB;IAgBD,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,uBAAuB;YAoDjB,iBAAiB;IAmDlB,GAAG,CAAC,CAAC,GAAG,MAAM,EACzB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,OAAO,EACzB,eAAe,CAAC,EAAE,WAAW,EAAE,EAC/B,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,CAAC;IAwJC,MAAM,CAAC,CAAC,GAAG,MAAM,EAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,OAAO,EACzB,eAAe,CAAC,EAAE,WAAW,EAAE,EAC/B,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAC1B,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC;IASlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAUpC"}
|
@@ -0,0 +1,264 @@
|
|
1
|
+
/**
|
2
|
+
* Remote agent implementation for executing agents via API.
|
3
|
+
*/
|
4
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
5
|
+
import { logger } from '../logging.js';
|
6
|
+
// API endpoint constants
|
7
|
+
const API_CHATS_ENDPOINT = '/api/v1/chats';
|
8
|
+
const API_CHAT_EXECUTE_ENDPOINT = '/api/v1/chats/{chat_id}/execute';
|
9
|
+
export class RemoteAgent {
|
10
|
+
agentId;
|
11
|
+
apiKey;
|
12
|
+
baseUrl;
|
13
|
+
chatId = null;
|
14
|
+
constructor(options) {
|
15
|
+
this.agentId = options.agentId;
|
16
|
+
this.baseUrl = options.baseUrl ?? 'https://cloud.mcp-use.com';
|
17
|
+
// Handle API key validation
|
18
|
+
const apiKey = options.apiKey ?? process.env.MCP_USE_API_KEY;
|
19
|
+
if (!apiKey) {
|
20
|
+
throw new Error('API key is required for remote execution. '
|
21
|
+
+ 'Please provide it as a parameter or set the MCP_USE_API_KEY environment variable. '
|
22
|
+
+ 'You can get an API key from https://cloud.mcp-use.com');
|
23
|
+
}
|
24
|
+
this.apiKey = apiKey;
|
25
|
+
}
|
26
|
+
pydanticToJsonSchema(schema) {
|
27
|
+
/**
|
28
|
+
* Convert a Zod schema to JSON schema for API transmission.
|
29
|
+
*/
|
30
|
+
return zodToJsonSchema(schema);
|
31
|
+
}
|
32
|
+
parseStructuredResponse(responseData, outputSchema) {
|
33
|
+
/**
|
34
|
+
* Parse the API response into the structured output format.
|
35
|
+
*/
|
36
|
+
let resultData;
|
37
|
+
// Handle different response formats
|
38
|
+
if (typeof responseData === 'object' && responseData !== null) {
|
39
|
+
if ('result' in responseData) {
|
40
|
+
const outerResult = responseData.result;
|
41
|
+
// Check if this is a nested result structure (agent execution response)
|
42
|
+
if (typeof outerResult === 'object' && outerResult !== null && 'result' in outerResult) {
|
43
|
+
// Extract the actual structured output from the nested result
|
44
|
+
resultData = outerResult.result;
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
// Use the outer result directly
|
48
|
+
resultData = outerResult;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
resultData = responseData;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
else if (typeof responseData === 'string') {
|
56
|
+
try {
|
57
|
+
resultData = JSON.parse(responseData);
|
58
|
+
}
|
59
|
+
catch {
|
60
|
+
// If it's not valid JSON, try to create the model from the string content
|
61
|
+
resultData = { content: responseData };
|
62
|
+
}
|
63
|
+
}
|
64
|
+
else {
|
65
|
+
resultData = responseData;
|
66
|
+
}
|
67
|
+
// Parse into the Zod schema
|
68
|
+
try {
|
69
|
+
return outputSchema.parse(resultData);
|
70
|
+
}
|
71
|
+
catch (e) {
|
72
|
+
logger.warn(`Failed to parse structured output: ${e}`);
|
73
|
+
// Fallback: try to parse it as raw content if the schema has a content field
|
74
|
+
const schemaShape = outputSchema._def?.shape();
|
75
|
+
if (schemaShape && 'content' in schemaShape) {
|
76
|
+
return outputSchema.parse({ content: String(resultData) });
|
77
|
+
}
|
78
|
+
throw e;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
async createChatSession() {
|
82
|
+
/**
|
83
|
+
* Create a persistent chat session for the agent.
|
84
|
+
*/
|
85
|
+
const chatPayload = {
|
86
|
+
title: `Remote Agent Session - ${this.agentId}`,
|
87
|
+
agent_id: this.agentId,
|
88
|
+
type: 'agent_execution',
|
89
|
+
};
|
90
|
+
const headers = {
|
91
|
+
'Content-Type': 'application/json',
|
92
|
+
'x-api-key': this.apiKey,
|
93
|
+
};
|
94
|
+
const chatUrl = `${this.baseUrl}${API_CHATS_ENDPOINT}`;
|
95
|
+
logger.info(`📝 Creating chat session for agent ${this.agentId}`);
|
96
|
+
try {
|
97
|
+
const response = await fetch(chatUrl, {
|
98
|
+
method: 'POST',
|
99
|
+
headers,
|
100
|
+
body: JSON.stringify(chatPayload),
|
101
|
+
});
|
102
|
+
if (!response.ok) {
|
103
|
+
const responseText = await response.text();
|
104
|
+
const statusCode = response.status;
|
105
|
+
if (statusCode === 404) {
|
106
|
+
throw new Error(`Agent not found: Agent '${this.agentId}' does not exist or you don't have access to it. `
|
107
|
+
+ 'Please verify the agent ID and ensure it exists in your account.');
|
108
|
+
}
|
109
|
+
throw new Error(`Failed to create chat session: ${statusCode} - ${responseText}`);
|
110
|
+
}
|
111
|
+
const chatData = await response.json();
|
112
|
+
const chatId = chatData.id;
|
113
|
+
logger.info(`✅ Chat session created: ${chatId}`);
|
114
|
+
return chatId;
|
115
|
+
}
|
116
|
+
catch (e) {
|
117
|
+
if (e instanceof Error) {
|
118
|
+
throw new TypeError(`Failed to create chat session: ${e.message}`);
|
119
|
+
}
|
120
|
+
throw new Error(`Failed to create chat session: ${String(e)}`);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
async run(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
124
|
+
/**
|
125
|
+
* Run a query on the remote agent.
|
126
|
+
*/
|
127
|
+
if (externalHistory !== undefined) {
|
128
|
+
logger.warn('External history is not yet supported for remote execution');
|
129
|
+
}
|
130
|
+
try {
|
131
|
+
logger.info(`🌐 Executing query on remote agent ${this.agentId}`);
|
132
|
+
// Step 1: Create a chat session for this agent (only if we don't have one)
|
133
|
+
if (this.chatId === null) {
|
134
|
+
this.chatId = await this.createChatSession();
|
135
|
+
}
|
136
|
+
const chatId = this.chatId;
|
137
|
+
// Step 2: Execute the agent within the chat context
|
138
|
+
const executionPayload = {
|
139
|
+
query,
|
140
|
+
max_steps: maxSteps ?? 10,
|
141
|
+
};
|
142
|
+
// Add structured output schema if provided
|
143
|
+
if (outputSchema) {
|
144
|
+
executionPayload.output_schema = this.pydanticToJsonSchema(outputSchema);
|
145
|
+
logger.info(`🔧 Using structured output with schema`);
|
146
|
+
}
|
147
|
+
const headers = {
|
148
|
+
'Content-Type': 'application/json',
|
149
|
+
'x-api-key': this.apiKey,
|
150
|
+
};
|
151
|
+
const executionUrl = `${this.baseUrl}${API_CHAT_EXECUTE_ENDPOINT.replace('{chat_id}', chatId)}`;
|
152
|
+
logger.info(`🚀 Executing agent in chat ${chatId}`);
|
153
|
+
const response = await fetch(executionUrl, {
|
154
|
+
method: 'POST',
|
155
|
+
headers,
|
156
|
+
body: JSON.stringify(executionPayload),
|
157
|
+
signal: AbortSignal.timeout(300000), // 5 minute timeout
|
158
|
+
});
|
159
|
+
if (!response.ok) {
|
160
|
+
const responseText = await response.text();
|
161
|
+
const statusCode = response.status;
|
162
|
+
// Provide specific error messages based on status code
|
163
|
+
if (statusCode === 401) {
|
164
|
+
logger.error(`❌ Authentication failed: ${responseText}`);
|
165
|
+
throw new Error('Authentication failed: Invalid or missing API key. '
|
166
|
+
+ 'Please check your API key and ensure the MCP_USE_API_KEY environment variable is set correctly.');
|
167
|
+
}
|
168
|
+
else if (statusCode === 403) {
|
169
|
+
logger.error(`❌ Access forbidden: ${responseText}`);
|
170
|
+
throw new Error(`Access denied: You don't have permission to execute agent '${this.agentId}'. `
|
171
|
+
+ 'Check if the agent exists and you have the necessary permissions.');
|
172
|
+
}
|
173
|
+
else if (statusCode === 404) {
|
174
|
+
logger.error(`❌ Agent not found: ${responseText}`);
|
175
|
+
throw new Error(`Agent not found: Agent '${this.agentId}' does not exist or you don't have access to it. `
|
176
|
+
+ 'Please verify the agent ID and ensure it exists in your account.');
|
177
|
+
}
|
178
|
+
else if (statusCode === 422) {
|
179
|
+
logger.error(`❌ Validation error: ${responseText}`);
|
180
|
+
throw new Error(`Request validation failed: ${responseText}. `
|
181
|
+
+ 'Please check your query parameters and output schema format.');
|
182
|
+
}
|
183
|
+
else if (statusCode === 500) {
|
184
|
+
logger.error(`❌ Server error: ${responseText}`);
|
185
|
+
throw new Error('Internal server error occurred during agent execution. '
|
186
|
+
+ 'Please try again later or contact support if the issue persists.');
|
187
|
+
}
|
188
|
+
else {
|
189
|
+
logger.error(`❌ Remote execution failed with status ${statusCode}: ${responseText}`);
|
190
|
+
throw new Error(`Remote agent execution failed: ${statusCode} - ${responseText}`);
|
191
|
+
}
|
192
|
+
}
|
193
|
+
const result = await response.json();
|
194
|
+
logger.info(`🔧 Response: ${JSON.stringify(result)}`);
|
195
|
+
logger.info('✅ Remote execution completed successfully');
|
196
|
+
// Check for error responses (even with 200 status)
|
197
|
+
if (typeof result === 'object' && result !== null) {
|
198
|
+
// Check for actual error conditions (not just presence of error field)
|
199
|
+
if (result.status === 'error' || result.error !== null) {
|
200
|
+
const errorMsg = result.error ?? String(result);
|
201
|
+
logger.error(`❌ Remote agent execution failed: ${errorMsg}`);
|
202
|
+
throw new Error(`Remote agent execution failed: ${errorMsg}`);
|
203
|
+
}
|
204
|
+
// Check if the response indicates agent initialization failure
|
205
|
+
if (String(result).includes('failed to initialize')) {
|
206
|
+
logger.error(`❌ Agent initialization failed: ${result}`);
|
207
|
+
throw new Error('Agent initialization failed on remote server. '
|
208
|
+
+ 'This usually indicates:\n'
|
209
|
+
+ '• Invalid agent configuration (LLM model, system prompt)\n'
|
210
|
+
+ '• Missing or invalid MCP server configurations\n'
|
211
|
+
+ '• Network connectivity issues with MCP servers\n'
|
212
|
+
+ '• Missing environment variables or credentials\n'
|
213
|
+
+ `Raw error: ${result}`);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
// Handle structured output
|
217
|
+
if (outputSchema) {
|
218
|
+
return this.parseStructuredResponse(result, outputSchema);
|
219
|
+
}
|
220
|
+
// Regular string output
|
221
|
+
if (typeof result === 'object' && result !== null && 'result' in result) {
|
222
|
+
return result.result;
|
223
|
+
}
|
224
|
+
else if (typeof result === 'string') {
|
225
|
+
return result;
|
226
|
+
}
|
227
|
+
else {
|
228
|
+
return String(result);
|
229
|
+
}
|
230
|
+
}
|
231
|
+
catch (e) {
|
232
|
+
if (e instanceof Error) {
|
233
|
+
// Check for specific error types
|
234
|
+
if (e.name === 'AbortError') {
|
235
|
+
logger.error(`❌ Remote execution timed out: ${e}`);
|
236
|
+
throw new Error('Remote agent execution timed out. The server may be overloaded or the query is taking too long to '
|
237
|
+
+ 'process. Try again or use a simpler query.');
|
238
|
+
}
|
239
|
+
logger.error(`❌ Remote execution error: ${e}`);
|
240
|
+
throw new Error(`Remote agent execution failed: ${e.message}`);
|
241
|
+
}
|
242
|
+
logger.error(`❌ Remote execution error: ${e}`);
|
243
|
+
throw new Error(`Remote agent execution failed: ${String(e)}`);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
async *stream(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
247
|
+
/**
|
248
|
+
* Stream implementation for remote agent - currently just wraps run.
|
249
|
+
* In the future, this could be enhanced to support actual streaming from the API.
|
250
|
+
*/
|
251
|
+
const result = await this.run(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
252
|
+
return result;
|
253
|
+
}
|
254
|
+
async close() {
|
255
|
+
/**
|
256
|
+
* Close the remote agent connection.
|
257
|
+
*/
|
258
|
+
logger.info('🔌 Remote agent client closed');
|
259
|
+
// In the future, we might want to delete the chat session here
|
260
|
+
// if (this.chatId) {
|
261
|
+
// await this.deleteChatSession(this.chatId)
|
262
|
+
// }
|
263
|
+
}
|
264
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/**
|
2
|
+
* Observability module for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides centralized observability management for LangChain agents,
|
5
|
+
* supporting multiple platforms like Langfuse and Laminar.
|
6
|
+
*/
|
7
|
+
import './langfuse.js';
|
8
|
+
export { langfuseClient, langfuseHandler, langfuseInitPromise, } from './langfuse.js';
|
9
|
+
export { createManager, getDefaultManager, type ObservabilityConfig, ObservabilityManager, } from './manager.js';
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,eAAe,CAAA;AAGtB,OAAO,EACL,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,oBAAoB,GACrB,MAAM,cAAc,CAAA"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* Observability module for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides centralized observability management for LangChain agents,
|
5
|
+
* supporting multiple platforms like Langfuse and Laminar.
|
6
|
+
*/
|
7
|
+
// Import observability providers - order matters for initialization
|
8
|
+
import './langfuse.js';
|
9
|
+
// Re-export individual handlers for direct usage if needed
|
10
|
+
export { langfuseClient, langfuseHandler, langfuseInitPromise, } from './langfuse.js';
|
11
|
+
// Export the manager and its utilities
|
12
|
+
export { createManager, getDefaultManager, ObservabilityManager, } from './manager.js';
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/**
|
2
|
+
* Langfuse observability integration for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides automatic instrumentation and callback handler
|
5
|
+
* for Langfuse observability platform.
|
6
|
+
*/
|
7
|
+
import type { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
8
|
+
export declare const langfuseHandler: () => BaseCallbackHandler | null;
|
9
|
+
export declare const langfuseClient: () => any;
|
10
|
+
export declare const langfuseInitPromise: () => Promise<void> | null;
|
11
|
+
//# sourceMappingURL=langfuse.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"langfuse.d.ts","sourceRoot":"","sources":["../../../src/observability/langfuse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAqIzE,eAAO,MAAM,eAAe,kCAA8B,CAAA;AAC1D,eAAO,MAAM,cAAc,WAA6B,CAAA;AACxD,eAAO,MAAM,mBAAmB,4BAAkC,CAAA"}
|
@@ -0,0 +1,123 @@
|
|
1
|
+
/**
|
2
|
+
* Langfuse observability integration for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides automatic instrumentation and callback handler
|
5
|
+
* for Langfuse observability platform.
|
6
|
+
*/
|
7
|
+
import { config } from 'dotenv';
|
8
|
+
import { logger } from '../logging.js';
|
9
|
+
config();
|
10
|
+
// Check if Langfuse is disabled via environment variable
|
11
|
+
const langfuseDisabled = process.env.MCP_USE_LANGFUSE?.toLowerCase() === 'false';
|
12
|
+
// Initialize variables - using const with object to avoid linter issues with mutable exports
|
13
|
+
const langfuseState = {
|
14
|
+
handler: null,
|
15
|
+
client: null,
|
16
|
+
initPromise: null,
|
17
|
+
};
|
18
|
+
async function initializeLangfuse() {
|
19
|
+
try {
|
20
|
+
// Dynamically import to avoid errors if package not installed
|
21
|
+
const langfuseModule = await import('langfuse-langchain').catch(() => null);
|
22
|
+
if (!langfuseModule) {
|
23
|
+
logger.debug('Langfuse package not installed - tracing disabled. Install with: npm install langfuse-langchain');
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
const { CallbackHandler } = langfuseModule;
|
27
|
+
// Create a custom CallbackHandler wrapper to add logging
|
28
|
+
class LoggingCallbackHandler extends CallbackHandler {
|
29
|
+
constructor(config) {
|
30
|
+
super(config);
|
31
|
+
}
|
32
|
+
async handleLLMStart(...args) {
|
33
|
+
logger.debug('Langfuse: LLM start intercepted');
|
34
|
+
if (this.verbose) {
|
35
|
+
logger.debug(`Langfuse: LLM start args: ${JSON.stringify(args)}`);
|
36
|
+
}
|
37
|
+
return super.handleLLMStart(...args);
|
38
|
+
}
|
39
|
+
async handleChainStart(...args) {
|
40
|
+
logger.debug('Langfuse: Chain start intercepted');
|
41
|
+
if (this.verbose) {
|
42
|
+
logger.debug(`Langfuse: Chain start args: ${JSON.stringify(args)}`);
|
43
|
+
}
|
44
|
+
return super.handleChainStart(...args);
|
45
|
+
}
|
46
|
+
async handleToolStart(...args) {
|
47
|
+
logger.debug('Langfuse: Tool start intercepted');
|
48
|
+
if (this.verbose) {
|
49
|
+
logger.debug(`Langfuse: Tool start args: ${JSON.stringify(args)}`);
|
50
|
+
}
|
51
|
+
return super.handleToolStart(...args);
|
52
|
+
}
|
53
|
+
async handleRetrieverStart(...args) {
|
54
|
+
logger.debug('Langfuse: Retriever start intercepted');
|
55
|
+
if (this.verbose) {
|
56
|
+
logger.debug(`Langfuse: Retriever start args: ${JSON.stringify(args)}`);
|
57
|
+
}
|
58
|
+
return super.handleRetrieverStart(...args);
|
59
|
+
}
|
60
|
+
async handleAgentAction(...args) {
|
61
|
+
logger.debug('Langfuse: Agent action intercepted');
|
62
|
+
if (this.verbose) {
|
63
|
+
logger.debug(`Langfuse: Agent action args: ${JSON.stringify(args)}`);
|
64
|
+
}
|
65
|
+
return super.handleAgentAction(...args);
|
66
|
+
}
|
67
|
+
async handleAgentEnd(...args) {
|
68
|
+
logger.debug('Langfuse: Agent end intercepted');
|
69
|
+
if (this.verbose) {
|
70
|
+
logger.debug(`Langfuse: Agent end args: ${JSON.stringify(args)}`);
|
71
|
+
}
|
72
|
+
return super.handleAgentEnd(...args);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
// Create the handler with configuration
|
76
|
+
const config = {
|
77
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
78
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
79
|
+
baseUrl: process.env.LANGFUSE_HOST || process.env.LANGFUSE_BASEURL || 'https://cloud.langfuse.com',
|
80
|
+
flushAt: Number.parseInt(process.env.LANGFUSE_FLUSH_AT || '15'),
|
81
|
+
flushInterval: Number.parseInt(process.env.LANGFUSE_FLUSH_INTERVAL || '10000'),
|
82
|
+
release: process.env.LANGFUSE_RELEASE,
|
83
|
+
requestTimeout: Number.parseInt(process.env.LANGFUSE_REQUEST_TIMEOUT || '10000'),
|
84
|
+
enabled: process.env.LANGFUSE_ENABLED !== 'false',
|
85
|
+
};
|
86
|
+
langfuseState.handler = new LoggingCallbackHandler(config);
|
87
|
+
logger.debug('Langfuse observability initialized successfully with logging enabled');
|
88
|
+
// Also initialize the client for direct usage if needed
|
89
|
+
try {
|
90
|
+
const langfuseCore = await import('langfuse').catch(() => null);
|
91
|
+
if (langfuseCore) {
|
92
|
+
const { Langfuse } = langfuseCore;
|
93
|
+
langfuseState.client = new Langfuse({
|
94
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
95
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
96
|
+
baseUrl: process.env.LANGFUSE_HOST || 'https://cloud.langfuse.com',
|
97
|
+
});
|
98
|
+
logger.debug('Langfuse client initialized');
|
99
|
+
}
|
100
|
+
}
|
101
|
+
catch (error) {
|
102
|
+
logger.debug(`Langfuse client initialization failed: ${error}`);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
catch (error) {
|
106
|
+
logger.debug(`Langfuse initialization error: ${error}`);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
// Only initialize if not disabled and required keys are present
|
110
|
+
if (langfuseDisabled) {
|
111
|
+
logger.debug('Langfuse tracing disabled via MCP_USE_LANGFUSE environment variable');
|
112
|
+
}
|
113
|
+
else if (!process.env.LANGFUSE_PUBLIC_KEY || !process.env.LANGFUSE_SECRET_KEY) {
|
114
|
+
logger.debug('Langfuse API keys not found - tracing disabled. Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY to enable');
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
// Create initialization promise to ensure handlers are ready when needed
|
118
|
+
langfuseState.initPromise = initializeLangfuse();
|
119
|
+
}
|
120
|
+
// Export getters to access the state
|
121
|
+
export const langfuseHandler = () => langfuseState.handler;
|
122
|
+
export const langfuseClient = () => langfuseState.client;
|
123
|
+
export const langfuseInitPromise = () => langfuseState.initPromise;
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/**
|
2
|
+
* Observability callbacks manager for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides a centralized manager for handling observability callbacks
|
5
|
+
* from various platforms (Langfuse, Laminar, etc.) in a clean and extensible way.
|
6
|
+
*/
|
7
|
+
import type { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
8
|
+
export interface ObservabilityConfig {
|
9
|
+
/** Custom callbacks to use instead of defaults */
|
10
|
+
customCallbacks?: BaseCallbackHandler[];
|
11
|
+
/** Whether to enable verbose logging */
|
12
|
+
verbose?: boolean;
|
13
|
+
}
|
14
|
+
export declare class ObservabilityManager {
|
15
|
+
private customCallbacks?;
|
16
|
+
private availableHandlers;
|
17
|
+
private handlerNames;
|
18
|
+
private initialized;
|
19
|
+
private verbose;
|
20
|
+
constructor(config?: ObservabilityConfig);
|
21
|
+
/**
|
22
|
+
* Collect all available observability handlers from configured platforms.
|
23
|
+
*/
|
24
|
+
private collectAvailableHandlers;
|
25
|
+
/**
|
26
|
+
* Get the list of callbacks to use.
|
27
|
+
* @returns List of callbacks - either custom callbacks if provided, or all available observability handlers.
|
28
|
+
*/
|
29
|
+
getCallbacks(): Promise<BaseCallbackHandler[]>;
|
30
|
+
/**
|
31
|
+
* Get the names of available handlers.
|
32
|
+
* @returns List of handler names (e.g., ["Langfuse", "Laminar"])
|
33
|
+
*/
|
34
|
+
getHandlerNames(): Promise<string[]>;
|
35
|
+
/**
|
36
|
+
* Check if any callbacks are available.
|
37
|
+
* @returns True if callbacks are available, False otherwise.
|
38
|
+
*/
|
39
|
+
hasCallbacks(): Promise<boolean>;
|
40
|
+
/**
|
41
|
+
* Add a callback to the custom callbacks list.
|
42
|
+
* @param callback The callback to add.
|
43
|
+
*/
|
44
|
+
addCallback(callback: BaseCallbackHandler): void;
|
45
|
+
/**
|
46
|
+
* Clear all custom callbacks.
|
47
|
+
*/
|
48
|
+
clearCallbacks(): void;
|
49
|
+
/**
|
50
|
+
* Flush all pending traces to observability platforms.
|
51
|
+
* Important for serverless environments and short-lived processes.
|
52
|
+
*/
|
53
|
+
flush(): Promise<void>;
|
54
|
+
/**
|
55
|
+
* Shutdown all handlers gracefully (for serverless environments).
|
56
|
+
*/
|
57
|
+
shutdown(): Promise<void>;
|
58
|
+
/**
|
59
|
+
* String representation of the ObservabilityManager.
|
60
|
+
*/
|
61
|
+
toString(): string;
|
62
|
+
}
|
63
|
+
/**
|
64
|
+
* Get the default ObservabilityManager instance.
|
65
|
+
* @returns The default ObservabilityManager instance (singleton).
|
66
|
+
*/
|
67
|
+
export declare function getDefaultManager(): ObservabilityManager;
|
68
|
+
/**
|
69
|
+
* Create a new ObservabilityManager instance.
|
70
|
+
* @param config Configuration options
|
71
|
+
* @returns A new ObservabilityManager instance.
|
72
|
+
*/
|
73
|
+
export declare function createManager(config?: ObservabilityConfig): ObservabilityManager;
|
74
|
+
//# sourceMappingURL=manager.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/observability/manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAGzE,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACvC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAuB;IAC/C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,GAAE,mBAAwB;IAK5C;;OAEG;YACW,wBAAwB;IA6BtC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAoBpD;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAU1C;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAKtC;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAQhD;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B;;OAEG;IACH,QAAQ,IAAI,MAAM;CAOnB;AAKD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAKxD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,mBAAwB,GAAG,oBAAoB,CAEpF"}
|
@@ -0,0 +1,167 @@
|
|
1
|
+
/**
|
2
|
+
* Observability callbacks manager for MCP-use.
|
3
|
+
*
|
4
|
+
* This module provides a centralized manager for handling observability callbacks
|
5
|
+
* from various platforms (Langfuse, Laminar, etc.) in a clean and extensible way.
|
6
|
+
*/
|
7
|
+
import { logger } from '../logging.js';
|
8
|
+
export class ObservabilityManager {
|
9
|
+
customCallbacks;
|
10
|
+
availableHandlers = [];
|
11
|
+
handlerNames = [];
|
12
|
+
initialized = false;
|
13
|
+
verbose;
|
14
|
+
constructor(config = {}) {
|
15
|
+
this.customCallbacks = config.customCallbacks;
|
16
|
+
this.verbose = config.verbose ?? false;
|
17
|
+
}
|
18
|
+
/**
|
19
|
+
* Collect all available observability handlers from configured platforms.
|
20
|
+
*/
|
21
|
+
async collectAvailableHandlers() {
|
22
|
+
if (this.initialized) {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
// Import handlers lazily to avoid circular imports
|
26
|
+
try {
|
27
|
+
const { langfuseHandler, langfuseInitPromise } = await import('./langfuse.js');
|
28
|
+
// Wait for initialization to complete
|
29
|
+
const initPromise = langfuseInitPromise();
|
30
|
+
if (initPromise) {
|
31
|
+
await initPromise;
|
32
|
+
}
|
33
|
+
const handler = langfuseHandler();
|
34
|
+
if (handler) {
|
35
|
+
this.availableHandlers.push(handler);
|
36
|
+
this.handlerNames.push('Langfuse');
|
37
|
+
logger.debug('ObservabilityManager: Langfuse handler available');
|
38
|
+
}
|
39
|
+
}
|
40
|
+
catch {
|
41
|
+
logger.debug('ObservabilityManager: Langfuse module not available');
|
42
|
+
}
|
43
|
+
// Future: Add more platforms here...
|
44
|
+
this.initialized = true;
|
45
|
+
}
|
46
|
+
/**
|
47
|
+
* Get the list of callbacks to use.
|
48
|
+
* @returns List of callbacks - either custom callbacks if provided, or all available observability handlers.
|
49
|
+
*/
|
50
|
+
async getCallbacks() {
|
51
|
+
// If custom callbacks were provided, use those
|
52
|
+
if (this.customCallbacks) {
|
53
|
+
logger.debug(`ObservabilityManager: Using ${this.customCallbacks.length} custom callbacks`);
|
54
|
+
return this.customCallbacks;
|
55
|
+
}
|
56
|
+
// Otherwise, collect and return all available handlers
|
57
|
+
await this.collectAvailableHandlers();
|
58
|
+
if (this.availableHandlers.length > 0) {
|
59
|
+
logger.debug(`ObservabilityManager: Using ${this.availableHandlers.length} handlers`);
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
logger.debug('ObservabilityManager: No callbacks configured');
|
63
|
+
}
|
64
|
+
return this.availableHandlers;
|
65
|
+
}
|
66
|
+
/**
|
67
|
+
* Get the names of available handlers.
|
68
|
+
* @returns List of handler names (e.g., ["Langfuse", "Laminar"])
|
69
|
+
*/
|
70
|
+
async getHandlerNames() {
|
71
|
+
if (this.customCallbacks) {
|
72
|
+
// For custom callbacks, try to get their class names
|
73
|
+
return this.customCallbacks.map(cb => cb.constructor.name);
|
74
|
+
}
|
75
|
+
await this.collectAvailableHandlers();
|
76
|
+
return this.handlerNames;
|
77
|
+
}
|
78
|
+
/**
|
79
|
+
* Check if any callbacks are available.
|
80
|
+
* @returns True if callbacks are available, False otherwise.
|
81
|
+
*/
|
82
|
+
async hasCallbacks() {
|
83
|
+
const callbacks = await this.getCallbacks();
|
84
|
+
return callbacks.length > 0;
|
85
|
+
}
|
86
|
+
/**
|
87
|
+
* Add a callback to the custom callbacks list.
|
88
|
+
* @param callback The callback to add.
|
89
|
+
*/
|
90
|
+
addCallback(callback) {
|
91
|
+
if (!this.customCallbacks) {
|
92
|
+
this.customCallbacks = [];
|
93
|
+
}
|
94
|
+
this.customCallbacks.push(callback);
|
95
|
+
logger.debug(`ObservabilityManager: Added custom callback: ${callback.constructor.name}`);
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* Clear all custom callbacks.
|
99
|
+
*/
|
100
|
+
clearCallbacks() {
|
101
|
+
this.customCallbacks = [];
|
102
|
+
logger.debug('ObservabilityManager: Cleared all custom callbacks');
|
103
|
+
}
|
104
|
+
/**
|
105
|
+
* Flush all pending traces to observability platforms.
|
106
|
+
* Important for serverless environments and short-lived processes.
|
107
|
+
*/
|
108
|
+
async flush() {
|
109
|
+
// Flush Langfuse traces
|
110
|
+
const callbacks = await this.getCallbacks();
|
111
|
+
for (const callback of callbacks) {
|
112
|
+
if ('flushAsync' in callback && typeof callback.flushAsync === 'function') {
|
113
|
+
await callback.flushAsync();
|
114
|
+
}
|
115
|
+
}
|
116
|
+
logger.debug('ObservabilityManager: All traces flushed');
|
117
|
+
}
|
118
|
+
/**
|
119
|
+
* Shutdown all handlers gracefully (for serverless environments).
|
120
|
+
*/
|
121
|
+
async shutdown() {
|
122
|
+
// Flush before shutdown
|
123
|
+
await this.flush();
|
124
|
+
// Shutdown other callbacks
|
125
|
+
const callbacks = await this.getCallbacks();
|
126
|
+
for (const callback of callbacks) {
|
127
|
+
// Check if the callback has a shutdown method (like Langfuse)
|
128
|
+
if ('shutdownAsync' in callback && typeof callback.shutdownAsync === 'function') {
|
129
|
+
await callback.shutdownAsync();
|
130
|
+
}
|
131
|
+
else if ('shutdown' in callback && typeof callback.shutdown === 'function') {
|
132
|
+
await callback.shutdown();
|
133
|
+
}
|
134
|
+
}
|
135
|
+
logger.debug('ObservabilityManager: All handlers shutdown');
|
136
|
+
}
|
137
|
+
/**
|
138
|
+
* String representation of the ObservabilityManager.
|
139
|
+
*/
|
140
|
+
toString() {
|
141
|
+
const names = this.handlerNames;
|
142
|
+
if (names.length > 0) {
|
143
|
+
return `ObservabilityManager(handlers=${names.join(', ')})`;
|
144
|
+
}
|
145
|
+
return 'ObservabilityManager(no handlers)';
|
146
|
+
}
|
147
|
+
}
|
148
|
+
// Singleton instance for easy access
|
149
|
+
let defaultManager = null;
|
150
|
+
/**
|
151
|
+
* Get the default ObservabilityManager instance.
|
152
|
+
* @returns The default ObservabilityManager instance (singleton).
|
153
|
+
*/
|
154
|
+
export function getDefaultManager() {
|
155
|
+
if (!defaultManager) {
|
156
|
+
defaultManager = new ObservabilityManager();
|
157
|
+
}
|
158
|
+
return defaultManager;
|
159
|
+
}
|
160
|
+
/**
|
161
|
+
* Create a new ObservabilityManager instance.
|
162
|
+
* @param config Configuration options
|
163
|
+
* @returns A new ObservabilityManager instance.
|
164
|
+
*/
|
165
|
+
export function createManager(config = {}) {
|
166
|
+
return new ObservabilityManager(config);
|
167
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/**
|
2
|
+
* Type definitions for observability module
|
3
|
+
*/
|
4
|
+
import type { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
5
|
+
/**
|
6
|
+
* Configuration for Langfuse integration
|
7
|
+
*/
|
8
|
+
export interface LangfuseConfig {
|
9
|
+
publicKey?: string;
|
10
|
+
secretKey?: string;
|
11
|
+
baseUrl?: string;
|
12
|
+
flushAt?: number;
|
13
|
+
flushInterval?: number;
|
14
|
+
release?: string;
|
15
|
+
requestTimeout?: number;
|
16
|
+
enabled?: boolean;
|
17
|
+
}
|
18
|
+
/**
|
19
|
+
* Configuration for Laminar integration
|
20
|
+
*/
|
21
|
+
export interface LaminarConfig {
|
22
|
+
projectApiKey?: string;
|
23
|
+
baseUrl?: string;
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* Extended callback handler with shutdown support
|
27
|
+
*/
|
28
|
+
export interface ObservabilityCallbackHandler extends BaseCallbackHandler {
|
29
|
+
/** Optional shutdown method for cleanup */
|
30
|
+
shutdownAsync?: () => Promise<void>;
|
31
|
+
shutdown?: () => void | Promise<void>;
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Observability platform information
|
35
|
+
*/
|
36
|
+
export interface ObservabilityPlatform {
|
37
|
+
name: string;
|
38
|
+
handler?: ObservabilityCallbackHandler;
|
39
|
+
initialized: boolean;
|
40
|
+
autoInstrumentation?: boolean;
|
41
|
+
}
|
42
|
+
//# sourceMappingURL=types.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/observability/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAEzE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,4BAA4B,CAAA;IACtC,WAAW,EAAE,OAAO,CAAA;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B"}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "mcp-use",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.1.
|
4
|
+
"version": "0.1.16",
|
5
5
|
"packageManager": "pnpm@10.6.1",
|
6
6
|
"description": "A utility library for integrating Model Context Protocol (MCP) with LangChain, Zod, and related tools. Provides helpers for schema conversion, event streaming, and SDK usage.",
|
7
7
|
"author": "Zane",
|
@@ -76,6 +76,18 @@
|
|
76
76
|
"example:add_server": "npm run build && node dist/examples/add_server_tool.js",
|
77
77
|
"example:structured": "npm run build && node dist/examples/structured_output.js"
|
78
78
|
},
|
79
|
+
"peerDependencies": {
|
80
|
+
"langfuse": "^3.32.0",
|
81
|
+
"langfuse-langchain": "^3.38.4"
|
82
|
+
},
|
83
|
+
"peerDependenciesMeta": {
|
84
|
+
"langfuse": {
|
85
|
+
"optional": true
|
86
|
+
},
|
87
|
+
"langfuse-langchain": {
|
88
|
+
"optional": true
|
89
|
+
}
|
90
|
+
},
|
79
91
|
"dependencies": {
|
80
92
|
"@dmitryrechkin/json-schema-to-zod": "^1.0.1",
|
81
93
|
"@langchain/anthropic": "^0.3.14",
|
@@ -111,10 +123,8 @@
|
|
111
123
|
},
|
112
124
|
"lint-staged": {
|
113
125
|
"*.{js,ts}": [
|
114
|
-
"
|
115
|
-
|
116
|
-
"**/*.ts": [
|
117
|
-
"npm run build"
|
126
|
+
"eslint --fix",
|
127
|
+
"eslint"
|
118
128
|
]
|
119
129
|
}
|
120
130
|
}
|