@lanonasis/cli 3.6.5 → 3.7.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.
- package/README.md +19 -2
- package/dist/commands/api-keys.d.ts +2 -1
- package/dist/commands/api-keys.js +73 -78
- package/dist/commands/auth.js +244 -177
- package/dist/commands/completion.js +31 -39
- package/dist/commands/config.js +162 -201
- package/dist/commands/enhanced-memory.js +11 -17
- package/dist/commands/guide.js +79 -88
- package/dist/commands/init.js +14 -20
- package/dist/commands/mcp.d.ts +10 -0
- package/dist/commands/mcp.js +215 -156
- package/dist/commands/memory.js +77 -83
- package/dist/commands/organization.js +15 -21
- package/dist/commands/topics.js +52 -58
- package/dist/core/achievements.js +19 -26
- package/dist/core/architecture.js +42 -59
- package/dist/core/dashboard.js +71 -81
- package/dist/core/error-handler.js +30 -39
- package/dist/core/power-mode.js +46 -53
- package/dist/core/progress.js +35 -44
- package/dist/core/welcome.js +56 -64
- package/dist/enhanced-cli.js +49 -58
- package/dist/index-simple.js +75 -113
- package/dist/index.js +64 -69
- package/dist/mcp/access-control.js +13 -17
- package/dist/mcp/client/enhanced-client.js +17 -28
- package/dist/mcp/enhanced-server.js +10 -14
- package/dist/mcp/logger.js +3 -7
- package/dist/mcp/memory-state.js +13 -17
- package/dist/mcp/schemas/tool-schemas.d.ts +16 -16
- package/dist/mcp/schemas/tool-schemas.js +122 -126
- package/dist/mcp/server/lanonasis-server.js +66 -57
- package/dist/mcp/transports/transport-manager.js +18 -25
- package/dist/mcp/vector-store.js +6 -10
- package/dist/mcp-server.js +23 -27
- package/dist/utils/api.js +21 -27
- package/dist/utils/config.d.ts +2 -1
- package/dist/utils/config.js +65 -78
- package/dist/utils/formatting.js +6 -14
- package/dist/utils/hash-utils.d.ts +23 -0
- package/dist/utils/hash-utils.js +37 -0
- package/dist/utils/mcp-client.js +76 -117
- package/package.json +36 -5
package/dist/index.js
CHANGED
|
@@ -1,41 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const organization_js_1 = require("./commands/organization.js");
|
|
16
|
-
const mcp_js_1 = require("./commands/mcp.js");
|
|
17
|
-
const api_keys_js_1 = __importDefault(require("./commands/api-keys.js"));
|
|
18
|
-
const config_js_2 = require("./utils/config.js");
|
|
19
|
-
const mcp_client_js_1 = require("./utils/mcp-client.js");
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
import { initCommand } from './commands/init.js';
|
|
6
|
+
import { loginCommand, diagnoseCommand } from './commands/auth.js';
|
|
7
|
+
import { memoryCommands } from './commands/memory.js';
|
|
8
|
+
import { topicCommands } from './commands/topics.js';
|
|
9
|
+
import { configCommands } from './commands/config.js';
|
|
10
|
+
import { orgCommands } from './commands/organization.js';
|
|
11
|
+
import { mcpCommands } from './commands/mcp.js';
|
|
12
|
+
import apiKeysCommand from './commands/api-keys.js';
|
|
13
|
+
import { CLIConfig } from './utils/config.js';
|
|
14
|
+
import { getMCPClient } from './utils/mcp-client.js';
|
|
20
15
|
// Load environment variables
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const require =
|
|
16
|
+
config();
|
|
17
|
+
import { createRequire } from 'module';
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
24
19
|
const packageJson = require('../package.json');
|
|
25
20
|
// Enhanced color scheme (VPS-style)
|
|
26
21
|
const colors = {
|
|
27
|
-
primary:
|
|
28
|
-
success:
|
|
29
|
-
warning:
|
|
30
|
-
error:
|
|
31
|
-
info:
|
|
32
|
-
accent:
|
|
33
|
-
muted:
|
|
34
|
-
highlight:
|
|
22
|
+
primary: chalk.blue.bold,
|
|
23
|
+
success: chalk.green,
|
|
24
|
+
warning: chalk.yellow,
|
|
25
|
+
error: chalk.red,
|
|
26
|
+
info: chalk.cyan,
|
|
27
|
+
accent: chalk.magenta,
|
|
28
|
+
muted: chalk.gray,
|
|
29
|
+
highlight: chalk.white.bold
|
|
35
30
|
};
|
|
36
|
-
const program = new
|
|
31
|
+
const program = new Command();
|
|
37
32
|
// CLI Configuration
|
|
38
|
-
const cliConfig = new
|
|
33
|
+
const cliConfig = new CLIConfig();
|
|
39
34
|
program
|
|
40
35
|
.name('lanonasis')
|
|
41
36
|
.alias('memory')
|
|
@@ -63,7 +58,7 @@ program
|
|
|
63
58
|
actionCommand.parent?.name?.() === 'mcp-server';
|
|
64
59
|
if (opts.mcp !== false && !isMcpFlow && !['init', 'auth', 'login', 'health', 'status'].includes(actionCommand.name())) {
|
|
65
60
|
try {
|
|
66
|
-
const client =
|
|
61
|
+
const client = getMCPClient();
|
|
67
62
|
if (!client.isConnectedToServer()) {
|
|
68
63
|
const useRemote = await cliConfig.isAuthenticated();
|
|
69
64
|
await client.connect({ useRemote });
|
|
@@ -151,7 +146,7 @@ const healthCheck = async () => {
|
|
|
151
146
|
console.log();
|
|
152
147
|
process.stdout.write('MCP Server status: ');
|
|
153
148
|
try {
|
|
154
|
-
const client =
|
|
149
|
+
const client = getMCPClient();
|
|
155
150
|
if (client.isConnectedToServer()) {
|
|
156
151
|
console.log(colors.success('✅ Connected'));
|
|
157
152
|
}
|
|
@@ -184,8 +179,8 @@ const requireAuth = (command) => {
|
|
|
184
179
|
await cliConfig.init();
|
|
185
180
|
const isAuthenticated = await cliConfig.isAuthenticated();
|
|
186
181
|
if (!isAuthenticated) {
|
|
187
|
-
console.error(
|
|
188
|
-
console.log(
|
|
182
|
+
console.error(chalk.red('✖ Authentication required'));
|
|
183
|
+
console.log(chalk.yellow('Please run:'), chalk.white('lanonasis auth login'));
|
|
189
184
|
process.exit(1);
|
|
190
185
|
}
|
|
191
186
|
});
|
|
@@ -195,7 +190,7 @@ program
|
|
|
195
190
|
.command('init')
|
|
196
191
|
.description('Initialize CLI configuration')
|
|
197
192
|
.option('-f, --force', 'overwrite existing configuration')
|
|
198
|
-
.action(
|
|
193
|
+
.action(initCommand);
|
|
199
194
|
// Authentication commands (no auth required)
|
|
200
195
|
const authCmd = program
|
|
201
196
|
.command('auth')
|
|
@@ -206,13 +201,13 @@ authCmd
|
|
|
206
201
|
.description('Login to your MaaS account')
|
|
207
202
|
.option('-e, --email <email>', 'email address')
|
|
208
203
|
.option('-p, --password <password>', 'password')
|
|
209
|
-
.action(
|
|
204
|
+
.action(loginCommand);
|
|
210
205
|
authCmd
|
|
211
206
|
.command('logout')
|
|
212
207
|
.description('Logout from your account')
|
|
213
208
|
.action(async () => {
|
|
214
209
|
await cliConfig.logout();
|
|
215
|
-
console.log(
|
|
210
|
+
console.log(chalk.green('✓ Logged out successfully'));
|
|
216
211
|
process.exit(0);
|
|
217
212
|
});
|
|
218
213
|
authCmd
|
|
@@ -225,10 +220,10 @@ authCmd
|
|
|
225
220
|
const lastFailure = cliConfig.getLastAuthFailure();
|
|
226
221
|
const authMethod = cliConfig.get('authMethod');
|
|
227
222
|
const lastValidated = cliConfig.get('lastValidated');
|
|
228
|
-
console.log(
|
|
223
|
+
console.log(chalk.blue.bold('🔐 Authentication Status'));
|
|
229
224
|
console.log('━'.repeat(40));
|
|
230
225
|
if (isAuth && user) {
|
|
231
|
-
console.log(
|
|
226
|
+
console.log(chalk.green('✓ Authenticated'));
|
|
232
227
|
console.log(`Email: ${user.email}`);
|
|
233
228
|
console.log(`Organization: ${user.organization_id}`);
|
|
234
229
|
console.log(`Plan: ${user.plan}`);
|
|
@@ -241,13 +236,13 @@ authCmd
|
|
|
241
236
|
}
|
|
242
237
|
}
|
|
243
238
|
else {
|
|
244
|
-
console.log(
|
|
245
|
-
console.log(
|
|
239
|
+
console.log(chalk.red('✖ Not authenticated'));
|
|
240
|
+
console.log(chalk.yellow('Run:'), chalk.white('memory login'));
|
|
246
241
|
}
|
|
247
242
|
// Show failure tracking information
|
|
248
243
|
if (failureCount > 0) {
|
|
249
244
|
console.log();
|
|
250
|
-
console.log(
|
|
245
|
+
console.log(chalk.yellow('⚠️ Authentication Issues:'));
|
|
251
246
|
console.log(`Failed attempts: ${failureCount}`);
|
|
252
247
|
if (lastFailure) {
|
|
253
248
|
const failureDate = new Date(lastFailure);
|
|
@@ -255,26 +250,26 @@ authCmd
|
|
|
255
250
|
}
|
|
256
251
|
if (cliConfig.shouldDelayAuth()) {
|
|
257
252
|
const delayMs = cliConfig.getAuthDelayMs();
|
|
258
|
-
console.log(
|
|
253
|
+
console.log(chalk.yellow(`Next retry delay: ${Math.round(delayMs / 1000)} seconds`));
|
|
259
254
|
}
|
|
260
255
|
console.log();
|
|
261
|
-
console.log(
|
|
262
|
-
console.log(
|
|
256
|
+
console.log(chalk.cyan('💡 To reset failure count:'));
|
|
257
|
+
console.log(chalk.white(' lanonasis auth logout && lanonasis auth login'));
|
|
263
258
|
}
|
|
264
259
|
});
|
|
265
260
|
authCmd
|
|
266
261
|
.command('diagnose')
|
|
267
262
|
.description('Diagnose authentication issues')
|
|
268
|
-
.action(
|
|
263
|
+
.action(diagnoseCommand);
|
|
269
264
|
// MCP Commands (primary interface)
|
|
270
|
-
|
|
265
|
+
mcpCommands(program);
|
|
271
266
|
// Memory commands (require auth) - now MCP-powered by default
|
|
272
267
|
const memoryCmd = program
|
|
273
268
|
.command('memory')
|
|
274
269
|
.alias('mem')
|
|
275
270
|
.description('Memory management commands');
|
|
276
271
|
requireAuth(memoryCmd);
|
|
277
|
-
|
|
272
|
+
memoryCommands(memoryCmd);
|
|
278
273
|
// Note: Memory commands are now MCP-powered when available
|
|
279
274
|
// REPL command (lightweight REPL for memory operations)
|
|
280
275
|
program
|
|
@@ -323,23 +318,23 @@ const topicCmd = program
|
|
|
323
318
|
.alias('topics')
|
|
324
319
|
.description('Topic management commands');
|
|
325
320
|
requireAuth(topicCmd);
|
|
326
|
-
|
|
321
|
+
topicCommands(topicCmd);
|
|
327
322
|
// Configuration commands (require auth)
|
|
328
323
|
const configCmd = program
|
|
329
324
|
.command('config')
|
|
330
325
|
.description('Configuration management');
|
|
331
326
|
requireAuth(configCmd);
|
|
332
|
-
|
|
327
|
+
configCommands(configCmd);
|
|
333
328
|
// Organization commands (require auth)
|
|
334
329
|
const orgCmd = program
|
|
335
330
|
.command('org')
|
|
336
331
|
.alias('organization')
|
|
337
332
|
.description('Organization management');
|
|
338
333
|
requireAuth(orgCmd);
|
|
339
|
-
|
|
334
|
+
orgCommands(orgCmd);
|
|
340
335
|
// API Key management commands (require auth)
|
|
341
|
-
requireAuth(
|
|
342
|
-
program.addCommand(
|
|
336
|
+
requireAuth(apiKeysCommand);
|
|
337
|
+
program.addCommand(apiKeysCommand);
|
|
343
338
|
// Dashboard management commands (require auth)
|
|
344
339
|
const dashboardCmd = program
|
|
345
340
|
.command('dashboard')
|
|
@@ -493,7 +488,7 @@ deployCmd
|
|
|
493
488
|
{ name: 'Documentation', url: 'https://api.lanonasis.com/docs', status: 'healthy' },
|
|
494
489
|
{ name: 'Memory API', url: 'https://api.lanonasis.com/memories', status: 'healthy' },
|
|
495
490
|
{ name: 'MCP Server', url: 'https://mcp.lanonasis.com/api/v1/events', status: 'healthy' },
|
|
496
|
-
{ name: 'Authentication', url: 'https://
|
|
491
|
+
{ name: 'Authentication', url: 'https://auth.lanonasis.com', status: 'healthy' }
|
|
497
492
|
];
|
|
498
493
|
for (const service of services) {
|
|
499
494
|
process.stdout.write(`${service.name.padEnd(20)}: `);
|
|
@@ -541,9 +536,9 @@ program
|
|
|
541
536
|
await cliConfig.init();
|
|
542
537
|
const isAuth = await cliConfig.isAuthenticated();
|
|
543
538
|
const apiUrl = cliConfig.getApiUrl();
|
|
544
|
-
console.log(
|
|
539
|
+
console.log(chalk.blue.bold('MaaS CLI Status'));
|
|
545
540
|
console.log(`API URL: ${apiUrl}`);
|
|
546
|
-
console.log(`Authenticated: ${isAuth ?
|
|
541
|
+
console.log(`Authenticated: ${isAuth ? chalk.green('Yes') : chalk.red('No')}`);
|
|
547
542
|
if (isAuth) {
|
|
548
543
|
const user = await cliConfig.getCurrentUser();
|
|
549
544
|
if (user) {
|
|
@@ -575,46 +570,46 @@ program
|
|
|
575
570
|
.description('Open documentation in browser')
|
|
576
571
|
.action(() => {
|
|
577
572
|
const url = 'https://api.lanonasis.com/docs';
|
|
578
|
-
console.log(
|
|
573
|
+
console.log(chalk.blue(`Opening documentation: ${url}`));
|
|
579
574
|
// Try to open in browser
|
|
580
575
|
import('open').then(open => {
|
|
581
576
|
open.default(url).catch(() => {
|
|
582
|
-
console.log(
|
|
583
|
-
console.log(
|
|
577
|
+
console.log(chalk.yellow('Could not open browser automatically.'));
|
|
578
|
+
console.log(chalk.white(`Please visit: ${url}`));
|
|
584
579
|
});
|
|
585
580
|
}).catch(() => {
|
|
586
|
-
console.log(
|
|
581
|
+
console.log(chalk.white(`Please visit: ${url}`));
|
|
587
582
|
});
|
|
588
583
|
});
|
|
589
584
|
// Help customization
|
|
590
585
|
program.configureHelp({
|
|
591
586
|
formatHelp: (cmd, helper) => {
|
|
592
|
-
let help =
|
|
587
|
+
let help = chalk.blue.bold('🧠 Memory as a Service CLI\n\n');
|
|
593
588
|
help += helper.commandUsage(cmd) + '\n\n';
|
|
594
589
|
if (cmd.description()) {
|
|
595
|
-
help +=
|
|
590
|
+
help += chalk.yellow('Description:\n');
|
|
596
591
|
help += ` ${cmd.description()}\n\n`;
|
|
597
592
|
}
|
|
598
593
|
const commands = helper.visibleCommands(cmd);
|
|
599
594
|
if (commands.length > 0) {
|
|
600
|
-
help +=
|
|
595
|
+
help += chalk.yellow('Commands:\n');
|
|
601
596
|
const maxNameLength = Math.max(...commands.map(c => c.name().length));
|
|
602
597
|
commands.forEach(c => {
|
|
603
598
|
const name = c.name().padEnd(maxNameLength);
|
|
604
|
-
help += ` ${
|
|
599
|
+
help += ` ${chalk.white(name)} ${c.description()}\n`;
|
|
605
600
|
});
|
|
606
601
|
help += '\n';
|
|
607
602
|
}
|
|
608
603
|
const options = helper.visibleOptions(cmd);
|
|
609
604
|
if (options.length > 0) {
|
|
610
|
-
help +=
|
|
605
|
+
help += chalk.yellow('Options:\n');
|
|
611
606
|
options.forEach(option => {
|
|
612
607
|
help += ` ${option.flags.padEnd(20)} ${option.description}\n`;
|
|
613
608
|
});
|
|
614
609
|
help += '\n';
|
|
615
610
|
}
|
|
616
|
-
help +=
|
|
617
|
-
help +=
|
|
611
|
+
help += chalk.gray('For more help on a specific command, run: memory <command> --help\n');
|
|
612
|
+
help += chalk.gray('Documentation: https://api.lanonasis.com/docs\n');
|
|
618
613
|
return help;
|
|
619
614
|
}
|
|
620
615
|
});
|
|
@@ -630,7 +625,7 @@ async function main() {
|
|
|
630
625
|
}
|
|
631
626
|
catch (error) {
|
|
632
627
|
if (error instanceof Error) {
|
|
633
|
-
console.error(
|
|
628
|
+
console.error(chalk.red('✖ Error:'), error.message);
|
|
634
629
|
if (process.env.CLI_VERBOSE === 'true') {
|
|
635
630
|
console.error(error.stack);
|
|
636
631
|
}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Memory Access Control System
|
|
4
3
|
* Implements granular permissions and audit logging inspired by mem0's ACL system
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const logger_js_1 = require("./logger.js");
|
|
10
|
-
class MemoryAccessControl {
|
|
5
|
+
import { CLIConfig } from '../utils/config.js';
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
export class MemoryAccessControl {
|
|
11
8
|
config;
|
|
12
9
|
accessRules = new Map();
|
|
13
10
|
accessLogs = [];
|
|
14
11
|
constructor() {
|
|
15
|
-
this.config = new
|
|
12
|
+
this.config = new CLIConfig();
|
|
16
13
|
}
|
|
17
14
|
/**
|
|
18
15
|
* Check if user has access to create memories in an app
|
|
@@ -28,7 +25,7 @@ class MemoryAccessControl {
|
|
|
28
25
|
return rules.some(rule => rule.permission === 'write' || rule.permission === 'admin');
|
|
29
26
|
}
|
|
30
27
|
catch (error) {
|
|
31
|
-
|
|
28
|
+
logger.error('Access check failed', { error, userId, appId });
|
|
32
29
|
return false;
|
|
33
30
|
}
|
|
34
31
|
}
|
|
@@ -53,7 +50,7 @@ class MemoryAccessControl {
|
|
|
53
50
|
(rule.memory_id === memoryId || !rule.memory_id));
|
|
54
51
|
}
|
|
55
52
|
catch (error) {
|
|
56
|
-
|
|
53
|
+
logger.error('Memory access check failed', { error, memoryId, appId });
|
|
57
54
|
return false;
|
|
58
55
|
}
|
|
59
56
|
}
|
|
@@ -71,7 +68,7 @@ class MemoryAccessControl {
|
|
|
71
68
|
return allMemories;
|
|
72
69
|
}
|
|
73
70
|
catch (error) {
|
|
74
|
-
|
|
71
|
+
logger.error('Failed to get accessible memories', { error, userId, appId });
|
|
75
72
|
return [];
|
|
76
73
|
}
|
|
77
74
|
}
|
|
@@ -93,14 +90,14 @@ class MemoryAccessControl {
|
|
|
93
90
|
};
|
|
94
91
|
this.accessLogs.push(logEntry);
|
|
95
92
|
// In production, this would be persisted to database
|
|
96
|
-
|
|
93
|
+
logger.debug('Memory access logged', logEntry);
|
|
97
94
|
// Keep only recent logs in memory (last 1000)
|
|
98
95
|
if (this.accessLogs.length > 1000) {
|
|
99
96
|
this.accessLogs = this.accessLogs.slice(-1000);
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
catch (error) {
|
|
103
|
-
|
|
100
|
+
logger.error('Failed to log memory access', { error, memoryId, appId, accessType });
|
|
104
101
|
}
|
|
105
102
|
}
|
|
106
103
|
/**
|
|
@@ -121,7 +118,7 @@ class MemoryAccessControl {
|
|
|
121
118
|
const existingRules = this.accessRules.get(key) || [];
|
|
122
119
|
existingRules.push(rule);
|
|
123
120
|
this.accessRules.set(key, existingRules);
|
|
124
|
-
|
|
121
|
+
logger.info('Access granted', { userId, appId, permission, memoryId });
|
|
125
122
|
}
|
|
126
123
|
/**
|
|
127
124
|
* Revoke access to a memory or app
|
|
@@ -136,7 +133,7 @@ class MemoryAccessControl {
|
|
|
136
133
|
return rule;
|
|
137
134
|
});
|
|
138
135
|
this.accessRules.set(key, updatedRules);
|
|
139
|
-
|
|
136
|
+
logger.info('Access revoked', { userId: _userId, appId: _appId, memoryId });
|
|
140
137
|
}
|
|
141
138
|
/**
|
|
142
139
|
* Get access logs for audit purposes
|
|
@@ -196,7 +193,7 @@ class MemoryAccessControl {
|
|
|
196
193
|
return response.data;
|
|
197
194
|
}
|
|
198
195
|
catch (error) {
|
|
199
|
-
|
|
196
|
+
logger.error('Failed to get memory info', { error, memoryId });
|
|
200
197
|
return null;
|
|
201
198
|
}
|
|
202
199
|
}
|
|
@@ -214,7 +211,7 @@ class MemoryAccessControl {
|
|
|
214
211
|
return response.data.memories?.map((m) => m.id) || [];
|
|
215
212
|
}
|
|
216
213
|
catch (error) {
|
|
217
|
-
|
|
214
|
+
logger.error('Failed to get user memories', { error, userId });
|
|
218
215
|
return [];
|
|
219
216
|
}
|
|
220
217
|
}
|
|
@@ -227,4 +224,3 @@ class MemoryAccessControl {
|
|
|
227
224
|
return `acl_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
|
-
exports.MemoryAccessControl = MemoryAccessControl;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Enhanced MCP Client with advanced features
|
|
4
3
|
* Provides multi-server support, connection pooling, and better error handling
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
12
|
-
const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
13
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
-
const events_1 = require("events");
|
|
15
|
-
class EnhancedMCPClient extends events_1.EventEmitter {
|
|
5
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
6
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
export class EnhancedMCPClient extends EventEmitter {
|
|
16
10
|
clients = new Map();
|
|
17
11
|
transports = new Map();
|
|
18
12
|
connectionStatus = new Map();
|
|
@@ -28,13 +22,13 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
28
22
|
*/
|
|
29
23
|
setupEventHandlers() {
|
|
30
24
|
this.on('connection:established', (server) => {
|
|
31
|
-
console.log(
|
|
25
|
+
console.log(chalk.green(`✅ Connected to ${server}`));
|
|
32
26
|
});
|
|
33
27
|
this.on('connection:lost', (server) => {
|
|
34
|
-
console.log(
|
|
28
|
+
console.log(chalk.yellow(`⚠️ Lost connection to ${server}`));
|
|
35
29
|
});
|
|
36
30
|
this.on('connection:error', (server, error) => {
|
|
37
|
-
console.log(
|
|
31
|
+
console.log(chalk.red(`❌ Connection error for ${server}: ${error.message}`));
|
|
38
32
|
});
|
|
39
33
|
}
|
|
40
34
|
/**
|
|
@@ -84,7 +78,7 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
84
78
|
}
|
|
85
79
|
// Exponential backoff
|
|
86
80
|
const delay = Math.min(1000 * Math.pow(2, attempts), 10000);
|
|
87
|
-
console.log(
|
|
81
|
+
console.log(chalk.yellow(`⏳ Retrying connection to ${config.name} in ${delay}ms...`));
|
|
88
82
|
await this.delay(delay);
|
|
89
83
|
}
|
|
90
84
|
}
|
|
@@ -108,7 +102,7 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
108
102
|
if (!config.command) {
|
|
109
103
|
throw new Error('Command required for stdio transport');
|
|
110
104
|
}
|
|
111
|
-
transport = new
|
|
105
|
+
transport = new StdioClientTransport({
|
|
112
106
|
command: config.command,
|
|
113
107
|
args: config.args || []
|
|
114
108
|
});
|
|
@@ -130,15 +124,11 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
130
124
|
throw new Error(`Unsupported transport type: ${config.type}`);
|
|
131
125
|
}
|
|
132
126
|
this.transports.set(config.name, transport);
|
|
133
|
-
const client = new
|
|
127
|
+
const client = new Client({
|
|
134
128
|
name: `lanonasis-cli-${config.name}`,
|
|
135
129
|
version: '3.0.1'
|
|
136
130
|
}, {
|
|
137
|
-
capabilities: {
|
|
138
|
-
tools: {},
|
|
139
|
-
resources: {},
|
|
140
|
-
prompts: {}
|
|
141
|
-
}
|
|
131
|
+
capabilities: {}
|
|
142
132
|
});
|
|
143
133
|
await client.connect(transport);
|
|
144
134
|
return client;
|
|
@@ -214,7 +204,7 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
214
204
|
// Try failover to another server
|
|
215
205
|
const failoverServer = await this.selectFailoverServer(server, toolName);
|
|
216
206
|
if (failoverServer) {
|
|
217
|
-
console.log(
|
|
207
|
+
console.log(chalk.yellow(`⚠️ Failing over to ${failoverServer}...`));
|
|
218
208
|
const failoverClient = this.clients.get(failoverServer);
|
|
219
209
|
if (failoverClient) {
|
|
220
210
|
return failoverClient.callTool({
|
|
@@ -302,7 +292,7 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
302
292
|
// Attempt reconnection
|
|
303
293
|
const config = this.getServerConfig(serverName);
|
|
304
294
|
if (config) {
|
|
305
|
-
console.log(
|
|
295
|
+
console.log(chalk.yellow(`⚠️ Attempting to reconnect to ${serverName}...`));
|
|
306
296
|
await this.connectSingle(config);
|
|
307
297
|
}
|
|
308
298
|
}
|
|
@@ -345,10 +335,10 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
345
335
|
for (const [name, client] of this.clients) {
|
|
346
336
|
try {
|
|
347
337
|
await client.close();
|
|
348
|
-
console.log(
|
|
338
|
+
console.log(chalk.gray(`Disconnected from ${name}`));
|
|
349
339
|
}
|
|
350
340
|
catch {
|
|
351
|
-
console.log(
|
|
341
|
+
console.log(chalk.yellow(`Warning: Error disconnecting from ${name}`));
|
|
352
342
|
}
|
|
353
343
|
}
|
|
354
344
|
this.clients.clear();
|
|
@@ -379,6 +369,5 @@ class EnhancedMCPClient extends events_1.EventEmitter {
|
|
|
379
369
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
380
370
|
}
|
|
381
371
|
}
|
|
382
|
-
exports.EnhancedMCPClient = EnhancedMCPClient;
|
|
383
372
|
// Export singleton instance
|
|
384
|
-
|
|
373
|
+
export const enhancedMCPClient = new EnhancedMCPClient();
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
/**
|
|
4
3
|
* Enhanced MCP Server - Simplified working version
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const logger_js_1 = require("./logger.js");
|
|
12
|
-
class EnhancedMCPServer {
|
|
5
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
6
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
7
|
+
import { CLIConfig } from '../utils/config.js';
|
|
8
|
+
import { logger } from './logger.js';
|
|
9
|
+
export class EnhancedMCPServer {
|
|
13
10
|
server;
|
|
14
11
|
config;
|
|
15
12
|
constructor() {
|
|
16
|
-
this.config = new
|
|
17
|
-
this.server = new
|
|
13
|
+
this.config = new CLIConfig();
|
|
14
|
+
this.server = new Server({
|
|
18
15
|
name: "lanonasis-maas-server",
|
|
19
16
|
version: "1.0.0"
|
|
20
17
|
}, {
|
|
@@ -28,17 +25,16 @@ class EnhancedMCPServer {
|
|
|
28
25
|
async start() {
|
|
29
26
|
try {
|
|
30
27
|
await this.config.init();
|
|
31
|
-
const transport = new
|
|
28
|
+
const transport = new StdioServerTransport();
|
|
32
29
|
await this.server.connect(transport);
|
|
33
|
-
|
|
30
|
+
logger.info('Enhanced MCP Server started successfully');
|
|
34
31
|
}
|
|
35
32
|
catch (error) {
|
|
36
|
-
|
|
33
|
+
logger.error('Failed to start Enhanced MCP Server', { error });
|
|
37
34
|
throw error;
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
|
-
exports.EnhancedMCPServer = EnhancedMCPServer;
|
|
42
38
|
// Main execution
|
|
43
39
|
async function main() {
|
|
44
40
|
const server = new EnhancedMCPServer();
|
package/dist/mcp/logger.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Enhanced logging system for MCP server
|
|
4
3
|
* Provides structured logging with different levels and contexts
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
exports.logger = exports.Logger = void 0;
|
|
8
|
-
class Logger {
|
|
5
|
+
export class Logger {
|
|
9
6
|
defaultContext;
|
|
10
7
|
context = {};
|
|
11
8
|
constructor(defaultContext = {}) {
|
|
@@ -44,8 +41,7 @@ class Logger {
|
|
|
44
41
|
return new Logger({ ...this.context, ...context });
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
service: 'lanonasis-mcp-server',
|
|
44
|
+
export const logger = new Logger({
|
|
45
|
+
service: 'mcp-core',
|
|
50
46
|
version: '1.0.0'
|
|
51
47
|
});
|