@lanonasis/cli 3.7.8 → 3.8.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/dist/commands/auth.js +3 -5
- package/dist/commands/config.js +1 -1
- package/dist/commands/mcp.js +37 -2
- package/dist/mcp/schemas/tool-schemas.d.ts +12 -12
- package/dist/mcp/server/lanonasis-server.d.ts +9 -0
- package/dist/mcp/server/lanonasis-server.js +29 -0
- package/dist/mcp-server-entry.d.ts +20 -0
- package/dist/mcp-server-entry.js +54 -0
- package/dist/mcp-server.js +2 -1
- package/dist/utils/api.js +1 -1
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.js +44 -15
- package/dist/utils/crypto-utils.js +1 -1
- package/package.json +6 -5
package/dist/commands/auth.js
CHANGED
|
@@ -370,7 +370,7 @@ export async function diagnoseCommand() {
|
|
|
370
370
|
// Step 2: Check stored credentials
|
|
371
371
|
console.log(chalk.cyan('\n2. Stored Credentials'));
|
|
372
372
|
const token = config.getToken();
|
|
373
|
-
const vendorKey = config.
|
|
373
|
+
const vendorKey = await config.getVendorKeyAsync();
|
|
374
374
|
const authMethod = config.get('authMethod');
|
|
375
375
|
if (vendorKey) {
|
|
376
376
|
diagnostics.hasCredentials = true;
|
|
@@ -825,10 +825,8 @@ async function handleCredentialsFlow(options, config) {
|
|
|
825
825
|
if (response.user.role) {
|
|
826
826
|
console.log(`Role: ${response.user.role}`);
|
|
827
827
|
}
|
|
828
|
-
console.log(chalk.gray('✓ API access configured'));
|
|
829
|
-
console.log();
|
|
830
|
-
console.log(chalk.dim('Note: MCP WebSocket commands require a vendor key.'));
|
|
831
|
-
console.log(chalk.dim('Run'), chalk.white('onasis auth vendor-key <key>'), chalk.dim('to configure MCP access.'));
|
|
828
|
+
console.log(chalk.gray('✓ API and MCP access configured'));
|
|
829
|
+
console.log(chalk.dim('Your JWT token works with all services: API, MCP, CLI.'));
|
|
832
830
|
}
|
|
833
831
|
catch (error) {
|
|
834
832
|
spinner.fail('Login failed');
|
package/dist/commands/config.js
CHANGED
|
@@ -382,7 +382,7 @@ export function configCommands(program) {
|
|
|
382
382
|
// Step 2: Validate authentication configuration
|
|
383
383
|
console.log(chalk.cyan('\n2. Authentication Configuration'));
|
|
384
384
|
const token = config.getToken();
|
|
385
|
-
const vendorKey = config.
|
|
385
|
+
const vendorKey = await config.getVendorKeyAsync();
|
|
386
386
|
const authMethod = config.get('authMethod');
|
|
387
387
|
if (!token && !vendorKey) {
|
|
388
388
|
console.log(chalk.yellow(' ⚠ No authentication credentials configured'));
|
package/dist/commands/mcp.js
CHANGED
|
@@ -190,7 +190,7 @@ export function mcpCommands(program) {
|
|
|
190
190
|
const rootBase = restUrl.replace(/\/api\/v1$/, '');
|
|
191
191
|
const healthUrl = `${rootBase}/health`;
|
|
192
192
|
const token = config.getToken();
|
|
193
|
-
const vendorKey = config.
|
|
193
|
+
const vendorKey = await config.getVendorKeyAsync();
|
|
194
194
|
const headers = {};
|
|
195
195
|
if (vendorKey) {
|
|
196
196
|
headers['X-API-Key'] = vendorKey;
|
|
@@ -457,6 +457,41 @@ export function mcpCommands(program) {
|
|
|
457
457
|
console.log(' --auto : Auto-detect based on configuration (default)');
|
|
458
458
|
}
|
|
459
459
|
});
|
|
460
|
+
// Start MCP server for external clients
|
|
461
|
+
mcp.command('start')
|
|
462
|
+
.description('Start MCP server for external clients (Claude Desktop, Cursor, etc.)')
|
|
463
|
+
.option('--transport <type>', 'Transport: stdio (default), ws, http, sse', 'stdio')
|
|
464
|
+
.option('--port <number>', 'Port for ws/http/sse', '3009')
|
|
465
|
+
.option('--host <address>', 'Host address', '127.0.0.1')
|
|
466
|
+
.action(async (options) => {
|
|
467
|
+
const apiKey = process.env.LANONASIS_API_KEY;
|
|
468
|
+
if (!apiKey) {
|
|
469
|
+
console.error('Error: LANONASIS_API_KEY environment variable required');
|
|
470
|
+
process.exit(1);
|
|
471
|
+
}
|
|
472
|
+
try {
|
|
473
|
+
const { LanonasisMCPServer } = await import('../mcp/server/lanonasis-server.js');
|
|
474
|
+
const server = new LanonasisMCPServer({
|
|
475
|
+
apiKey,
|
|
476
|
+
transport: options.transport,
|
|
477
|
+
port: parseInt(options.port, 10),
|
|
478
|
+
host: options.host
|
|
479
|
+
});
|
|
480
|
+
if (options.transport === 'stdio') {
|
|
481
|
+
// Log to stderr since stdout is for MCP protocol
|
|
482
|
+
console.error(`Starting MCP server in stdio mode...`);
|
|
483
|
+
await server.startStdio();
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
console.error(`Starting MCP server on ${options.host}:${options.port} (${options.transport})...`);
|
|
487
|
+
await server.start();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
console.error(`Failed to start MCP server: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
492
|
+
process.exit(1);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
460
495
|
// Diagnose MCP connection issues
|
|
461
496
|
mcp.command('diagnose')
|
|
462
497
|
.description('Diagnose MCP connection issues')
|
|
@@ -483,7 +518,7 @@ export function mcpCommands(program) {
|
|
|
483
518
|
// Step 1: Check authentication status
|
|
484
519
|
console.log(chalk.cyan('1. Authentication Status'));
|
|
485
520
|
const token = config.getToken();
|
|
486
|
-
const vendorKey = config.
|
|
521
|
+
const vendorKey = await config.getVendorKeyAsync();
|
|
487
522
|
if (!token && !vendorKey) {
|
|
488
523
|
console.log(chalk.red(' ✖ No authentication credentials found'));
|
|
489
524
|
console.log(chalk.gray(' → Run: lanonasis auth login'));
|
|
@@ -15,15 +15,15 @@ export declare const MemoryCreateSchema: z.ZodObject<{
|
|
|
15
15
|
content?: string;
|
|
16
16
|
tags?: string[];
|
|
17
17
|
topic_id?: string;
|
|
18
|
-
memory_type?: "context" | "reference" | "note";
|
|
19
18
|
metadata?: Record<string, any>;
|
|
19
|
+
memory_type?: "context" | "reference" | "note";
|
|
20
20
|
}, {
|
|
21
21
|
title?: string;
|
|
22
22
|
content?: string;
|
|
23
23
|
tags?: string[];
|
|
24
24
|
topic_id?: string;
|
|
25
|
-
memory_type?: "context" | "reference" | "note";
|
|
26
25
|
metadata?: Record<string, any>;
|
|
26
|
+
memory_type?: "context" | "reference" | "note";
|
|
27
27
|
}>;
|
|
28
28
|
export declare const MemorySearchSchema: z.ZodObject<{
|
|
29
29
|
query: z.ZodString;
|
|
@@ -59,15 +59,15 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
|
|
|
59
59
|
content?: string;
|
|
60
60
|
tags?: string[];
|
|
61
61
|
memory_id?: string;
|
|
62
|
-
memory_type?: "context" | "reference" | "note";
|
|
63
62
|
metadata?: Record<string, any>;
|
|
63
|
+
memory_type?: "context" | "reference" | "note";
|
|
64
64
|
}, {
|
|
65
65
|
title?: string;
|
|
66
66
|
content?: string;
|
|
67
67
|
tags?: string[];
|
|
68
68
|
memory_id?: string;
|
|
69
|
-
memory_type?: "context" | "reference" | "note";
|
|
70
69
|
metadata?: Record<string, any>;
|
|
70
|
+
memory_type?: "context" | "reference" | "note";
|
|
71
71
|
}>;
|
|
72
72
|
export declare const MemoryDeleteSchema: z.ZodObject<{
|
|
73
73
|
memory_id: z.ZodString;
|
|
@@ -217,13 +217,13 @@ export declare const BulkOperationSchema: z.ZodObject<{
|
|
|
217
217
|
transaction: z.ZodDefault<z.ZodBoolean>;
|
|
218
218
|
}, "strip", z.ZodTypeAny, {
|
|
219
219
|
operation?: "create" | "delete" | "update";
|
|
220
|
-
entity_type?: "topic" | "memory" | "apikey";
|
|
221
220
|
items?: Record<string, any>[];
|
|
221
|
+
entity_type?: "topic" | "memory" | "apikey";
|
|
222
222
|
transaction?: boolean;
|
|
223
223
|
}, {
|
|
224
224
|
operation?: "create" | "delete" | "update";
|
|
225
|
-
entity_type?: "topic" | "memory" | "apikey";
|
|
226
225
|
items?: Record<string, any>[];
|
|
226
|
+
entity_type?: "topic" | "memory" | "apikey";
|
|
227
227
|
transaction?: boolean;
|
|
228
228
|
}>;
|
|
229
229
|
export declare const ImportExportSchema: z.ZodObject<{
|
|
@@ -387,15 +387,15 @@ export declare const MCPSchemas: {
|
|
|
387
387
|
content?: string;
|
|
388
388
|
tags?: string[];
|
|
389
389
|
topic_id?: string;
|
|
390
|
-
memory_type?: "context" | "reference" | "note";
|
|
391
390
|
metadata?: Record<string, any>;
|
|
391
|
+
memory_type?: "context" | "reference" | "note";
|
|
392
392
|
}, {
|
|
393
393
|
title?: string;
|
|
394
394
|
content?: string;
|
|
395
395
|
tags?: string[];
|
|
396
396
|
topic_id?: string;
|
|
397
|
-
memory_type?: "context" | "reference" | "note";
|
|
398
397
|
metadata?: Record<string, any>;
|
|
398
|
+
memory_type?: "context" | "reference" | "note";
|
|
399
399
|
}>;
|
|
400
400
|
search: z.ZodObject<{
|
|
401
401
|
query: z.ZodString;
|
|
@@ -431,15 +431,15 @@ export declare const MCPSchemas: {
|
|
|
431
431
|
content?: string;
|
|
432
432
|
tags?: string[];
|
|
433
433
|
memory_id?: string;
|
|
434
|
-
memory_type?: "context" | "reference" | "note";
|
|
435
434
|
metadata?: Record<string, any>;
|
|
435
|
+
memory_type?: "context" | "reference" | "note";
|
|
436
436
|
}, {
|
|
437
437
|
title?: string;
|
|
438
438
|
content?: string;
|
|
439
439
|
tags?: string[];
|
|
440
440
|
memory_id?: string;
|
|
441
|
-
memory_type?: "context" | "reference" | "note";
|
|
442
441
|
metadata?: Record<string, any>;
|
|
442
|
+
memory_type?: "context" | "reference" | "note";
|
|
443
443
|
}>;
|
|
444
444
|
delete: z.ZodObject<{
|
|
445
445
|
memory_id: z.ZodString;
|
|
@@ -597,13 +597,13 @@ export declare const MCPSchemas: {
|
|
|
597
597
|
transaction: z.ZodDefault<z.ZodBoolean>;
|
|
598
598
|
}, "strip", z.ZodTypeAny, {
|
|
599
599
|
operation?: "create" | "delete" | "update";
|
|
600
|
-
entity_type?: "topic" | "memory" | "apikey";
|
|
601
600
|
items?: Record<string, any>[];
|
|
601
|
+
entity_type?: "topic" | "memory" | "apikey";
|
|
602
602
|
transaction?: boolean;
|
|
603
603
|
}, {
|
|
604
604
|
operation?: "create" | "delete" | "update";
|
|
605
|
-
entity_type?: "topic" | "memory" | "apikey";
|
|
606
605
|
items?: Record<string, any>[];
|
|
606
|
+
entity_type?: "topic" | "memory" | "apikey";
|
|
607
607
|
transaction?: boolean;
|
|
608
608
|
}>;
|
|
609
609
|
importExport: z.ZodObject<{
|
|
@@ -9,6 +9,10 @@ export interface LanonasisServerOptions {
|
|
|
9
9
|
verbose?: boolean;
|
|
10
10
|
apiUrl?: string;
|
|
11
11
|
token?: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
transport?: 'stdio' | 'ws' | 'http' | 'sse';
|
|
14
|
+
port?: number;
|
|
15
|
+
host?: string;
|
|
12
16
|
preferredTransport?: 'stdio' | 'websocket' | 'http';
|
|
13
17
|
enableTransportFallback?: boolean;
|
|
14
18
|
}
|
|
@@ -209,6 +213,11 @@ export declare class LanonasisMCPServer {
|
|
|
209
213
|
* Start the server
|
|
210
214
|
*/
|
|
211
215
|
start(): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* Start the server in stdio mode for external MCP clients (Claude Desktop, Cursor, etc.)
|
|
218
|
+
* This is the primary entry point for `lanonasis mcp start`
|
|
219
|
+
*/
|
|
220
|
+
startStdio(): Promise<void>;
|
|
212
221
|
/**
|
|
213
222
|
* Stop the server
|
|
214
223
|
*/
|
|
@@ -1473,6 +1473,35 @@ Please choose an option (1-4):`
|
|
|
1473
1473
|
throw error;
|
|
1474
1474
|
}
|
|
1475
1475
|
}
|
|
1476
|
+
/**
|
|
1477
|
+
* Start the server in stdio mode for external MCP clients (Claude Desktop, Cursor, etc.)
|
|
1478
|
+
* This is the primary entry point for `lanonasis mcp start`
|
|
1479
|
+
*/
|
|
1480
|
+
async startStdio() {
|
|
1481
|
+
await this.initialize();
|
|
1482
|
+
try {
|
|
1483
|
+
// Use API key from options if provided (from LANONASIS_API_KEY env var)
|
|
1484
|
+
if (this.options.apiKey) {
|
|
1485
|
+
// Set the API key for authentication
|
|
1486
|
+
await this.config.setVendorKey(this.options.apiKey);
|
|
1487
|
+
}
|
|
1488
|
+
// Create stdio transport
|
|
1489
|
+
this.transport = new StdioServerTransport();
|
|
1490
|
+
await this.server.connect(this.transport);
|
|
1491
|
+
// Log to stderr since stdout is for MCP protocol
|
|
1492
|
+
console.error(chalk.cyan('🚀 Lanonasis MCP Server started (stdio mode)'));
|
|
1493
|
+
console.error(chalk.gray(`Backend: ${this.config.getApiUrl()}`));
|
|
1494
|
+
console.error(chalk.gray(`Tools: 18+ available`));
|
|
1495
|
+
console.error(chalk.gray('Ready for MCP client connections...'));
|
|
1496
|
+
// Keep the process alive
|
|
1497
|
+
process.stdin.resume();
|
|
1498
|
+
}
|
|
1499
|
+
catch (error) {
|
|
1500
|
+
console.error(chalk.red('❌ Failed to start MCP Server:'));
|
|
1501
|
+
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
1502
|
+
throw error;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1476
1505
|
/**
|
|
1477
1506
|
* Stop the server
|
|
1478
1507
|
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Lanonasis MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Direct entry point for external MCP clients (Claude Desktop, Cursor, Windsurf, etc.)
|
|
6
|
+
* This allows simple configuration like:
|
|
7
|
+
*
|
|
8
|
+
* claude mcp add lanonasis -- lanonasis-mcp
|
|
9
|
+
*
|
|
10
|
+
* Or in claude_desktop_config.json:
|
|
11
|
+
* {
|
|
12
|
+
* "mcpServers": {
|
|
13
|
+
* "lanonasis": {
|
|
14
|
+
* "command": "lanonasis-mcp",
|
|
15
|
+
* "env": { "LANONASIS_API_KEY": "lano_xxx" }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Lanonasis MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Direct entry point for external MCP clients (Claude Desktop, Cursor, Windsurf, etc.)
|
|
6
|
+
* This allows simple configuration like:
|
|
7
|
+
*
|
|
8
|
+
* claude mcp add lanonasis -- lanonasis-mcp
|
|
9
|
+
*
|
|
10
|
+
* Or in claude_desktop_config.json:
|
|
11
|
+
* {
|
|
12
|
+
* "mcpServers": {
|
|
13
|
+
* "lanonasis": {
|
|
14
|
+
* "command": "lanonasis-mcp",
|
|
15
|
+
* "env": { "LANONASIS_API_KEY": "lano_xxx" }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
import { LanonasisMCPServer } from './mcp/server/lanonasis-server.js';
|
|
21
|
+
async function main() {
|
|
22
|
+
// Get API key from environment
|
|
23
|
+
const apiKey = process.env.LANONASIS_API_KEY;
|
|
24
|
+
if (!apiKey) {
|
|
25
|
+
console.error('Error: LANONASIS_API_KEY environment variable is required');
|
|
26
|
+
console.error('');
|
|
27
|
+
console.error('Usage:');
|
|
28
|
+
console.error(' LANONASIS_API_KEY=lano_xxx lanonasis-mcp');
|
|
29
|
+
console.error('');
|
|
30
|
+
console.error('Or configure in Claude Desktop/Cursor:');
|
|
31
|
+
console.error(' {');
|
|
32
|
+
console.error(' "mcpServers": {');
|
|
33
|
+
console.error(' "lanonasis": {');
|
|
34
|
+
console.error(' "command": "lanonasis-mcp",');
|
|
35
|
+
console.error(' "env": { "LANONASIS_API_KEY": "your_api_key" }');
|
|
36
|
+
console.error(' }');
|
|
37
|
+
console.error(' }');
|
|
38
|
+
console.error(' }');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const server = new LanonasisMCPServer({
|
|
43
|
+
apiKey,
|
|
44
|
+
verbose: process.env.LOG_LEVEL === 'debug'
|
|
45
|
+
});
|
|
46
|
+
// Start in stdio mode (standard for MCP clients)
|
|
47
|
+
await server.startStdio();
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`Failed to start MCP server: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
main();
|
package/dist/mcp-server.js
CHANGED
|
@@ -77,12 +77,13 @@ export class CLIMCPServer {
|
|
|
77
77
|
console.error(`Auth: ${this.config.hasVendorKey() ? 'Vendor Key' : 'JWT Token'}`);
|
|
78
78
|
}
|
|
79
79
|
const resolvedPort = typeof port === 'number' && !Number.isNaN(port) ? port : 3001;
|
|
80
|
+
const vendorKey = await this.config.getVendorKeyAsync();
|
|
80
81
|
// Set environment variables from CLI config
|
|
81
82
|
const env = {
|
|
82
83
|
...process.env,
|
|
83
84
|
PORT: resolvedPort.toString(),
|
|
84
85
|
MEMORY_API_URL: this.config.getApiUrl(),
|
|
85
|
-
LANONASIS_VENDOR_KEY:
|
|
86
|
+
LANONASIS_VENDOR_KEY: vendorKey,
|
|
86
87
|
LANONASIS_TOKEN: this.config.getToken(),
|
|
87
88
|
MCP_VERBOSE: verbose ? 'true' : 'false',
|
|
88
89
|
CLI_ALIGNED: 'true'
|
package/dist/utils/api.js
CHANGED
|
@@ -27,7 +27,7 @@ export class APIClient {
|
|
|
27
27
|
}
|
|
28
28
|
// Enhanced Authentication Support
|
|
29
29
|
const token = this.config.getToken();
|
|
30
|
-
const vendorKey = this.config.
|
|
30
|
+
const vendorKey = await this.config.getVendorKeyAsync();
|
|
31
31
|
if (vendorKey) {
|
|
32
32
|
// Vendor key authentication (validated server-side)
|
|
33
33
|
// Send raw key - server handles hashing for comparison
|
package/dist/utils/config.d.ts
CHANGED
package/dist/utils/config.js
CHANGED
|
@@ -14,6 +14,7 @@ export class CLIConfig {
|
|
|
14
14
|
authCheckCache = null;
|
|
15
15
|
AUTH_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
16
16
|
apiKeyStorage;
|
|
17
|
+
vendorKeyCache;
|
|
17
18
|
constructor() {
|
|
18
19
|
this.configDir = path.join(os.homedir(), '.maas');
|
|
19
20
|
this.configPath = path.join(this.configDir, 'config.json');
|
|
@@ -28,6 +29,7 @@ export class CLIConfig {
|
|
|
28
29
|
this.configDir = configDir;
|
|
29
30
|
this.configPath = path.join(configDir, 'config.json');
|
|
30
31
|
this.lockFile = path.join(configDir, 'config.lock');
|
|
32
|
+
this.vendorKeyCache = undefined;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Exposes the current config path for tests and diagnostics.
|
|
@@ -45,6 +47,8 @@ export class CLIConfig {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
async load() {
|
|
50
|
+
// Reset in-memory cache; disk state may have changed
|
|
51
|
+
this.vendorKeyCache = undefined;
|
|
48
52
|
try {
|
|
49
53
|
const data = await fs.readFile(this.configPath, 'utf-8');
|
|
50
54
|
this.config = JSON.parse(data);
|
|
@@ -170,7 +174,7 @@ export class CLIConfig {
|
|
|
170
174
|
getApiUrl() {
|
|
171
175
|
const baseUrl = process.env.MEMORY_API_URL ||
|
|
172
176
|
this.config.apiUrl ||
|
|
173
|
-
'https://
|
|
177
|
+
'https://api.lanonasis.com'; // Primary REST API endpoint
|
|
174
178
|
// Ensure we don't double-append /api/v1 - strip it if present since APIClient adds it
|
|
175
179
|
return baseUrl.replace(/\/api\/v1\/?$/, '');
|
|
176
180
|
}
|
|
@@ -192,8 +196,8 @@ export class CLIConfig {
|
|
|
192
196
|
if (!this.config.discoveredServices) {
|
|
193
197
|
this.config.discoveredServices = {
|
|
194
198
|
auth_base: 'https://auth.lanonasis.com',
|
|
195
|
-
memory_base: 'https://
|
|
196
|
-
mcp_base: 'https://mcp.lanonasis.com/api/v1', //
|
|
199
|
+
memory_base: 'https://api.lanonasis.com', // Primary REST API (Supabase Edge Functions)
|
|
200
|
+
mcp_base: 'https://mcp.lanonasis.com/api/v1', // MCP protocol REST path
|
|
197
201
|
mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
|
|
198
202
|
mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
|
|
199
203
|
project_scope: 'lanonasis-maas'
|
|
@@ -245,10 +249,10 @@ export class CLIConfig {
|
|
|
245
249
|
if (authBase.includes('localhost') || authBase.includes('127.0.0.1')) {
|
|
246
250
|
authBase = 'https://auth.lanonasis.com';
|
|
247
251
|
}
|
|
248
|
-
// Memory base should be the
|
|
252
|
+
// Memory base should be the REST API URL without /api/v1 suffix
|
|
249
253
|
// The API client will append the path as needed
|
|
250
|
-
const rawMemoryBase = discovered.endpoints?.http || 'https://
|
|
251
|
-
const memoryBase = rawMemoryBase.replace(/\/api\/v1\/?$/, '') || 'https://
|
|
254
|
+
const rawMemoryBase = discovered.endpoints?.http || 'https://api.lanonasis.com/api/v1';
|
|
255
|
+
const memoryBase = rawMemoryBase.replace(/\/api\/v1\/?$/, '') || 'https://api.lanonasis.com';
|
|
252
256
|
this.config.discoveredServices = {
|
|
253
257
|
auth_base: authBase || 'https://auth.lanonasis.com',
|
|
254
258
|
memory_base: memoryBase,
|
|
@@ -371,8 +375,8 @@ export class CLIConfig {
|
|
|
371
375
|
const nodeEnv = (process.env.NODE_ENV ?? '').toLowerCase();
|
|
372
376
|
const isDevEnvironment = nodeEnv === 'development' || nodeEnv === 'test';
|
|
373
377
|
const defaultAuthBase = isDevEnvironment ? 'http://localhost:4000' : 'https://auth.lanonasis.com';
|
|
374
|
-
const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000' : 'https://
|
|
375
|
-
const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1'; //
|
|
378
|
+
const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000' : 'https://api.lanonasis.com'; // Primary REST API (Supabase Edge Functions)
|
|
379
|
+
const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1'; // MCP protocol REST path
|
|
376
380
|
const defaultMcpWsBase = isDevEnvironment ? 'ws://localhost:4100/ws' : 'wss://mcp.lanonasis.com/ws';
|
|
377
381
|
const defaultMcpSseBase = isDevEnvironment ? 'http://localhost:4100/api/v1/events' : 'https://mcp.lanonasis.com/api/v1/events';
|
|
378
382
|
const endpoints = {
|
|
@@ -438,8 +442,8 @@ export class CLIConfig {
|
|
|
438
442
|
}
|
|
439
443
|
const currentServices = this.config.discoveredServices ?? {
|
|
440
444
|
auth_base: 'https://auth.lanonasis.com',
|
|
441
|
-
memory_base: 'https://
|
|
442
|
-
mcp_base: 'https://mcp.lanonasis.com/api/v1', //
|
|
445
|
+
memory_base: 'https://api.lanonasis.com', // Primary REST API (Supabase Edge Functions)
|
|
446
|
+
mcp_base: 'https://mcp.lanonasis.com/api/v1', // MCP protocol REST path
|
|
443
447
|
mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
|
|
444
448
|
mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
|
|
445
449
|
project_scope: 'lanonasis-maas'
|
|
@@ -488,6 +492,8 @@ export class CLIConfig {
|
|
|
488
492
|
environment: process.env.NODE_ENV || 'production',
|
|
489
493
|
createdAt: new Date().toISOString()
|
|
490
494
|
});
|
|
495
|
+
// Cache the vendor key for this process so synchronous callers can reuse it
|
|
496
|
+
this.vendorKeyCache = trimmedKey;
|
|
491
497
|
if (process.env.CLI_VERBOSE === 'true') {
|
|
492
498
|
console.log('🔐 Vendor key stored securely via @lanonasis/oauth-client');
|
|
493
499
|
}
|
|
@@ -566,10 +572,16 @@ export class CLIConfig {
|
|
|
566
572
|
}
|
|
567
573
|
}
|
|
568
574
|
getVendorKey() {
|
|
575
|
+
if (this.vendorKeyCache) {
|
|
576
|
+
return this.vendorKeyCache;
|
|
577
|
+
}
|
|
569
578
|
try {
|
|
570
579
|
// Retrieve from secure storage using ApiKeyStorage (synchronous wrapper)
|
|
571
580
|
const stored = this.getVendorKeySync();
|
|
572
|
-
|
|
581
|
+
if (stored) {
|
|
582
|
+
this.vendorKeyCache = stored;
|
|
583
|
+
}
|
|
584
|
+
return this.vendorKeyCache;
|
|
573
585
|
}
|
|
574
586
|
catch (error) {
|
|
575
587
|
if (process.env.CLI_VERBOSE === 'true') {
|
|
@@ -600,7 +612,8 @@ export class CLIConfig {
|
|
|
600
612
|
await this.apiKeyStorage.initialize();
|
|
601
613
|
const stored = await this.apiKeyStorage.retrieve();
|
|
602
614
|
if (stored) {
|
|
603
|
-
|
|
615
|
+
this.vendorKeyCache = stored.apiKey;
|
|
616
|
+
return this.vendorKeyCache;
|
|
604
617
|
}
|
|
605
618
|
}
|
|
606
619
|
catch (error) {
|
|
@@ -613,13 +626,14 @@ export class CLIConfig {
|
|
|
613
626
|
if (process.env.CLI_VERBOSE === 'true') {
|
|
614
627
|
console.log('ℹ️ Found legacy plaintext vendor key, will migrate on next auth');
|
|
615
628
|
}
|
|
616
|
-
|
|
629
|
+
this.vendorKeyCache = this.config.vendorKey;
|
|
630
|
+
return this.vendorKeyCache;
|
|
617
631
|
}
|
|
618
632
|
return undefined;
|
|
619
633
|
}
|
|
620
634
|
hasVendorKey() {
|
|
621
635
|
// Check for marker or legacy storage
|
|
622
|
-
return !!this.config.vendorKey;
|
|
636
|
+
return !!(this.vendorKeyCache || this.config.vendorKey);
|
|
623
637
|
}
|
|
624
638
|
async setApiUrl(url) {
|
|
625
639
|
this.config.apiUrl = url;
|
|
@@ -848,10 +862,25 @@ export class CLIConfig {
|
|
|
848
862
|
async logout() {
|
|
849
863
|
this.config.token = undefined;
|
|
850
864
|
this.config.user = undefined;
|
|
865
|
+
this.vendorKeyCache = undefined;
|
|
866
|
+
this.config.vendorKey = undefined;
|
|
867
|
+
this.config.authMethod = undefined;
|
|
868
|
+
try {
|
|
869
|
+
await this.apiKeyStorage.initialize();
|
|
870
|
+
// ApiKeyStorage may implement clear() to remove encrypted secrets
|
|
871
|
+
const storage = this.apiKeyStorage;
|
|
872
|
+
if (typeof storage.clear === 'function') {
|
|
873
|
+
await storage.clear();
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
catch {
|
|
877
|
+
// Ignore storage cleanup errors during logout
|
|
878
|
+
}
|
|
851
879
|
await this.save();
|
|
852
880
|
}
|
|
853
881
|
async clear() {
|
|
854
882
|
this.config = {};
|
|
883
|
+
this.vendorKeyCache = undefined;
|
|
855
884
|
await this.save();
|
|
856
885
|
}
|
|
857
886
|
async exists() {
|
|
@@ -866,7 +895,7 @@ export class CLIConfig {
|
|
|
866
895
|
// Enhanced credential validation methods
|
|
867
896
|
async validateStoredCredentials() {
|
|
868
897
|
try {
|
|
869
|
-
const vendorKey = this.
|
|
898
|
+
const vendorKey = await this.getVendorKeyAsync();
|
|
870
899
|
const token = this.getToken();
|
|
871
900
|
if (!vendorKey && !token) {
|
|
872
901
|
return false;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import crypto from 'crypto';
|
|
10
10
|
import { homedir, platform, hostname } from 'os';
|
|
11
|
-
import { hashApiKey, isSha256Hash } from '
|
|
11
|
+
import { hashApiKey, isSha256Hash } from '@lanonasis/security-sdk/hash-utils';
|
|
12
12
|
// Encryption algorithm configuration
|
|
13
13
|
const ALGORITHM = 'aes-256-gcm';
|
|
14
14
|
const KEY_LENGTH = 32; // 256 bits
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lanonasis/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"onasis": "dist/index.js",
|
|
9
|
-
"lanonasis": "dist/index.js"
|
|
9
|
+
"lanonasis": "dist/index.js",
|
|
10
|
+
"lanonasis-mcp": "dist/mcp-server-entry.js"
|
|
10
11
|
},
|
|
11
12
|
"exports": {
|
|
12
13
|
".": {
|
|
@@ -23,8 +24,8 @@
|
|
|
23
24
|
],
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@lanonasis/oauth-client": "1.2.5",
|
|
26
|
-
"@lanonasis/security-sdk": "
|
|
27
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
27
|
+
"@lanonasis/security-sdk": "1.0.5",
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
28
29
|
"axios": "^1.7.7",
|
|
29
30
|
"chalk": "^5.3.0",
|
|
30
31
|
"cli-progress": "^3.12.0",
|
|
@@ -61,4 +62,4 @@
|
|
|
61
62
|
"test:watch": "npm test -- --watch",
|
|
62
63
|
"test:coverage": "npm test -- --coverage"
|
|
63
64
|
}
|
|
64
|
-
}
|
|
65
|
+
}
|