@lanonasis/cli 1.0.1 → 1.2.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.
@@ -0,0 +1,318 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { table } from 'table';
4
+ import { getMCPClient } from '../utils/mcp-client.js';
5
+ import { CLIConfig } from '../utils/config.js';
6
+ export function mcpCommands(program) {
7
+ const mcp = program
8
+ .command('mcp')
9
+ .description('MCP (Model Context Protocol) server operations');
10
+ // Also register mcp-server command directly on program for convenience
11
+ const mcpServer = program
12
+ .command('mcp-server')
13
+ .description('MCP server initialization and management');
14
+ mcpServer.command('init')
15
+ .description('Initialize MCP server configuration')
16
+ .action(async () => {
17
+ console.log(chalk.cyan('🚀 Initializing MCP Server Configuration'));
18
+ console.log('');
19
+ const config = new CLIConfig();
20
+ const isAuthenticated = !!config.get('token');
21
+ if (isAuthenticated) {
22
+ console.log(chalk.green('✓ Authenticated - Using remote MCP mode'));
23
+ console.log(' Your memory operations will use api.lanonasis.com');
24
+ console.log(' with real-time SSE updates enabled');
25
+ }
26
+ else {
27
+ console.log(chalk.yellow('âš ī¸ Not authenticated - Using local MCP mode'));
28
+ console.log(' Run "lanonasis auth login" to enable remote mode');
29
+ }
30
+ console.log('');
31
+ console.log(chalk.cyan('Available MCP Commands:'));
32
+ console.log(' lanonasis mcp connect # Auto-connect to best mode');
33
+ console.log(' lanonasis mcp connect -r # Force remote mode');
34
+ console.log(' lanonasis mcp connect -l # Force local mode');
35
+ console.log(' lanonasis mcp status # Check connection status');
36
+ console.log(' lanonasis mcp tools # List available tools');
37
+ console.log('');
38
+ console.log(chalk.cyan('Memory operations are MCP-powered by default!'));
39
+ // Auto-connect to MCP
40
+ const spinner = ora('Auto-connecting to MCP...').start();
41
+ try {
42
+ const client = getMCPClient();
43
+ const connected = await client.connect({ useRemote: isAuthenticated });
44
+ if (connected) {
45
+ spinner.succeed(chalk.green(`Connected to ${isAuthenticated ? 'remote' : 'local'} MCP server`));
46
+ }
47
+ else {
48
+ spinner.fail('Failed to auto-connect to MCP');
49
+ }
50
+ }
51
+ catch (error) {
52
+ spinner.fail('MCP auto-connect failed');
53
+ }
54
+ });
55
+ // Connect command
56
+ mcp.command('connect')
57
+ .description('Connect to MCP server (local or remote)')
58
+ .option('-l, --local', 'Connect to local MCP server')
59
+ .option('-r, --remote', 'Connect to remote MCP server (api.lanonasis.com)')
60
+ .option('-s, --server <path>', 'Local MCP server path')
61
+ .option('-u, --url <url>', 'Remote MCP server URL')
62
+ .action(async (options) => {
63
+ const spinner = ora('Connecting to MCP server...').start();
64
+ const config = new CLIConfig();
65
+ try {
66
+ // Determine connection mode
67
+ let useRemote = options.remote;
68
+ if (!options.local && !options.remote) {
69
+ // Default to remote if authenticated, otherwise local
70
+ useRemote = !!config.get('token');
71
+ }
72
+ // Save preference
73
+ config.set('mcpUseRemote', useRemote);
74
+ if (options.server) {
75
+ config.set('mcpServerPath', options.server);
76
+ }
77
+ if (options.url) {
78
+ config.set('mcpServerUrl', options.url);
79
+ }
80
+ const client = getMCPClient();
81
+ const connected = await client.connect({
82
+ useRemote,
83
+ serverPath: options.server,
84
+ serverUrl: options.url
85
+ });
86
+ if (connected) {
87
+ spinner.succeed(chalk.green(`Connected to ${useRemote ? 'remote' : 'local'} MCP server`));
88
+ if (useRemote) {
89
+ console.log(chalk.cyan('â„šī¸ Using remote MCP via api.lanonasis.com'));
90
+ console.log(chalk.cyan('📡 SSE endpoint active for real-time updates'));
91
+ }
92
+ }
93
+ else {
94
+ spinner.fail('Failed to connect to MCP server');
95
+ }
96
+ }
97
+ catch (error) {
98
+ spinner.fail(`Connection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
99
+ process.exit(1);
100
+ }
101
+ });
102
+ // Disconnect command
103
+ mcp.command('disconnect')
104
+ .description('Disconnect from MCP server')
105
+ .action(async () => {
106
+ const client = getMCPClient();
107
+ await client.disconnect();
108
+ console.log(chalk.green('✓ Disconnected from MCP server'));
109
+ });
110
+ // Status command
111
+ mcp.command('status')
112
+ .description('Show MCP connection status')
113
+ .action(async () => {
114
+ const client = getMCPClient();
115
+ const status = client.getConnectionStatus();
116
+ console.log(chalk.cyan('\n📊 MCP Connection Status'));
117
+ console.log(chalk.cyan('========================'));
118
+ console.log(`Status: ${status.connected ? chalk.green('Connected') : chalk.red('Disconnected')}`);
119
+ console.log(`Mode: ${status.mode === 'remote' ? chalk.blue('Remote (API)') : chalk.yellow('Local')}`);
120
+ console.log(`Server: ${status.server}`);
121
+ if (status.connected && status.mode === 'remote') {
122
+ console.log(`\n${chalk.cyan('Features:')}`);
123
+ console.log('â€ĸ Real-time updates via SSE');
124
+ console.log('â€ĸ Authenticated API access');
125
+ console.log('â€ĸ MCP-compatible tool interface');
126
+ }
127
+ });
128
+ // List tools command
129
+ mcp.command('tools')
130
+ .description('List available MCP tools')
131
+ .action(async () => {
132
+ const spinner = ora('Fetching available tools...').start();
133
+ try {
134
+ const client = getMCPClient();
135
+ if (!client.isConnectedToServer()) {
136
+ spinner.info('Not connected. Attempting auto-connect...');
137
+ const config = new CLIConfig();
138
+ const useRemote = !!config.get('token');
139
+ await client.connect({ useRemote });
140
+ }
141
+ const tools = await client.listTools();
142
+ spinner.succeed('Tools fetched successfully');
143
+ console.log(chalk.cyan('\n🔧 Available MCP Tools'));
144
+ console.log(chalk.cyan('====================='));
145
+ const tableData = [
146
+ [chalk.bold('Tool Name'), chalk.bold('Description')]
147
+ ];
148
+ tools.forEach(tool => {
149
+ tableData.push([
150
+ chalk.green(tool.name),
151
+ tool.description
152
+ ]);
153
+ });
154
+ console.log(table(tableData, {
155
+ border: {
156
+ topBody: '─',
157
+ topJoin: 'â”Ŧ',
158
+ topLeft: '┌',
159
+ topRight: '┐',
160
+ bottomBody: '─',
161
+ bottomJoin: '┴',
162
+ bottomLeft: '└',
163
+ bottomRight: '┘',
164
+ bodyLeft: '│',
165
+ bodyRight: '│',
166
+ bodyJoin: '│',
167
+ joinBody: '─',
168
+ joinLeft: '├',
169
+ joinRight: '┤',
170
+ joinJoin: 'â”ŧ'
171
+ }
172
+ }));
173
+ }
174
+ catch (error) {
175
+ spinner.fail(`Failed to fetch tools: ${error instanceof Error ? error.message : 'Unknown error'}`);
176
+ process.exit(1);
177
+ }
178
+ });
179
+ // Call tool command
180
+ mcp.command('call')
181
+ .description('Call an MCP tool directly')
182
+ .argument('<tool>', 'Tool name to call')
183
+ .option('-a, --args <json>', 'Tool arguments as JSON')
184
+ .action(async (toolName, options) => {
185
+ const spinner = ora(`Calling tool: ${toolName}...`).start();
186
+ try {
187
+ const client = getMCPClient();
188
+ if (!client.isConnectedToServer()) {
189
+ spinner.info('Not connected. Attempting auto-connect...');
190
+ const config = new CLIConfig();
191
+ const useRemote = !!config.get('token');
192
+ await client.connect({ useRemote });
193
+ }
194
+ let args = {};
195
+ if (options.args) {
196
+ try {
197
+ args = JSON.parse(options.args);
198
+ }
199
+ catch (error) {
200
+ spinner.fail('Invalid JSON arguments');
201
+ process.exit(1);
202
+ }
203
+ }
204
+ const result = await client.callTool(toolName, args);
205
+ spinner.succeed(`Tool ${toolName} executed successfully`);
206
+ console.log(chalk.cyan('\n📤 Tool Result:'));
207
+ console.log(JSON.stringify(result, null, 2));
208
+ }
209
+ catch (error) {
210
+ spinner.fail(`Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
211
+ process.exit(1);
212
+ }
213
+ });
214
+ // Memory-specific MCP commands
215
+ const memory = mcp.command('memory')
216
+ .description('Memory operations via MCP');
217
+ memory.command('create')
218
+ .description('Create memory via MCP')
219
+ .requiredOption('-t, --title <title>', 'Memory title')
220
+ .requiredOption('-c, --content <content>', 'Memory content')
221
+ .option('-T, --type <type>', 'Memory type', 'context')
222
+ .option('--tags <tags>', 'Comma-separated tags')
223
+ .action(async (options) => {
224
+ const spinner = ora('Creating memory via MCP...').start();
225
+ try {
226
+ const client = getMCPClient();
227
+ if (!client.isConnectedToServer()) {
228
+ spinner.info('Not connected. Attempting auto-connect...');
229
+ const config = new CLIConfig();
230
+ const useRemote = !!config.get('token');
231
+ await client.connect({ useRemote });
232
+ }
233
+ const result = await client.callTool('memory_create_memory', {
234
+ title: options.title,
235
+ content: options.content,
236
+ memory_type: options.type,
237
+ tags: options.tags ? options.tags.split(',').map((t) => t.trim()) : []
238
+ });
239
+ spinner.succeed('Memory created successfully');
240
+ console.log(chalk.green('\n✓ Memory created'));
241
+ console.log(`ID: ${chalk.cyan(result.id)}`);
242
+ console.log(`Title: ${result.title}`);
243
+ console.log(`Type: ${result.memory_type}`);
244
+ }
245
+ catch (error) {
246
+ spinner.fail(`Failed to create memory: ${error instanceof Error ? error.message : 'Unknown error'}`);
247
+ process.exit(1);
248
+ }
249
+ });
250
+ memory.command('search')
251
+ .description('Search memories via MCP')
252
+ .argument('<query>', 'Search query')
253
+ .option('-l, --limit <number>', 'Maximum results', '10')
254
+ .option('-t, --threshold <number>', 'Similarity threshold (0-1)', '0.7')
255
+ .action(async (query, options) => {
256
+ const spinner = ora('Searching memories via MCP...').start();
257
+ try {
258
+ const client = getMCPClient();
259
+ if (!client.isConnectedToServer()) {
260
+ spinner.info('Not connected. Attempting auto-connect...');
261
+ const config = new CLIConfig();
262
+ const useRemote = !!config.get('token');
263
+ await client.connect({ useRemote });
264
+ }
265
+ const results = await client.callTool('memory_search_memories', {
266
+ query,
267
+ limit: parseInt(options.limit),
268
+ threshold: parseFloat(options.threshold)
269
+ });
270
+ spinner.succeed(`Found ${results.length} memories`);
271
+ if (results.length === 0) {
272
+ console.log(chalk.yellow('\nNo memories found matching your query'));
273
+ return;
274
+ }
275
+ console.log(chalk.cyan('\n🔍 Search Results:'));
276
+ results.forEach((memory, index) => {
277
+ console.log(`\n${chalk.bold(`${index + 1}. ${memory.title}`)}`);
278
+ console.log(` ID: ${chalk.gray(memory.id)}`);
279
+ console.log(` Type: ${chalk.blue(memory.memory_type)}`);
280
+ console.log(` Score: ${chalk.green((memory.relevance_score * 100).toFixed(1) + '%')}`);
281
+ console.log(` Content: ${memory.content.substring(0, 100)}...`);
282
+ });
283
+ }
284
+ catch (error) {
285
+ spinner.fail(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
286
+ process.exit(1);
287
+ }
288
+ });
289
+ // Configure MCP preferences
290
+ mcp.command('config')
291
+ .description('Configure MCP preferences')
292
+ .option('--prefer-remote', 'Prefer remote MCP server when available')
293
+ .option('--prefer-local', 'Prefer local MCP server')
294
+ .option('--auto', 'Auto-detect best connection mode')
295
+ .action(async (options) => {
296
+ const config = new CLIConfig();
297
+ if (options.preferRemote) {
298
+ config.set('mcpPreference', 'remote');
299
+ console.log(chalk.green('✓ Set MCP preference to remote'));
300
+ }
301
+ else if (options.preferLocal) {
302
+ config.set('mcpPreference', 'local');
303
+ console.log(chalk.green('✓ Set MCP preference to local'));
304
+ }
305
+ else if (options.auto) {
306
+ config.set('mcpPreference', 'auto');
307
+ console.log(chalk.green('✓ Set MCP preference to auto-detect'));
308
+ }
309
+ else {
310
+ const current = config.get('mcpPreference') || 'auto';
311
+ console.log(`Current MCP preference: ${chalk.cyan(current)}`);
312
+ console.log('\nOptions:');
313
+ console.log(' --prefer-remote : Use remote MCP server (api.lanonasis.com)');
314
+ console.log(' --prefer-local : Use local MCP server');
315
+ console.log(' --auto : Auto-detect based on authentication');
316
+ }
317
+ });
318
+ }
@@ -6,6 +6,7 @@ import wrap from 'word-wrap';
6
6
  import { format } from 'date-fns';
7
7
  import { apiClient } from '../utils/api.js';
8
8
  import { formatBytes, truncateText } from '../utils/formatting.js';
9
+ // Using GetMemoriesParams from api.ts
9
10
  export function memoryCommands(program) {
10
11
  // Create memory
11
12
  program
@@ -80,7 +81,8 @@ export function memoryCommands(program) {
80
81
  }
81
82
  }
82
83
  catch (error) {
83
- console.error(chalk.red('✖ Failed to create memory:'), error.message);
84
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
85
+ console.error(chalk.red('✖ Failed to create memory:'), errorMessage);
84
86
  process.exit(1);
85
87
  }
86
88
  });
