langflow-mcp-server 2.0.0 → 3.0.0

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.
Files changed (40) hide show
  1. package/.env.example +5 -0
  2. package/LICENSE +1 -1
  3. package/README.md +91 -8
  4. package/dist/__tests__/fixtures/advanced-execution.d.ts +5 -1
  5. package/dist/__tests__/fixtures/advanced-execution.d.ts.map +1 -1
  6. package/dist/__tests__/fixtures/advanced-execution.js +43 -1
  7. package/dist/__tests__/fixtures/advanced-execution.js.map +1 -1
  8. package/dist/mcp/index.js +8 -1
  9. package/dist/mcp/index.js.map +1 -1
  10. package/dist/mcp/server-consolidated.d.ts +28 -0
  11. package/dist/mcp/server-consolidated.d.ts.map +1 -0
  12. package/dist/mcp/server-consolidated.js +740 -0
  13. package/dist/mcp/server-consolidated.js.map +1 -0
  14. package/dist/mcp/server.d.ts +1 -1
  15. package/dist/mcp/server.d.ts.map +1 -1
  16. package/dist/mcp/server.js +105 -21
  17. package/dist/mcp/server.js.map +1 -1
  18. package/dist/mcp/tools-consolidated.d.ts +3 -0
  19. package/dist/mcp/tools-consolidated.d.ts.map +1 -0
  20. package/dist/mcp/tools-consolidated.js +600 -0
  21. package/dist/mcp/tools-consolidated.js.map +1 -0
  22. package/dist/mcp/tools.d.ts.map +1 -1
  23. package/dist/mcp/tools.js +95 -8
  24. package/dist/mcp/tools.js.map +1 -1
  25. package/dist/mcp/validation-consolidated.d.ts +404 -0
  26. package/dist/mcp/validation-consolidated.d.ts.map +1 -0
  27. package/dist/mcp/validation-consolidated.js +374 -0
  28. package/dist/mcp/validation-consolidated.js.map +1 -0
  29. package/dist/mcp/validation.d.ts +20 -1
  30. package/dist/mcp/validation.d.ts.map +1 -1
  31. package/dist/mcp/validation.js +21 -5
  32. package/dist/mcp/validation.js.map +1 -1
  33. package/dist/services/langflow-client.d.ts +5 -2
  34. package/dist/services/langflow-client.d.ts.map +1 -1
  35. package/dist/services/langflow-client.js +93 -62
  36. package/dist/services/langflow-client.js.map +1 -1
  37. package/dist/types/index.d.ts +14 -0
  38. package/dist/types/index.d.ts.map +1 -1
  39. package/healthcheck.js +41 -0
  40. package/package.json +7 -6