@@ -100,25 +102,26 @@ export function memoryCommands(program) {
100
102
  try {
101
103
  const spinner = ora('Fetching memories...').start();
102
104
  const params = {
103
- page: parseInt(options.page),
104
- limit: parseInt(options.limit),
105
- sort: options.sort,
106
- order: options.order
105
+ offset: (parseInt(options.page || '1') - 1) * parseInt(options.limit || '20'),
106
+ limit: parseInt(options.limit || '20'),
107
+ sort_by: (options.sort || 'created_at'),
108
+ sort_order: (options.order || 'desc')
107
109
  };
108
110
  if (options.type)
109
111
  params.memory_type = options.type;
110
112
  if (options.tags)
111
- params.tags = options.tags;
112
- if (options.userId)
113
- params.user_id = options.userId;
113
+ params.tags = options.tags.split(',').map(t => t.trim());
114
+ // Note: user_id filtering removed as it's handled by authentication
114
115
  const result = await apiClient.getMemories(params);
115
116
  spinner.stop();
116
- if (result.memories.length === 0) {
117
+ if (result.data.length === 0) {
117
118
  console.log(chalk.yellow('No memories found'));
118
119
  return;
119
120
  }
120
121
  console.log(chalk.blue.bold(`\n📚 Memories (${result.pagination.total} total)`));
121
- console.log(chalk.gray(`Page ${result.pagination.page} of ${result.pagination.pages}`));
122
+ const currentPage = Math.floor(result.pagination.offset / result.pagination.limit) + 1;
123
+ const totalPages = Math.ceil(result.pagination.total / result.pagination.limit);
124
+ console.log(chalk.gray(`Page ${currentPage} of ${totalPages}`));
122
125
  console.log();
123
126
  const outputFormat = process.env.CLI_OUTPUT_FORMAT || 'table';
124
127
  if (outputFormat === 'json') {
@@ -126,7 +129,7 @@ export function memoryCommands(program) {
126
129
  }
127
130
  else {
128
131
  // Table format
129
- const tableData = result.memories.map((memory) => [
132
+ const tableData = result.data.map((memory) => [
130
133
  truncateText(memory.title, 30),
131
134
  memory.memory_type,
132
135
  memory.tags.slice(0, 3).join(', '),
@@ -134,7 +137,6 @@ export function memoryCommands(program) {
134
137
  memory.access_count
135
138
  ]);
136
139
  const tableConfig = {
137
- header: ['Title', 'Type', 'Tags', 'Created', 'Access'],
138
140
  columnDefault: {
139
141
  width: 20,
140
142
  wrapWord: true
@@ -147,15 +149,18 @@ export function memoryCommands(program) {
147
149
  { width: 8 }
148
150
  ]
149
151
  };
150
- console.log(table([tableConfig.header, ...tableData], tableConfig));
152
+ const tableHeaders = ['Title', 'Type', 'Tags', 'Created', 'Access'];
153
+ console.log(table([tableHeaders, ...tableData], tableConfig));
151
154
  // Pagination info
152
- if (result.pagination.pages > 1) {
153
- console.log(chalk.gray(`\nUse --page ${result.pagination.page + 1} for next page`));
155
+ if (result.pagination.has_more) {
156
+ const nextPage = currentPage + 1;
157
+ console.log(chalk.gray(`\nUse --page ${nextPage} for next page`));
154
158
  }
155
159
  }
156
160
  }
157
161
  catch (error) {
158
- console.error(chalk.red('✖ Failed to list memories:'), error.message);
162
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
163
+ console.error(chalk.red('✖ Failed to list memories:'), errorMessage);
159
164
  process.exit(1);
160
165
  }
161
166
  });
@@ -172,8 +177,8 @@ export function memoryCommands(program) {
172
177
  try {
173
178
  const spinner = ora(`Searching for "${query}"...`).start();
174
179
  const searchOptions = {
175
- limit: parseInt(options.limit),
176
- threshold: parseFloat(options.threshold)
180
+ limit: parseInt(options.limit || '20'),
181
+ threshold: parseFloat(options.threshold || '0.7')
177
182
  };
178
183
  if (options.type) {
179
184
  searchOptions.memory_types = options.type.split(',').map((t) => t.trim());
@@ -183,14 +188,14 @@ export function memoryCommands(program) {
183
188
  }
184
189
  const result = await apiClient.searchMemories(query, searchOptions);
185
190
  spinner.stop();
186
- if (result.results.length === 0) {
191
+ if (result.data.length === 0) {
187
192
  console.log(chalk.yellow('No memories found matching your search'));
188
193
  return;
189
194
  }
190
- console.log(chalk.blue.bold(`\n🔍 Search Results (${result.total_results} found)`));
191
- console.log(chalk.gray(`Query: "${query}" | Search time: ${result.search_time_ms}ms`));
195
+ console.log(chalk.blue.bold(`\n🔍 Search Results (${result.pagination.total} found)`));
196
+ console.log(chalk.gray(`Query: "${query}"`));
192
197
  console.log();
193
- result.results.forEach((memory, index) => {
198
+ result.data.forEach((memory, index) => {
194
199
  const score = (memory.relevance_score * 100).toFixed(1);
195
200
  console.log(chalk.green(`${index + 1}. ${memory.title}`) + chalk.gray(` (${score}% match)`));
196
201
  console.log(chalk.white(` ${truncateText(memory.content, 100)}`));
@@ -202,7 +207,8 @@ export function memoryCommands(program) {
202
207
  });
203
208
  }
204
209
  catch (error) {
205
- console.error(chalk.red('✖ Search failed:'), error.message);
210
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
211
+ console.error(chalk.red('✖ Search failed:'), errorMessage);
206
212
  process.exit(1);
207
213
  }
208
214
  });
@@ -244,7 +250,8 @@ export function memoryCommands(program) {
244
250
  }
245
251
  }
246
252
  catch (error) {
247
- console.error(chalk.red('✖ Failed to get memory:'), error.message);
253
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
254
+ console.error(chalk.red('✖ Failed to get memory:'), errorMessage);
248
255
  process.exit(1);
249
256
  }
250
257
  });
@@ -324,7 +331,8 @@ export function memoryCommands(program) {
324
331
  console.log(` Title: ${memory.title}`);
325
332
  }
326
333
  catch (error) {
327
- console.error(chalk.red('✖ Failed to update memory:'), error.message);
334
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
335
+ console.error(chalk.red('✖ Failed to update memory:'), errorMessage);
328
336
  process.exit(1);
329
337
  }
330
338
  });
@@ -357,7 +365,8 @@ export function memoryCommands(program) {
357
365
  spinner.succeed('Memory deleted successfully');
358
366
  }
359
367
  catch (error) {
360
- console.error(chalk.red('✖ Failed to delete memory:'), error.message);
368
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
369
+ console.error(chalk.red('✖ Failed to delete memory:'), errorMessage);
361
370
  process.exit(1);
362
371
  }
363
372
  });
@@ -394,7 +403,8 @@ export function memoryCommands(program) {
394
403
  }
395
404
  }
396
405
  catch (error) {
397
- console.error(chalk.red('✖ Failed to get statistics:'), error.message);
406
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
407
+ console.error(chalk.red('✖ Failed to get statistics:'), errorMessage);
398
408
  process.exit(1);
399
409
  }
400
410
  });