@@ -0,0 +1,740 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LangflowMCPServerConsolidated = void 0;
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const zod_1 = require("zod");
8
+ const tools_consolidated_1 = require("./tools-consolidated");
9
+ const logger_1 = require("../utils/logger");
10
+ const langflow_client_1 = require("../services/langflow-client");
11
+ const validation_consolidated_1 = require("./validation-consolidated");
12
+ class LangflowMCPServerConsolidated {
13
+ constructor() {
14
+ this.client = null;
15
+ const baseUrl = process.env.LANGFLOW_BASE_URL;
16
+ const apiKey = process.env.LANGFLOW_API_KEY;
17
+ if (!baseUrl || !apiKey) {
18
+ throw new Error('LANGFLOW_BASE_URL and LANGFLOW_API_KEY must be set in environment');
19
+ }
20
+ try {
21
+ const url = new URL(baseUrl);
22
+ if (!['http:', 'https:'].includes(url.protocol)) {
23
+ throw new Error(`Invalid protocol: ${url.protocol}. Only http: and https: are allowed.`);
24
+ }
25
+ }
26
+ catch (error) {
27
+ if (error instanceof TypeError) {
28
+ throw new Error(`Invalid LANGFLOW_BASE_URL format: ${baseUrl}`);
29
+ }
30
+ throw error;
31
+ }
32
+ if (apiKey.length < 10) {
33
+ throw new Error('LANGFLOW_API_KEY appears to be invalid (too short)');
34
+ }
35
+ const DEFAULT_TIMEOUT = 30000;
36
+ const MIN_TIMEOUT = 1000;
37
+ const MAX_TIMEOUT = 300000;
38
+ const timeoutStr = process.env.LANGFLOW_TIMEOUT || String(DEFAULT_TIMEOUT);
39
+ let timeout = parseInt(timeoutStr, 10);
40
+ if (isNaN(timeout) || timeout < MIN_TIMEOUT || timeout > MAX_TIMEOUT) {
41
+ logger_1.logger.warn(`Invalid LANGFLOW_TIMEOUT: ${timeoutStr}, using default: ${DEFAULT_TIMEOUT}`);
42
+ timeout = DEFAULT_TIMEOUT;
43
+ }
44
+ const config = { baseUrl, apiKey, timeout };
45
+ this.client = new langflow_client_1.LangflowClient(config);
46
+ logger_1.logger.info('Initializing Langflow MCP server (consolidated tools)');
47
+ let serverVersion = 'dev';
48
+ try {
49
+ const pkg = require('../../package.json');
50
+ serverVersion = pkg.version ?? serverVersion;
51
+ }
52
+ catch (e) {
53
+ logger_1.logger.warn('package.json not readable; using fallback version "dev"', e);
54
+ }
55
+ this.server = new index_js_1.Server({ name: 'langflow-mcp', version: serverVersion }, { capabilities: { tools: {} } });
56
+ this.setupHandlers();
57
+ }
58
+ formatSuccessResponse(data) {
59
+ return {
60
+ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }]
61
+ };
62
+ }
63
+ sanitizeSensitiveData(args, depth = 0, seen = new WeakSet()) {
64
+ const MAX_DEPTH = 10;
65
+ const MAX_STRING_LENGTH = 200;
66
+ const SENSITIVE_KEYS = new Set([
67
+ 'password', 'new_password', 'api_key', 'token',
68
+ 'access_token', 'refresh_token', 'authorization',
69
+ 'x-api-key', 'x-store-api-key', 'set-cookie',
70
+ 'bearer', 'session', 'session_id', 'cookie',
71
+ 'private_key', 'secret', 'credentials', 'api-key',
72
+ 'file_content', 'file', 'content', 'payload', 'data'
73
+ ]);
74
+ if (depth > MAX_DEPTH)
75
+ return { __error: 'max depth exceeded' };
76
+ if (!args || typeof args !== 'object')
77
+ return args;
78
+ if (seen.has(args))
79
+ return { __error: 'circular reference' };
80
+ seen.add(args);
81
+ const sanitized = {};
82
+ for (const [key, value] of Object.entries(args)) {
83
+ const keyLower = key.toLowerCase();
84
+ if (SENSITIVE_KEYS.has(keyLower)) {
85
+ sanitized[key] = '***REDACTED***';
86
+ }
87
+ else if (typeof value === 'string' && value.length > MAX_STRING_LENGTH) {
88
+ sanitized[key] = `${value.slice(0, MAX_STRING_LENGTH)}...[truncated ${value.length} chars]`;
89
+ }
90
+ else if (Array.isArray(value)) {
91
+ sanitized[key] = value.map(item => typeof item === 'object' && item !== null
92
+ ? this.sanitizeSensitiveData(item, depth + 1, seen)
93
+ : typeof item === 'string' && item.length > MAX_STRING_LENGTH
94
+ ? `${item.slice(0, MAX_STRING_LENGTH)}...[truncated]`
95
+ : item);
96
+ }
97
+ else if (typeof value === 'object' && value !== null) {
98
+ sanitized[key] = this.sanitizeSensitiveData(value, depth + 1, seen);
99
+ }
100
+ else {
101
+ sanitized[key] = value;
102
+ }
103
+ }
104
+ return sanitized;
105
+ }
106
+ formatErrorResponse(error, toolName, args) {
107
+ const sanitized = args ? this.sanitizeSensitiveData(args) : undefined;
108
+ const safeError = error instanceof Error
109
+ ? { name: error.name, message: error.message }
110
+ : { message: String(error) };
111
+ logger_1.logger.error(`Error executing tool ${toolName}:`, { args: sanitized, error: safeError });
112
+ let errorMessage;
113
+ let errorDetails = {};
114
+ if (error instanceof zod_1.ZodError) {
115
+ errorMessage = 'Validation error';
116
+ errorDetails = {
117
+ issues: error.issues.map(issue => ({
118
+ path: Array.isArray(issue.path) ? issue.path.join('.') : '',
119
+ message: issue.message
120
+ }))
121
+ };
122
+ }
123
+ else if (error instanceof Error) {
124
+ errorMessage = error.message;
125
+ if (error.stack && process.env.NODE_ENV !== 'production') {
126
+ errorDetails.stack = error.stack.split('\n').slice(0, 5);
127
+ }
128
+ }
129
+ else {
130
+ errorMessage = 'Unknown error';
131
+ }
132
+ return {
133
+ content: [{
134
+ type: 'text',
135
+ text: JSON.stringify({
136
+ error: true,
137
+ message: errorMessage,
138
+ tool: toolName,
139
+ timestamp: new Date().toISOString(),
140
+ ...errorDetails
141
+ }, null, 2)
142
+ }],
143
+ isError: true
144
+ };
145
+ }
146
+ validateFileSize(fileContent, maxSizeBytes = 10 * 1024 * 1024) {
147
+ const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
148
+ if (!base64Regex.test(fileContent)) {
149
+ throw new Error('Invalid base64 format');
150
+ }
151
+ const estimatedSize = (fileContent.length * 3) / 4;
152
+ if (estimatedSize > maxSizeBytes) {
153
+ throw new Error(`File size exceeds maximum allowed size of ${maxSizeBytes} bytes (10MB)`);
154
+ }
155
+ const fileBuffer = Buffer.from(fileContent, 'base64');
156
+ if (fileBuffer.length > maxSizeBytes) {
157
+ throw new Error(`File size ${fileBuffer.length} bytes exceeds maximum allowed size`);
158
+ }
159
+ return fileBuffer;
160
+ }
161
+ setupHandlers() {
162
+ this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
163
+ tools: tools_consolidated_1.consolidatedTools.map(tool => ({
164
+ name: tool.name,
165
+ description: tool.description,
166
+ inputSchema: tool.inputSchema,
167
+ })),
168
+ }));
169
+ this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
170
+ if (!this.client) {
171
+ throw new Error('Langflow client not initialized');
172
+ }
173
+ const { name, arguments: rawArgs } = request.params;
174
+ if (rawArgs !== undefined && rawArgs !== null) {
175
+ if (typeof rawArgs !== 'object' || Array.isArray(rawArgs)) {
176
+ throw new Error('Arguments must be an object');
177
+ }
178
+ }
179
+ const args = (rawArgs ?? {});
180
+ try {
181
+ switch (name) {
182
+ case 'flow':
183
+ return await this.handleFlowTool(args);
184
+ case 'flow_execution':
185
+ return await this.handleFlowExecutionTool(args);
186
+ case 'build':
187
+ return await this.handleBuildTool(args);
188
+ case 'folder':
189
+ return await this.handleFolderTool(args);
190
+ case 'project':
191
+ return await this.handleProjectTool(args);
192
+ case 'variable':
193
+ return await this.handleVariableTool(args);
194
+ case 'knowledge_base':
195
+ return await this.handleKnowledgeBaseTool(args);
196
+ case 'file':
197
+ return await this.handleFileTool(args);
198
+ case 'monitor':
199
+ return await this.handleMonitorTool(args);
200
+ case 'user':
201
+ return await this.handleUserTool(args);
202
+ case 'auth':
203
+ return await this.handleAuthTool(args);
204
+ case 'store':
205
+ return await this.handleStoreTool(args);
206
+ case 'registration':
207
+ return await this.handleRegistrationTool(args);
208
+ case 'validation':
209
+ return await this.handleValidationTool(args);
210
+ case 'system':
211
+ return await this.handleSystemTool(args);
212
+ default:
213
+ throw new Error(`Unknown tool: ${name}`);
214
+ }
215
+ }
216
+ catch (error) {
217
+ return this.formatErrorResponse(error, name, args);
218
+ }
219
+ });
220
+ }
221
+ async handleFlowTool(args) {
222
+ const validated = validation_consolidated_1.FlowToolSchema.parse(args);
223
+ switch (validated.action) {
224
+ case 'list': {
225
+ const { action: _, ...params } = validated;
226
+ const flows = await this.client.listFlows(params);
227
+ return this.formatSuccessResponse(flows);
228
+ }
229
+ case 'get': {
230
+ const flow = await this.client.getFlow(validated.flow_id);
231
+ return this.formatSuccessResponse(flow);
232
+ }
233
+ case 'create': {
234
+ const { action: _, ...data } = validated;
235
+ const created = await this.client.createFlow(data);
236
+ return this.formatSuccessResponse(created);
237
+ }
238
+ case 'update': {
239
+ const { action: _, flow_id, ...updates } = validated;
240
+ const updated = await this.client.updateFlow(flow_id, updates);
241
+ return this.formatSuccessResponse(updated);
242
+ }
243
+ case 'delete': {
244
+ await this.client.deleteFlow(validated.flow_id);
245
+ return this.formatSuccessResponse({ success: true, message: 'Flow deleted successfully' });
246
+ }
247
+ case 'delete_many': {
248
+ const result = await this.client.deleteFlows(validated.flow_ids);
249
+ return this.formatSuccessResponse(result);
250
+ }
251
+ case 'batch_create': {
252
+ const result = await this.client.batchCreateFlows(validated.flows);
253
+ return this.formatSuccessResponse(result);
254
+ }
255
+ case 'download': {
256
+ const result = await this.client.downloadFlows(validated.flow_ids);
257
+ return this.formatSuccessResponse(result);
258
+ }
259
+ case 'upload': {
260
+ const flow = await this.client.uploadFlow(validated.file);
261
+ return this.formatSuccessResponse(flow);
262
+ }
263
+ case 'get_public': {
264
+ const result = await this.client.getPublicFlow(validated.flow_id);
265
+ return this.formatSuccessResponse(result);
266
+ }
267
+ case 'get_examples': {
268
+ const examples = await this.client.getBasicExamples();
269
+ return this.formatSuccessResponse(examples);
270
+ }
271
+ case 'get_starters': {
272
+ const starters = await this.client.listStarterProjects();
273
+ return this.formatSuccessResponse(starters);
274
+ }
275
+ }
276
+ }
277
+ async handleFlowExecutionTool(args) {
278
+ const validated = validation_consolidated_1.FlowExecutionToolSchema.parse(args);
279
+ switch (validated.action) {
280
+ case 'run': {
281
+ const { action: _, flow_id_or_name, stream, ...inputRequest } = validated;
282
+ const result = await this.client.runFlow(flow_id_or_name, inputRequest, stream);
283
+ return this.formatSuccessResponse(result);
284
+ }
285
+ case 'run_advanced': {
286
+ const { action: _, flow_id_or_name, stream, user_id, ...request } = validated;
287
+ const result = await this.client.runFlowAdvanced(flow_id_or_name, request, stream, user_id);
288
+ return this.formatSuccessResponse(result);
289
+ }
290
+ case 'run_session': {
291
+ const { action: _, flow_id_or_name, stream, ...request } = validated;
292
+ const result = await this.client.runFlowSession(flow_id_or_name, request, stream);
293
+ return this.formatSuccessResponse(result);
294
+ }
295
+ case 'webhook': {
296
+ const { action: _, flow_id_or_name, ...inputRequest } = validated;
297
+ const result = await this.client.triggerWebhook(flow_id_or_name, inputRequest);
298
+ return this.formatSuccessResponse(result);
299
+ }
300
+ case 'process': {
301
+ const { action: _, flow_id, ...request } = validated;
302
+ const result = await this.client.processFlow(flow_id, request);
303
+ return this.formatSuccessResponse(result);
304
+ }
305
+ case 'predict': {
306
+ const { action: _, flow_id, ...request } = validated;
307
+ const result = await this.client.predictFlow(flow_id, request);
308
+ return this.formatSuccessResponse(result);
309
+ }
310
+ }
311
+ }
312
+ async handleBuildTool(args) {
313
+ const validated = validation_consolidated_1.BuildToolSchema.parse(args);
314
+ switch (validated.action) {
315
+ case 'start': {
316
+ const { action: _, flow_id, inputs, data, files, ...params } = validated;
317
+ const result = await this.client.buildFlow(flow_id, { inputs, data, files }, params);
318
+ return this.formatSuccessResponse(result);
319
+ }
320
+ case 'status': {
321
+ const result = await this.client.getBuildStatus(validated.job_id, validated.event_delivery);
322
+ return this.formatSuccessResponse(result);
323
+ }
324
+ case 'cancel': {
325
+ const result = await this.client.cancelBuild(validated.job_id);
326
+ return this.formatSuccessResponse(result);
327
+ }
328
+ case 'vertices': {
329
+ const { action: _, flow_id, ...request } = validated;
330
+ const result = await this.client.buildVertices(flow_id, request);
331
+ return this.formatSuccessResponse(result);
332
+ }
333
+ case 'get_vertex': {
334
+ const result = await this.client.getVertex({ flow_id: validated.flow_id, vertex_id: validated.vertex_id });
335
+ return this.formatSuccessResponse(result);
336
+ }
337
+ case 'stream_vertex': {
338
+ const result = await this.client.streamVertexBuild({ flow_id: validated.flow_id, vertex_id: validated.vertex_id });
339
+ return this.formatSuccessResponse(result);
340
+ }
341
+ case 'task_status': {
342
+ const result = await this.client.getTaskStatus(validated.task_id);
343
+ return this.formatSuccessResponse(result);
344
+ }
345
+ }
346
+ }
347
+ async handleFolderTool(args) {
348
+ const validated = validation_consolidated_1.FolderToolSchema.parse(args);
349
+ switch (validated.action) {
350
+ case 'list': {
351
+ const { action: _, ...params } = validated;
352
+ const folders = await this.client.listFolders(params);
353
+ return this.formatSuccessResponse(folders);
354
+ }
355
+ case 'get': {
356
+ const folder = await this.client.getFolder(validated.folder_id);
357
+ return this.formatSuccessResponse(folder);
358
+ }
359
+ case 'create': {
360
+ const { action: _, ...data } = validated;
361
+ const created = await this.client.createFolder(data);
362
+ return this.formatSuccessResponse(created);
363
+ }
364
+ case 'update': {
365
+ const { action: _, folder_id, ...updates } = validated;
366
+ const updated = await this.client.updateFolder(folder_id, updates);
367
+ return this.formatSuccessResponse(updated);
368
+ }
369
+ case 'delete': {
370
+ await this.client.deleteFolder(validated.folder_id);
371
+ return this.formatSuccessResponse({ success: true, message: 'Folder deleted successfully' });
372
+ }
373
+ case 'download': {
374
+ const result = await this.client.downloadFolder(validated.folder_id);
375
+ if (!result)
376
+ throw new Error('No folder data received from server');
377
+ const base64Data = Buffer.from(result).toString('base64');
378
+ return this.formatSuccessResponse({ data: base64Data, encoding: 'base64' });
379
+ }
380
+ case 'upload': {
381
+ const fileBuffer = this.validateFileSize(validated.file_content);
382
+ const result = await this.client.uploadFolder(fileBuffer, validated.file_name);
383
+ return this.formatSuccessResponse(result);
384
+ }
385
+ }
386
+ }
387
+ async handleProjectTool(args) {
388
+ const validated = validation_consolidated_1.ProjectToolSchema.parse(args);
389
+ switch (validated.action) {
390
+ case 'list': {
391
+ const { action: _, ...params } = validated;
392
+ const projects = await this.client.listProjects(params);
393
+ return this.formatSuccessResponse(projects);
394
+ }
395
+ case 'get': {
396
+ const project = await this.client.getProject(validated.project_id);
397
+ return this.formatSuccessResponse(project);
398
+ }
399
+ case 'create': {
400
+ const { action: _, ...data } = validated;
401
+ const created = await this.client.createProject(data);
402
+ return this.formatSuccessResponse(created);
403
+ }
404
+ case 'update': {
405
+ const { action: _, project_id, ...updates } = validated;
406
+ const updated = await this.client.updateProject(project_id, updates);
407
+ return this.formatSuccessResponse(updated);
408
+ }
409
+ case 'delete': {
410
+ await this.client.deleteProject(validated.project_id);
411
+ return this.formatSuccessResponse({ success: true, message: 'Project deleted successfully' });
412
+ }
413
+ case 'download': {
414
+ const result = await this.client.downloadProject(validated.project_id);
415
+ return this.formatSuccessResponse(result);
416
+ }
417
+ case 'upload': {
418
+ const project = await this.client.uploadProject(validated.file);
419
+ return this.formatSuccessResponse(project);
420
+ }
421
+ }
422
+ }
423
+ async handleVariableTool(args) {
424
+ const validated = validation_consolidated_1.VariableToolSchema.parse(args);
425
+ switch (validated.action) {
426
+ case 'list': {
427
+ const variables = await this.client.listVariables();
428
+ return this.formatSuccessResponse(variables);
429
+ }
430
+ case 'create': {
431
+ const { action: _, ...data } = validated;
432
+ const created = await this.client.createVariable(data);
433
+ return this.formatSuccessResponse(created);
434
+ }
435
+ case 'update': {
436
+ const { action: _, variable_id, ...updates } = validated;
437
+ const updated = await this.client.updateVariable(variable_id, updates);
438
+ return this.formatSuccessResponse(updated);
439
+ }
440
+ case 'delete': {
441
+ await this.client.deleteVariable(validated.variable_id);
442
+ return this.formatSuccessResponse({ success: true, message: 'Variable deleted successfully' });
443
+ }
444
+ }
445
+ }
446
+ async handleKnowledgeBaseTool(args) {
447
+ const validated = validation_consolidated_1.KnowledgeBaseToolSchema.parse(args);
448
+ switch (validated.action) {
449
+ case 'list': {
450
+ const knowledgeBases = await this.client.listKnowledgeBases();
451
+ return this.formatSuccessResponse(knowledgeBases);
452
+ }
453
+ case 'get': {
454
+ const kb = await this.client.getKnowledgeBase(validated.kb_name);
455
+ return this.formatSuccessResponse(kb);
456
+ }
457
+ case 'delete': {
458
+ await this.client.deleteKnowledgeBase(validated.kb_name);
459
+ return this.formatSuccessResponse({ success: true, message: 'Knowledge base deleted successfully' });
460
+ }
461
+ case 'bulk_delete': {
462
+ const result = await this.client.bulkDeleteKnowledgeBases(validated.kb_names);
463
+ return this.formatSuccessResponse(result);
464
+ }
465
+ case 'upload': {
466
+ const fileBuffer = this.validateFileSize(validated.file_content);
467
+ const result = await this.client.uploadKnowledgeBase(validated.kb_name, fileBuffer, validated.file_name);
468
+ return this.formatSuccessResponse(result);
469
+ }
470
+ }
471
+ }
472
+ async handleFileTool(args) {
473
+ const validated = validation_consolidated_1.FileToolSchema.parse(args);
474
+ switch (validated.action) {
475
+ case 'list': {
476
+ const files = await this.client.listFiles({ flow_id: validated.flow_id });
477
+ return this.formatSuccessResponse(files);
478
+ }
479
+ case 'upload': {
480
+ const fileBuffer = this.validateFileSize(validated.file_content);
481
+ const result = await this.client.uploadFile({
482
+ flow_id: validated.flow_id,
483
+ file: fileBuffer,
484
+ file_name: validated.file_name
485
+ });
486
+ return this.formatSuccessResponse(result);
487
+ }
488
+ case 'download': {
489
+ const fileData = await this.client.downloadFile({
490
+ flow_id: validated.flow_id,
491
+ file_name: validated.file_name
492
+ });
493
+ if (!fileData)
494
+ throw new Error('No file data received from server');
495
+ const base64Data = Buffer.from(fileData).toString('base64');
496
+ return this.formatSuccessResponse({ file_name: validated.file_name, content: base64Data });
497
+ }
498
+ case 'delete': {
499
+ const result = await this.client.deleteFile({
500
+ flow_id: validated.flow_id,
501
+ file_name: validated.file_name
502
+ });
503
+ return this.formatSuccessResponse(result);
504
+ }
505
+ case 'get_image': {
506
+ const imageData = await this.client.getFileImage({
507
+ flow_id: validated.flow_id,
508
+ file_name: validated.file_name
509
+ });
510
+ if (!imageData)
511
+ throw new Error('No image data received from server');
512
+ const base64Data = Buffer.from(imageData).toString('base64');
513
+ return this.formatSuccessResponse({ file_name: validated.file_name, content: base64Data });
514
+ }
515
+ }
516
+ }
517
+ async handleMonitorTool(args) {
518
+ const validated = validation_consolidated_1.MonitorToolSchema.parse(args);
519
+ switch (validated.action) {
520
+ case 'get_builds': {
521
+ const result = await this.client.getMonitorBuilds({ flow_id: validated.flow_id });
522
+ return this.formatSuccessResponse(result);
523
+ }
524
+ case 'delete_builds': {
525
+ await this.client.deleteMonitorBuilds(validated.flow_id);
526
+ return this.formatSuccessResponse({ success: true, message: 'Monitor builds deleted successfully' });
527
+ }
528
+ case 'get_messages': {
529
+ const { action: _, ...params } = validated;
530
+ const result = await this.client.getMonitorMessages(params);
531
+ return this.formatSuccessResponse(result);
532
+ }
533
+ case 'get_message': {
534
+ const result = await this.client.getMonitorMessage(validated.message_id);
535
+ return this.formatSuccessResponse(result);
536
+ }
537
+ case 'delete_messages': {
538
+ await this.client.deleteMonitorMessages(validated.message_ids);
539
+ return this.formatSuccessResponse({ success: true, message: 'Monitor messages deleted successfully' });
540
+ }
541
+ case 'get_sessions': {
542
+ const { action: _, ...params } = validated;
543
+ const result = await this.client.getMonitorSessions(params);
544
+ return this.formatSuccessResponse(result);
545
+ }
546
+ case 'get_session_messages': {
547
+ const result = await this.client.getMonitorSessionMessages(validated.session_id);
548
+ return this.formatSuccessResponse(result);
549
+ }
550
+ case 'migrate_session': {
551
+ const result = await this.client.migrateMonitorSession({
552
+ old_session_id: validated.session_id,
553
+ new_session_id: validated.new_session_id
554
+ });
555
+ return this.formatSuccessResponse(result);
556
+ }
557
+ case 'get_transactions': {
558
+ const { action: _, flow_id, ...params } = validated;
559
+ const result = await this.client.getMonitorTransactions({ flow_id: flow_id, ...params });
560
+ return this.formatSuccessResponse(result);
561
+ }
562
+ }
563
+ }
564
+ async handleUserTool(args) {
565
+ const validated = validation_consolidated_1.UserToolSchema.parse(args);
566
+ switch (validated.action) {
567
+ case 'list': {
568
+ const { action: _, page, size, ...rest } = validated;
569
+ const skip = page && size ? (page - 1) * size : page ? page - 1 : undefined;
570
+ const params = { skip, limit: size, ...rest };
571
+ const result = await this.client.listUsers(params);
572
+ return this.formatSuccessResponse(result);
573
+ }
574
+ case 'get': {
575
+ const result = await this.client.getUser(validated.user_id);
576
+ return this.formatSuccessResponse(result);
577
+ }
578
+ case 'get_current': {
579
+ const result = await this.client.getCurrentUser();
580
+ return this.formatSuccessResponse(result);
581
+ }
582
+ case 'update': {
583
+ const { action: _, user_id, ...updates } = validated;
584
+ const result = await this.client.updateUser(user_id, updates);
585
+ return this.formatSuccessResponse(result);
586
+ }
587
+ case 'reset_password': {
588
+ const result = await this.client.resetUserPassword(validated.user_id, validated.new_password);
589
+ return this.formatSuccessResponse(result);
590
+ }
591
+ }
592
+ }
593
+ async handleAuthTool(args) {
594
+ const validated = validation_consolidated_1.AuthToolSchema.parse(args);
595
+ switch (validated.action) {
596
+ case 'login': {
597
+ const result = await this.client.login(validated.username, validated.password);
598
+ return this.formatSuccessResponse(result);
599
+ }
600
+ case 'auto_login': {
601
+ const result = await this.client.autoLogin();
602
+ return this.formatSuccessResponse(result);
603
+ }
604
+ case 'logout': {
605
+ const result = await this.client.logout();
606
+ return this.formatSuccessResponse(result);
607
+ }
608
+ case 'refresh': {
609
+ const result = await this.client.refreshToken();
610
+ return this.formatSuccessResponse(result);
611
+ }
612
+ case 'list_keys': {
613
+ const result = await this.client.listApiKeys();
614
+ return this.formatSuccessResponse(result);
615
+ }
616
+ case 'create_key': {
617
+ const result = await this.client.createApiKey(validated.name);
618
+ return this.formatSuccessResponse({
619
+ ...result,
620
+ security_warning: 'IMPORTANT: Store this API key securely. It cannot be retrieved later.'
621
+ });
622
+ }
623
+ case 'delete_key': {
624
+ await this.client.deleteApiKey(validated.api_key_id);
625
+ return this.formatSuccessResponse({ success: true, message: 'API key deleted successfully' });
626
+ }
627
+ }
628
+ }
629
+ async handleStoreTool(args) {
630
+ const validated = validation_consolidated_1.StoreToolSchema.parse(args);
631
+ switch (validated.action) {
632
+ case 'list_components': {
633
+ const components = await this.client.listComponents();
634
+ return this.formatSuccessResponse(components);
635
+ }
636
+ case 'list_custom': {
637
+ const result = await this.client.listCustomComponents();
638
+ return this.formatSuccessResponse(result);
639
+ }
640
+ case 'create_custom': {
641
+ const result = await this.client.createCustomComponent({ name: validated.name, code: validated.code });
642
+ return this.formatSuccessResponse(result);
643
+ }
644
+ case 'check': {
645
+ const result = await this.client.checkStore();
646
+ return this.formatSuccessResponse(result);
647
+ }
648
+ case 'check_key': {
649
+ const result = await this.client.checkStoreApiKey(validated.api_key);
650
+ return this.formatSuccessResponse(result);
651
+ }
652
+ case 'list_store': {
653
+ const { action: _, ...params } = validated;
654
+ const components = await this.client.listStoreComponents(params);
655
+ return this.formatSuccessResponse(components);
656
+ }
657
+ case 'get_store': {
658
+ const component = await this.client.getStoreComponent(validated.component_id);
659
+ return this.formatSuccessResponse(component);
660
+ }
661
+ case 'list_tags': {
662
+ const tags = await this.client.listStoreTags();
663
+ return this.formatSuccessResponse(tags);
664
+ }
665
+ case 'get_likes': {
666
+ const likes = await this.client.getUserLikes();
667
+ return this.formatSuccessResponse(likes);
668
+ }
669
+ }
670
+ }
671
+ async handleRegistrationTool(args) {
672
+ const validated = validation_consolidated_1.RegistrationToolSchema.parse(args);
673
+ switch (validated.action) {
674
+ case 'get': {
675
+ const result = await this.client.getRegistration();
676
+ return this.formatSuccessResponse(result);
677
+ }
678
+ case 'register': {
679
+ const result = await this.client.registerUser(validated.email);
680
+ return this.formatSuccessResponse(result);
681
+ }
682
+ }
683
+ }
684
+ async handleValidationTool(args) {
685
+ const validated = validation_consolidated_1.ValidationToolSchema.parse(args);
686
+ switch (validated.action) {
687
+ case 'code': {
688
+ const result = await this.client.validateCode(validated.code);
689
+ return this.formatSuccessResponse(result);
690
+ }
691
+ case 'prompt': {
692
+ const result = await this.client.validatePrompt(validated.prompt);
693
+ return this.formatSuccessResponse(result);
694
+ }
695
+ }
696
+ }
697
+ async handleSystemTool(args) {
698
+ const validated = validation_consolidated_1.SystemToolSchema.parse(args);
699
+ switch (validated.action) {
700
+ case 'health': {
701
+ const result = await this.client.healthCheck();
702
+ return this.formatSuccessResponse({ status: result ? 'healthy' : 'unhealthy', healthy: result });
703
+ }
704
+ case 'version': {
705
+ const result = await this.client.getVersion();
706
+ return this.formatSuccessResponse(result);
707
+ }
708
+ case 'logs': {
709
+ const result = await this.client.getLogs(validated.stream);
710
+ return this.formatSuccessResponse(result);
711
+ }
712
+ case 'list_pictures': {
713
+ const pictures = await this.client.listProfilePictures();
714
+ return this.formatSuccessResponse(pictures);
715
+ }
716
+ case 'get_picture': {
717
+ const pictureData = await this.client.getProfilePicture(validated.folder_name, validated.file_name);
718
+ if (!pictureData)
719
+ throw new Error('No picture data received from server');
720
+ const base64Data = Buffer.from(pictureData).toString('base64');
721
+ return this.formatSuccessResponse({ file_name: validated.file_name, content: base64Data });
722
+ }
723
+ case 'list_voices': {
724
+ const voices = await this.client.listElevenLabsVoices();
725
+ return this.formatSuccessResponse(voices);
726
+ }
727
+ }
728
+ }
729
+ async run() {
730
+ const transport = new stdio_js_1.StdioServerTransport();
731
+ await this.server.connect(transport);
732
+ logger_1.logger.info('Langflow MCP server (consolidated) running on stdio');
733
+ }
734
+ async shutdown() {
735
+ logger_1.logger.info('Shutting down Langflow MCP server');
736
+ await this.server.close();
737
+ }
738
+ }
739
+ exports.LangflowMCPServerConsolidated = LangflowMCPServerConsolidated;
740
+ //# sourceMappingURL=server-consolidated.js.map