@@ -82,7 +82,8 @@ export function topicCommands(program) {
82
82
  }
83
83
  }
84
84
  catch (error) {
85
- console.error(chalk.red('✖ Failed to create topic:'), error.message);
85
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
86
+ console.error(chalk.red('✖ Failed to create topic:'), errorMessage);
86
87
  process.exit(1);
87
88
  }
88
89
  });
@@ -116,7 +117,6 @@ export function topicCommands(program) {
116
117
  topic.parent_topic_id ? '✓' : ''
117
118
  ]);
118
119
  const tableConfig = {
119
- header: ['Name', 'Description', 'Color', 'Created', 'Child'],
120
120
  columnDefault: {
121
121
  width: 20,
122
122
  wrapWord: true
@@ -129,11 +129,13 @@ export function topicCommands(program) {
129
129
  { width: 8 }
130
130
  ]
131
131
  };
132
- console.log(table([tableConfig.header, ...tableData], tableConfig));
132
+ const tableHeaders = ['Name', 'Description', 'System', 'Created'];
133
+ console.log(table([tableHeaders, ...tableData], tableConfig));
133
134
  }
134
135
  }
135
136
  catch (error) {
136
- console.error(chalk.red('✖ Failed to list topics:'), error.message);
137
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
138
+ console.error(chalk.red('✖ Failed to list topics:'), errorMessage);
137
139
  process.exit(1);
138
140
  }
139
141
  });
@@ -174,7 +176,8 @@ export function topicCommands(program) {
174
176
  }
175
177
  }
176
178
  catch (error) {
177
- console.error(chalk.red('✖ Failed to get topic:'), error.message);
179
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
180
+ console.error(chalk.red('✖ Failed to get topic:'), errorMessage);
178
181
  process.exit(1);
179
182
  }
180
183
  });
@@ -257,7 +260,8 @@ export function topicCommands(program) {
257
260
  console.log(` Name: ${topic.name}`);
258
261
  }
259
262
  catch (error) {
260
- console.error(chalk.red('✖ Failed to update topic:'), error.message);
263
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
264
+ console.error(chalk.red('✖ Failed to update topic:'), errorMessage);
261
265
  process.exit(1);
262
266
  }
263
267
  });
@@ -290,7 +294,8 @@ export function topicCommands(program) {
290
294
  spinner.succeed('Topic deleted successfully');
291
295
  }
292
296
  catch (error) {
293
- console.error(chalk.red('✖ Failed to delete topic:'), error.message);
297
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
298
+ console.error(chalk.red('✖ Failed to delete topic:'), errorMessage);
294
299
  process.exit(1);
295
300
  }
296
301
  });
@@ -11,7 +11,7 @@ const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
11
11
  const program = new Command();
12
12
  program
13
13
  .name('lanonasis')
14
- .description('Lanonasis Enterprise CLI - Memory as a Service and Infrastructure Management')
14
+ .description('Lanonasis Enterprise CLI - Memory as a Service with MCP Integration')
15
15
  .version(packageJson.version);
16
16
  program
17
17
  .command('init')
package/dist/index.js CHANGED
@@ -8,7 +8,9 @@ import { memoryCommands } from './commands/memory.js';
8
8
  import { topicCommands } from './commands/topics.js';
9
9
  import { configCommands } from './commands/config.js';
10
10
  import { orgCommands } from './commands/organization.js';
11
+ import { mcpCommands } from './commands/mcp.js';
11
12
  import { CLIConfig } from './utils/config.js';
13
+ import { getMCPClient } from './utils/mcp-client.js';
12
14
  // Load environment variables
13
15
  config();
14
16
  const program = new Command();
@@ -17,12 +19,13 @@ const cliConfig = new CLIConfig();
17
19
  program
18
20
  .name('memory')
19
21
  .alias('maas')
20
- .description('Enterprise Memory as a Service (MaaS) CLI')
22
+ .description('Enterprise Memory as a Service (MaaS) CLI with MCP Integration')
21
23
  .version('1.0.0')
22
24
  .option('-v, --verbose', 'enable verbose logging')
23
25
  .option('--api-url <url>', 'override API URL')
24
26
  .option('--output <format>', 'output format (json, table, yaml)', 'table')
25
- .hook('preAction', (thisCommand, actionCommand) => {
27
+ .option('--no-mcp', 'disable MCP and use direct API')
28
+ .hook('preAction', async (thisCommand, actionCommand) => {
26
29
  const opts = thisCommand.opts();
27
30
  if (opts.verbose) {
28
31
  process.env.CLI_VERBOSE = 'true';
@@ -31,6 +34,24 @@ program
31
34
  process.env.MEMORY_API_URL = opts.apiUrl;
32
35
  }
33
36
  process.env.CLI_OUTPUT_FORMAT = opts.output;
37
+ // Auto-initialize MCP unless disabled
38
+ if (opts.mcp !== false && !['init', 'auth', 'login', 'mcp'].includes(actionCommand.name())) {
39
+ try {
40
+ const client = getMCPClient();
41
+ if (!client.isConnectedToServer()) {
42
+ const useRemote = await cliConfig.isAuthenticated();
43
+ await client.connect({ useRemote });
44
+ if (process.env.CLI_VERBOSE === 'true') {
45
+ console.log(chalk.gray(`MCP connected (${useRemote ? 'remote' : 'local'})`));
46
+ }
47
+ }
48
+ }
49
+ catch {
50
+ if (process.env.CLI_VERBOSE === 'true') {
51
+ console.log(chalk.yellow('MCP auto-connect failed, using direct API'));
52
+ }
53
+ }
54
+ }
34
55
  });
35
56
  // Global error handler
36
57
  process.on('uncaughtException', (error) => {
@@ -110,13 +131,16 @@ authCmd
110
131
  console.log(chalk.yellow('Run:'), chalk.white('memory login'));
111
132
  }
112
133
  });
113
- // Memory commands (require auth)
134
+ // MCP Commands (primary interface)
135
+ mcpCommands(program);
136
+ // Memory commands (require auth) - now MCP-powered by default
114
137
  const memoryCmd = program
115
138
  .command('memory')
116
139
  .alias('mem')
117
140
  .description('Memory management commands');
118
141
  requireAuth(memoryCmd);
119
142
  memoryCommands(memoryCmd);
143
+ // Note: Memory commands are now MCP-powered when available
120
144
  // Topic commands (require auth)
121
145
  const topicCmd = program
122
146
  .command('topic')
@@ -174,8 +198,7 @@ program
174
198
  // Help customization
175
199
  program.configureHelp({
176
200
  formatHelp: (cmd, helper) => {
177
- const term = helper.termWidth || 80;
178
- const helpWidth = Math.min(term - 2, 80);
201
+ // Get terminal width for formatting (currently using default helper formatting)
179
202
  let help = chalk.blue.bold('🧠 Memory as a Service CLI\n\n');
180
203
  help += helper.commandUsage(cmd) + '\n\n';
181
204
  if (cmd.description()) {