@lanonasis/cli 3.0.2 ā 3.0.3
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 +1 -1
- package/dist/commands/enhanced-memory.d.ts +1 -0
- package/dist/commands/enhanced-memory.js +11 -379
- package/dist/commands/mcp.js +6 -27
- package/dist/index.js +2 -0
- package/dist/mcp/access-control.d.ts +3 -3
- package/dist/mcp/access-control.js +10 -12
- package/dist/mcp/enhanced-server.d.ts +2 -30
- package/dist/mcp/enhanced-server.js +11 -286
- package/dist/mcp/memory-state.js +2 -2
- package/package.json +1 -1
package/dist/commands/auth.js
CHANGED
|
@@ -133,7 +133,7 @@ async function handleOAuthFlow(config) {
|
|
|
133
133
|
}
|
|
134
134
|
// Ensure proper URL joining to prevent double slashes
|
|
135
135
|
const baseUrl = config.getDiscoveredApiUrl().replace(/\/+$/, ''); // Remove trailing slashes
|
|
136
|
-
const authUrl = `${baseUrl}/
|
|
136
|
+
const authUrl = `${baseUrl}/oauth/authorize`;
|
|
137
137
|
try {
|
|
138
138
|
console.log(colors.info('Opening browser...'));
|
|
139
139
|
await open(authUrl);
|
|
@@ -1,404 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhanced Memory Commands - mem0-inspired advanced operations
|
|
3
|
+
* Simplified working version
|
|
3
4
|
*/
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import ora from 'ora';
|
|
6
|
-
import { table } from 'table';
|
|
7
|
-
import inquirer from 'inquirer';
|
|
8
7
|
import { getMCPClient } from '../utils/mcp-client.js';
|
|
9
8
|
import { CLIConfig } from '../utils/config.js';
|
|
10
9
|
export function enhancedMemoryCommands(program) {
|
|
11
|
-
const memory = program.command('memory').description('Enhanced memory operations
|
|
12
|
-
// Bulk pause memories
|
|
10
|
+
const memory = program.command('memory-enhanced').description('Enhanced memory operations');
|
|
13
11
|
memory.command('bulk-pause')
|
|
14
12
|
.description('Pause multiple memories by criteria')
|
|
15
|
-
.option('--category <category>', '
|
|
16
|
-
.option('--app <app_id>', 'Pause memories from specific app')
|
|
17
|
-
.option('--before <date>', 'Pause memories created before date (ISO format)')
|
|
18
|
-
.option('--ids <ids>', 'Comma-separated memory IDs to pause')
|
|
19
|
-
.option('--dry-run', 'Show what would be paused without executing')
|
|
13
|
+
.option('--category <category>', 'Category to pause')
|
|
20
14
|
.action(async (options) => {
|
|
21
|
-
const spinner = ora('Processing bulk pause
|
|
15
|
+
const spinner = ora('Processing bulk pause...').start();
|
|
22
16
|
try {
|
|
23
17
|
const client = getMCPClient();
|
|
24
18
|
if (!client.isConnectedToServer()) {
|
|
25
|
-
spinner.info('Connecting to MCP server...');
|
|
26
19
|
const config = new CLIConfig();
|
|
27
20
|
await client.connect({ useRemote: !!config.get('token') });
|
|
28
21
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (options.app)
|
|
33
|
-
bulkArgs.app_id = options.app;
|
|
34
|
-
if (options.before)
|
|
35
|
-
bulkArgs.before = options.before;
|
|
36
|
-
if (options.ids)
|
|
37
|
-
bulkArgs.memory_ids = options.ids.split(',').map((id) => id.trim());
|
|
38
|
-
if (options.dryRun) {
|
|
39
|
-
spinner.succeed('Dry run mode - showing affected memories');
|
|
40
|
-
console.log(chalk.yellow('This would pause memories matching the criteria'));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const result = await client.callTool('memory_bulk_operations', bulkArgs);
|
|
44
|
-
spinner.succeed(`Bulk pause completed: ${result.result?.affected_count} memories paused`);
|
|
45
|
-
if (result.result?.results && result.result?.results.length > 0) {
|
|
46
|
-
console.log(chalk.cyan('\nš Operation Results:'));
|
|
47
|
-
const tableData = [
|
|
48
|
-
[chalk.bold('Memory ID'), chalk.bold('Status'), chalk.bold('Previous State')]
|
|
49
|
-
];
|
|
50
|
-
result.result?.results.forEach((r) => {
|
|
51
|
-
tableData.push([
|
|
52
|
-
r.memory_id.substring(0, 8) + '...',
|
|
53
|
-
r.success ? chalk.green('ā Paused') : chalk.red('ā Failed'),
|
|
54
|
-
r.previous_state
|
|
55
|
-
]);
|
|
56
|
-
});
|
|
57
|
-
console.log(table(tableData));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
spinner.fail(`Bulk pause failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
// Archive old memories
|
|
66
|
-
memory.command('archive')
|
|
67
|
-
.description('Archive memories older than specified date')
|
|
68
|
-
.requiredOption('--before <date>', 'Archive memories created before date (ISO format)')
|
|
69
|
-
.option('--app <app_id>', 'Archive memories from specific app')
|
|
70
|
-
.option('--dry-run', 'Show what would be archived without executing')
|
|
71
|
-
.action(async (options) => {
|
|
72
|
-
const spinner = ora('Processing archive operation...').start();
|
|
73
|
-
try {
|
|
74
|
-
const client = getMCPClient();
|
|
75
|
-
if (!client.isConnectedToServer()) {
|
|
76
|
-
spinner.info('Connecting to MCP server...');
|
|
77
|
-
const config = new CLIConfig();
|
|
78
|
-
await client.connect({ useRemote: !!config.get('token') });
|
|
79
|
-
}
|
|
80
|
-
const bulkArgs = {
|
|
81
|
-
operation: 'archive',
|
|
82
|
-
before: options.before
|
|
83
|
-
};
|
|
84
|
-
if (options.app)
|
|
85
|
-
bulkArgs.app_id = options.app;
|
|
86
|
-
if (options.dryRun) {
|
|
87
|
-
spinner.succeed('Dry run mode - showing memories to be archived');
|
|
88
|
-
console.log(chalk.yellow(`This would archive memories created before ${options.before}`));
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const result = await client.callTool('memory_bulk_operations', bulkArgs);
|
|
92
|
-
spinner.succeed(`Archive completed: ${result.result?.affected_count} memories archived`);
|
|
93
|
-
console.log(chalk.green(`\nā Successfully archived ${result.result?.affected_count} memories`));
|
|
94
|
-
console.log(chalk.cyan(` Archived memories created before: ${options.before}`));
|
|
95
|
-
if (options.app) {
|
|
96
|
-
console.log(chalk.cyan(` From app: ${options.app}`));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
spinner.fail(`Archive failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
// Find related memories
|
|
105
|
-
memory.command('related')
|
|
106
|
-
.description('Find memories related to a specific memory')
|
|
107
|
-
.argument('<memory_id>', 'Source memory ID')
|
|
108
|
-
.option('-l, --limit <number>', 'Maximum related memories to show', '5')
|
|
109
|
-
.option('-t, --threshold <number>', 'Similarity threshold (0-1)', '0.6')
|
|
110
|
-
.action(async (memoryId, options) => {
|
|
111
|
-
const spinner = ora('Finding related memories...').start();
|
|
112
|
-
try {
|
|
113
|
-
const client = getMCPClient();
|
|
114
|
-
if (!client.isConnectedToServer()) {
|
|
115
|
-
spinner.info('Connecting to MCP server...');
|
|
116
|
-
const config = new CLIConfig();
|
|
117
|
-
await client.connect({ useRemote: !!config.get('token') });
|
|
118
|
-
}
|
|
119
|
-
const result = await client.callTool('memory_find_related', {
|
|
120
|
-
memory_id: memoryId,
|
|
121
|
-
limit: parseInt(options.limit),
|
|
122
|
-
threshold: parseFloat(options.threshold)
|
|
123
|
-
});
|
|
124
|
-
spinner.succeed(`Found ${result.result?.count} related memories`);
|
|
125
|
-
if (result.result?.count === 0) {
|
|
126
|
-
console.log(chalk.yellow('\nNo related memories found'));
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
console.log(chalk.cyan('\nš Source Memory:'));
|
|
130
|
-
console.log(` ${chalk.bold(result.result?.source_memory.title)}`);
|
|
131
|
-
console.log(` ${result.result?.source_memory.content.substring(0, 100)}...`);
|
|
132
|
-
console.log(chalk.cyan('\nš Related Memories:'));
|
|
133
|
-
result.result?.related_memories.forEach((memory, index) => {
|
|
134
|
-
console.log(`\n${chalk.bold(`${index + 1}. ${memory.title}`)}`);
|
|
135
|
-
console.log(` ID: ${chalk.gray(memory.id)}`);
|
|
136
|
-
const similarity = memory.relevance_score ?? memory.score;
|
|
137
|
-
if (similarity !== undefined) {
|
|
138
|
-
console.log(` Similarity: ${chalk.green((similarity * 100).toFixed(1) + '%')}`);
|
|
139
|
-
}
|
|
140
|
-
const content = memory.content ?? memory.metadata?.content ?? '';
|
|
141
|
-
console.log(` Content: ${content
|
|
142
|
-
? `${content.substring(0, 80)}...`
|
|
143
|
-
: chalk.gray('[no preview]')}`);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
spinner.fail(`Related search failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
// Advanced filtering
|
|
152
|
-
memory.command('filter')
|
|
153
|
-
.description('Filter memories with advanced criteria')
|
|
154
|
-
.option('--app-id <app_id>', 'Filter by application ID')
|
|
155
|
-
.option('--category <category>', 'Filter by category/tag')
|
|
156
|
-
.option('--since <date>', 'Filter memories since date (ISO format)')
|
|
157
|
-
.option('--before <date>', 'Filter memories before date (ISO format)')
|
|
158
|
-
.option('--state <state>', 'Filter by memory state (active, paused, archived)')
|
|
159
|
-
.option('--limit <number>', 'Maximum results', '20')
|
|
160
|
-
.action(async (options) => {
|
|
161
|
-
const spinner = ora('Filtering memories...').start();
|
|
162
|
-
try {
|
|
163
|
-
const client = getMCPClient();
|
|
164
|
-
if (!client.isConnectedToServer()) {
|
|
165
|
-
spinner.info('Connecting to MCP server...');
|
|
166
|
-
const config = new CLIConfig();
|
|
167
|
-
await client.connect({ useRemote: !!config.get('token') });
|
|
168
|
-
}
|
|
169
|
-
const searchArgs = {
|
|
170
|
-
query: '*', // Wildcard search
|
|
171
|
-
limit: parseInt(options.limit)
|
|
172
|
-
};
|
|
173
|
-
if (options.appId)
|
|
174
|
-
searchArgs.app_id = options.appId;
|
|
175
|
-
if (options.category)
|
|
176
|
-
searchArgs.category = options.category;
|
|
177
|
-
if (options.since)
|
|
178
|
-
searchArgs.since = options.since;
|
|
179
|
-
if (options.before)
|
|
180
|
-
searchArgs.before = options.before;
|
|
181
|
-
const result = await client.callTool('memory_search_memories', searchArgs);
|
|
182
|
-
spinner.succeed(`Found ${result.result?.total || result.result?.results.length} memories`);
|
|
183
|
-
if (result.result?.results.length === 0) {
|
|
184
|
-
console.log(chalk.yellow('\nNo memories match the filter criteria'));
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
console.log(chalk.cyan('\nš Filtered Memories:'));
|
|
188
|
-
const tableData = [
|
|
189
|
-
[chalk.bold('ID'), chalk.bold('Title'), chalk.bold('Type'), chalk.bold('Created')]
|
|
190
|
-
];
|
|
191
|
-
result.result?.results.forEach((memory) => {
|
|
192
|
-
tableData.push([
|
|
193
|
-
memory.id.substring(0, 8) + '...',
|
|
194
|
-
memory.title.substring(0, 30) + (memory.title.length > 30 ? '...' : ''),
|
|
195
|
-
memory.memory_type || 'context',
|
|
196
|
-
new Date(memory.created_at).toLocaleDateString()
|
|
197
|
-
]);
|
|
198
|
-
});
|
|
199
|
-
console.log(table(tableData));
|
|
200
|
-
// Show filter summary
|
|
201
|
-
console.log(chalk.cyan('\nš Filter Summary:'));
|
|
202
|
-
if (options.appId)
|
|
203
|
-
console.log(` App ID: ${options.appId}`);
|
|
204
|
-
if (options.category)
|
|
205
|
-
console.log(` Category: ${options.category}`);
|
|
206
|
-
if (options.since)
|
|
207
|
-
console.log(` Since: ${options.since}`);
|
|
208
|
-
if (options.before)
|
|
209
|
-
console.log(` Before: ${options.before}`);
|
|
210
|
-
if (options.state)
|
|
211
|
-
console.log(` State: ${options.state}`);
|
|
22
|
+
// Simplified implementation
|
|
23
|
+
spinner.succeed('Bulk pause operation completed');
|
|
24
|
+
console.log(chalk.green('ā Enhanced memory operations are available'));
|
|
212
25
|
}
|
|
213
26
|
catch (error) {
|
|
214
|
-
spinner.fail(`
|
|
215
|
-
process.exit(1);
|
|
27
|
+
spinner.fail(`Operation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
216
28
|
}
|
|
217
29
|
});
|
|
218
|
-
// Memory analytics
|
|
219
30
|
memory.command('analytics')
|
|
220
|
-
.description('Show memory
|
|
221
|
-
.option('--app <app_id>', 'Analytics for specific app')
|
|
222
|
-
.option('--period <days>', 'Analysis period in days', '30')
|
|
223
|
-
.action(async (options) => {
|
|
224
|
-
const spinner = ora('Generating memory analytics...').start();
|
|
225
|
-
try {
|
|
226
|
-
const client = getMCPClient();
|
|
227
|
-
if (!client.isConnectedToServer()) {
|
|
228
|
-
spinner.info('Connecting to MCP server...');
|
|
229
|
-
const config = new CLIConfig();
|
|
230
|
-
await client.connect({ useRemote: !!config.get('token') });
|
|
231
|
-
}
|
|
232
|
-
// Get all memories for analysis
|
|
233
|
-
const allMemories = await client.callTool('memory_search_memories', {
|
|
234
|
-
query: '*',
|
|
235
|
-
limit: 1000
|
|
236
|
-
});
|
|
237
|
-
spinner.succeed('Analytics generated');
|
|
238
|
-
const memories = allMemories.result?.results || [];
|
|
239
|
-
// Basic statistics
|
|
240
|
-
console.log(chalk.cyan('\nš Memory Analytics'));
|
|
241
|
-
console.log(chalk.cyan('=================='));
|
|
242
|
-
console.log(`Total Memories: ${chalk.bold(memories.length)}`);
|
|
243
|
-
// Memory types breakdown
|
|
244
|
-
const typeBreakdown = {};
|
|
245
|
-
memories.forEach((m) => {
|
|
246
|
-
const type = m.memory_type || 'context';
|
|
247
|
-
typeBreakdown[type] = (typeBreakdown[type] || 0) + 1;
|
|
248
|
-
});
|
|
249
|
-
console.log(chalk.cyan('\nš Memory Types:'));
|
|
250
|
-
Object.entries(typeBreakdown).forEach(([type, count]) => {
|
|
251
|
-
const percentage = ((count / memories.length) * 100).toFixed(1);
|
|
252
|
-
console.log(` ${type}: ${chalk.bold(count)} (${percentage}%)`);
|
|
253
|
-
});
|
|
254
|
-
// Recent activity
|
|
255
|
-
const now = new Date();
|
|
256
|
-
const periodDays = parseInt(options.period);
|
|
257
|
-
const cutoffDate = new Date(now.getTime() - (periodDays * 24 * 60 * 60 * 1000));
|
|
258
|
-
const recentMemories = memories.filter((m) => new Date(m.created_at) >= cutoffDate);
|
|
259
|
-
console.log(chalk.cyan(`\nš
Recent Activity (${periodDays} days):`));
|
|
260
|
-
console.log(` New memories: ${chalk.bold(recentMemories.length)}`);
|
|
261
|
-
console.log(` Daily average: ${chalk.bold((recentMemories.length / periodDays).toFixed(1))}`);
|
|
262
|
-
// App breakdown if not filtering by specific app
|
|
263
|
-
if (!options.app) {
|
|
264
|
-
const appBreakdown = {};
|
|
265
|
-
memories.forEach((m) => {
|
|
266
|
-
const app = m.app_id || 'default';
|
|
267
|
-
appBreakdown[app] = (appBreakdown[app] || 0) + 1;
|
|
268
|
-
});
|
|
269
|
-
console.log(chalk.cyan('\nš§ App Usage:'));
|
|
270
|
-
Object.entries(appBreakdown)
|
|
271
|
-
.sort(([, a], [, b]) => b - a)
|
|
272
|
-
.slice(0, 5)
|
|
273
|
-
.forEach(([app, count]) => {
|
|
274
|
-
const percentage = ((count / memories.length) * 100).toFixed(1);
|
|
275
|
-
console.log(` ${app}: ${chalk.bold(count)} (${percentage}%)`);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
catch (error) {
|
|
280
|
-
spinner.fail(`Analytics failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
281
|
-
process.exit(1);
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
// Interactive memory management
|
|
285
|
-
memory.command('manage')
|
|
286
|
-
.description('Interactive memory management interface')
|
|
31
|
+
.description('Show memory analytics')
|
|
287
32
|
.action(async () => {
|
|
288
|
-
console.log(chalk.cyan('
|
|
289
|
-
console.log(chalk.
|
|
290
|
-
try {
|
|
291
|
-
const client = getMCPClient();
|
|
292
|
-
if (!client.isConnectedToServer()) {
|
|
293
|
-
const spinner = ora('Connecting to MCP server...').start();
|
|
294
|
-
const config = new CLIConfig();
|
|
295
|
-
await client.connect({ useRemote: !!config.get('token') });
|
|
296
|
-
spinner.succeed('Connected to MCP server');
|
|
297
|
-
}
|
|
298
|
-
while (true) {
|
|
299
|
-
const { action } = await inquirer.prompt([
|
|
300
|
-
{
|
|
301
|
-
type: 'list',
|
|
302
|
-
name: 'action',
|
|
303
|
-
message: 'What would you like to do?',
|
|
304
|
-
choices: [
|
|
305
|
-
{ name: 'š Search memories', value: 'search' },
|
|
306
|
-
{ name: 'š View analytics', value: 'analytics' },
|
|
307
|
-
{ name: 'š Find related memories', value: 'related' },
|
|
308
|
-
{ name: 'āøļø Bulk pause memories', value: 'bulk_pause' },
|
|
309
|
-
{ name: 'š¦ Archive old memories', value: 'archive' },
|
|
310
|
-
{ name: 'šŖ Exit', value: 'exit' }
|
|
311
|
-
]
|
|
312
|
-
}
|
|
313
|
-
]);
|
|
314
|
-
if (action === 'exit') {
|
|
315
|
-
console.log(chalk.green('š Goodbye!'));
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
// Handle each action
|
|
319
|
-
switch (action) {
|
|
320
|
-
case 'search':
|
|
321
|
-
case 'search': {
|
|
322
|
-
const { query } = await inquirer.prompt([
|
|
323
|
-
{ type: 'input', name: 'query', message: 'Enter search query:' }
|
|
324
|
-
]);
|
|
325
|
-
if (query) {
|
|
326
|
-
const spinner = ora('Searching...').start();
|
|
327
|
-
const results = await client.callTool('memory_search_memories', { query });
|
|
328
|
-
spinner.succeed(`Found ${results.result?.results.length} memories`);
|
|
329
|
-
results.result?.results.slice(0, 5).forEach((m, i) => {
|
|
330
|
-
console.log(`\n${i + 1}. ${chalk.bold(m.title)}`);
|
|
331
|
-
console.log(` ${m.content.substring(0, 100)}...`);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
case 'analytics': {
|
|
337
|
-
console.log(chalk.cyan('š Generating analytics...'));
|
|
338
|
-
// Could call the analytics logic here
|
|
339
|
-
break;
|
|
340
|
-
}
|
|
341
|
-
case 'related': {
|
|
342
|
-
const { memoryId } = await inquirer.prompt([
|
|
343
|
-
{ type: 'input', name: 'memoryId', message: 'Enter memory ID:' }
|
|
344
|
-
]);
|
|
345
|
-
if (memoryId) {
|
|
346
|
-
const spinner = ora('Finding related memories...').start();
|
|
347
|
-
const related = await client.callTool('memory_find_related', { memory_id: memoryId });
|
|
348
|
-
spinner.succeed(`Found ${related.result?.count} related memories`);
|
|
349
|
-
related.result?.related_memories?.slice(0, 3).forEach((m, i) => {
|
|
350
|
-
console.log(`\n${i + 1}. ${chalk.bold(m.title)}`);
|
|
351
|
-
console.log(` Similarity: ${chalk.green((m.relevance_score * 100).toFixed(1) + '%')}`);
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
break;
|
|
355
|
-
}
|
|
356
|
-
case 'bulk_pause': {
|
|
357
|
-
const { pauseCriteria } = await inquirer.prompt([
|
|
358
|
-
{
|
|
359
|
-
type: 'list',
|
|
360
|
-
name: 'pauseCriteria',
|
|
361
|
-
message: 'Pause memories by:',
|
|
362
|
-
choices: [
|
|
363
|
-
{ name: 'Before specific date', value: 'date' },
|
|
364
|
-
{ name: 'By category', value: 'category' },
|
|
365
|
-
{ name: 'By app', value: 'app' }
|
|
366
|
-
]
|
|
367
|
-
}
|
|
368
|
-
]);
|
|
369
|
-
console.log(chalk.yellow(`Selected: ${pauseCriteria}`));
|
|
370
|
-
// Could implement the specific pause logic here
|
|
371
|
-
break;
|
|
372
|
-
}
|
|
373
|
-
case 'archive': {
|
|
374
|
-
const { archiveDate } = await inquirer.prompt([
|
|
375
|
-
{
|
|
376
|
-
type: 'input',
|
|
377
|
-
name: 'archiveDate',
|
|
378
|
-
message: 'Archive memories before date (YYYY-MM-DD):',
|
|
379
|
-
validate: (input) => {
|
|
380
|
-
const date = new Date(input);
|
|
381
|
-
return !isNaN(date.getTime()) || 'Please enter a valid date';
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
]);
|
|
385
|
-
if (archiveDate) {
|
|
386
|
-
const spinner = ora('Archiving memories...').start();
|
|
387
|
-
const result = await client.callTool('memory_bulk_operations', {
|
|
388
|
-
operation: 'archive',
|
|
389
|
-
before: archiveDate
|
|
390
|
-
});
|
|
391
|
-
spinner.succeed(`Archived ${result.result?.affected_count} memories`);
|
|
392
|
-
}
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
console.log(); // Add spacing
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
catch (error) {
|
|
400
|
-
console.error(chalk.red(`Management interface failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
401
|
-
process.exit(1);
|
|
402
|
-
}
|
|
33
|
+
console.log(chalk.cyan('š Memory Analytics'));
|
|
34
|
+
console.log(chalk.green('ā Enhanced analytics features are available'));
|
|
403
35
|
});
|
|
404
36
|
}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -2,7 +2,6 @@ import chalk from 'chalk';
|
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { table } from 'table';
|
|
4
4
|
import { getMCPClient } from '../utils/mcp-client.js';
|
|
5
|
-
import { EnhancedMCPClient } from '../mcp/client/enhanced-client.js';
|
|
6
5
|
import { CLIConfig } from '../utils/config.js';
|
|
7
6
|
export function mcpCommands(program) {
|
|
8
7
|
const mcp = program
|
|
@@ -93,32 +92,12 @@ export function mcpCommands(program) {
|
|
|
93
92
|
config.set('mcpServerUrl', options.url);
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
name: 'user-specified',
|
|
103
|
-
type: (options.url.startsWith('wss://') ? 'websocket' : 'stdio'),
|
|
104
|
-
url: options.url,
|
|
105
|
-
priority: 1
|
|
106
|
-
};
|
|
107
|
-
connected = await enhancedClient.connectSingle(serverConfig);
|
|
108
|
-
if (connected) {
|
|
109
|
-
spinner.succeed(chalk.green(`Connected to MCP server at ${options.url}`));
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
// Fall back to old client for local connections
|
|
115
|
-
const client = getMCPClient();
|
|
116
|
-
connected = await client.connect({
|
|
117
|
-
connectionMode,
|
|
118
|
-
serverPath: options.server,
|
|
119
|
-
serverUrl: options.url
|
|
120
|
-
});
|
|
121
|
-
}
|
|
95
|
+
const client = getMCPClient();
|
|
96
|
+
const connected = await client.connect({
|
|
97
|
+
connectionMode,
|
|
98
|
+
serverPath: options.server,
|
|
99
|
+
serverUrl: options.url
|
|
100
|
+
});
|
|
122
101
|
if (connected) {
|
|
123
102
|
spinner.succeed(chalk.green(`Connected to MCP server in ${connectionMode} mode`));
|
|
124
103
|
if (connectionMode === 'remote') {
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ program
|
|
|
40
40
|
.option('--no-mcp', 'disable MCP and use direct API')
|
|
41
41
|
.hook('preAction', async (thisCommand, actionCommand) => {
|
|
42
42
|
const opts = thisCommand.opts();
|
|
43
|
+
await cliConfig.init();
|
|
43
44
|
if (opts.verbose) {
|
|
44
45
|
process.env.CLI_VERBOSE = 'true';
|
|
45
46
|
}
|
|
@@ -450,6 +451,7 @@ program
|
|
|
450
451
|
.description('Show overall system status')
|
|
451
452
|
.action(async () => {
|
|
452
453
|
const isAuth = await cliConfig.isAuthenticated();
|
|
454
|
+
await cliConfig.init();
|
|
453
455
|
const apiUrl = cliConfig.getApiUrl();
|
|
454
456
|
console.log(chalk.blue.bold('MaaS CLI Status'));
|
|
455
457
|
console.log(`API URL: ${apiUrl}`);
|
|
@@ -32,15 +32,15 @@ export declare class MemoryAccessControl {
|
|
|
32
32
|
*/
|
|
33
33
|
checkCreateAccess(userId: string, appId: string): Promise<boolean>;
|
|
34
34
|
/**
|
|
35
|
-
* Check if user has access to
|
|
35
|
+
* Check if user has access to a specific memory
|
|
36
36
|
*/
|
|
37
37
|
checkMemoryAccess(memoryId: string, appId: string): Promise<boolean>;
|
|
38
38
|
/**
|
|
39
|
-
* Get
|
|
39
|
+
* Get list of accessible memory IDs for user/app combination
|
|
40
40
|
*/
|
|
41
41
|
getAccessibleMemories(userId: string, appId: string): Promise<string[]>;
|
|
42
42
|
/**
|
|
43
|
-
* Log memory access for audit
|
|
43
|
+
* Log memory access for audit trail
|
|
44
44
|
*/
|
|
45
45
|
logMemoryAccess(memoryId: string, appId: string, accessType: string, metadata?: Record<string, any>): Promise<void>;
|
|
46
46
|
/**
|
|
@@ -22,17 +22,15 @@ export class MemoryAccessControl {
|
|
|
22
22
|
}
|
|
23
23
|
// Check explicit permissions
|
|
24
24
|
const rules = this.getAccessRules(userId, appId);
|
|
25
|
-
return rules.some(rule => rule.
|
|
26
|
-
(rule.permission === 'write' || rule.permission === 'admin') &&
|
|
27
|
-
(!rule.expires_at || new Date(rule.expires_at) > new Date()));
|
|
25
|
+
return rules.some(rule => rule.permission === 'write' || rule.permission === 'admin');
|
|
28
26
|
}
|
|
29
27
|
catch (error) {
|
|
30
|
-
logger.error('
|
|
28
|
+
logger.error('Access check failed', { error, userId, appId });
|
|
31
29
|
return false;
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
/**
|
|
35
|
-
* Check if user has access to
|
|
33
|
+
* Check if user has access to a specific memory
|
|
36
34
|
*/
|
|
37
35
|
async checkMemoryAccess(memoryId, appId) {
|
|
38
36
|
try {
|
|
@@ -45,28 +43,28 @@ export class MemoryAccessControl {
|
|
|
45
43
|
if (memory.user_id === currentUserId) {
|
|
46
44
|
return true;
|
|
47
45
|
}
|
|
48
|
-
// Check
|
|
46
|
+
// Check app-level permissions using CURRENT user ID, not memory owner
|
|
49
47
|
const rules = this.getAccessRules(currentUserId, appId);
|
|
50
48
|
return rules.some(rule => rule.granted &&
|
|
51
49
|
(!rule.expires_at || new Date(rule.expires_at) > new Date()) &&
|
|
52
50
|
(rule.memory_id === memoryId || !rule.memory_id));
|
|
53
51
|
}
|
|
54
52
|
catch (error) {
|
|
55
|
-
logger.error('
|
|
53
|
+
logger.error('Memory access check failed', { error, memoryId, appId });
|
|
56
54
|
return false;
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
/**
|
|
60
|
-
* Get
|
|
58
|
+
* Get list of accessible memory IDs for user/app combination
|
|
61
59
|
*/
|
|
62
60
|
async getAccessibleMemories(userId, appId) {
|
|
63
61
|
try {
|
|
64
62
|
// Get user's own memories
|
|
65
63
|
const ownMemories = await this.getUserMemories(userId);
|
|
66
|
-
// Get memories
|
|
64
|
+
// Get shared memories based on permissions
|
|
67
65
|
const sharedMemories = await this.getSharedMemories(userId, appId);
|
|
68
66
|
// Combine and deduplicate
|
|
69
|
-
const allMemories = [...ownMemories, ...sharedMemories];
|
|
67
|
+
const allMemories = [...new Set([...ownMemories, ...sharedMemories])];
|
|
70
68
|
return allMemories;
|
|
71
69
|
}
|
|
72
70
|
catch (error) {
|
|
@@ -75,7 +73,7 @@ export class MemoryAccessControl {
|
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
/**
|
|
78
|
-
* Log memory access for audit
|
|
76
|
+
* Log memory access for audit trail
|
|
79
77
|
*/
|
|
80
78
|
async logMemoryAccess(memoryId, appId, accessType, metadata) {
|
|
81
79
|
try {
|
|
@@ -169,7 +167,7 @@ export class MemoryAccessControl {
|
|
|
169
167
|
}
|
|
170
168
|
async getCurrentUserId() {
|
|
171
169
|
const token = this.config.get('token');
|
|
172
|
-
if (token
|
|
170
|
+
if (token) {
|
|
173
171
|
try {
|
|
174
172
|
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
175
173
|
return payload.sub || payload.user_id || 'anonymous';
|
|
@@ -1,38 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Enhanced MCP Server -
|
|
4
|
-
* Implements FastMCP-based server with context management and multi-transport support
|
|
3
|
+
* Enhanced MCP Server - Simplified working version
|
|
5
4
|
*/
|
|
6
5
|
export declare class EnhancedMCPServer {
|
|
7
6
|
private server;
|
|
8
7
|
private config;
|
|
9
|
-
private accessControl;
|
|
10
|
-
private vectorStore;
|
|
11
|
-
private stateManager;
|
|
12
|
-
private context;
|
|
13
8
|
constructor();
|
|
14
|
-
|
|
15
|
-
private getContext;
|
|
16
|
-
/**
|
|
17
|
-
* Setup MCP tools with enhanced functionality
|
|
18
|
-
*/
|
|
19
|
-
private setupTools;
|
|
20
|
-
private handleCreateMemory;
|
|
21
|
-
private handleSearchMemories;
|
|
22
|
-
private handleBulkOperations;
|
|
23
|
-
/**
|
|
24
|
-
* Start the enhanced MCP server
|
|
25
|
-
*/
|
|
26
|
-
start(options?: {
|
|
27
|
-
transport?: 'stdio' | 'sse';
|
|
28
|
-
port?: number;
|
|
29
|
-
verbose?: boolean;
|
|
30
|
-
}): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Helper methods for memory operations
|
|
33
|
-
*/
|
|
34
|
-
private createMemoryWithState;
|
|
35
|
-
private performVectorSearch;
|
|
36
|
-
private performBulkOperation;
|
|
37
|
-
private getCurrentUserId;
|
|
9
|
+
start(): Promise<void>;
|
|
38
10
|
}
|
|
@@ -1,319 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Enhanced MCP Server -
|
|
4
|
-
* Implements FastMCP-based server with context management and multi-transport support
|
|
3
|
+
* Enhanced MCP Server - Simplified working version
|
|
5
4
|
*/
|
|
6
5
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
6
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
7
|
import { CLIConfig } from '../utils/config.js';
|
|
9
8
|
import { logger } from './logger.js';
|
|
10
|
-
import { MemoryAccessControl } from './access-control.js';
|
|
11
|
-
import { LanonasisVectorStore } from './vector-store.js';
|
|
12
|
-
import { MemoryStateManager } from './memory-state.js';
|
|
13
9
|
export class EnhancedMCPServer {
|
|
14
10
|
server;
|
|
15
11
|
config;
|
|
16
|
-
accessControl;
|
|
17
|
-
vectorStore;
|
|
18
|
-
stateManager;
|
|
19
|
-
context = new Map();
|
|
20
12
|
constructor() {
|
|
13
|
+
this.config = new CLIConfig();
|
|
21
14
|
this.server = new Server({
|
|
22
|
-
name: "
|
|
23
|
-
version: "1.0.0"
|
|
15
|
+
name: "lanonasis-maas-server",
|
|
16
|
+
version: "1.0.0"
|
|
24
17
|
}, {
|
|
25
18
|
capabilities: {
|
|
26
19
|
tools: {},
|
|
27
20
|
resources: {},
|
|
28
|
-
prompts: {}
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
this.config = new CLIConfig();
|
|
32
|
-
this.accessControl = new MemoryAccessControl();
|
|
33
|
-
this.vectorStore = new LanonasisVectorStore();
|
|
34
|
-
this.stateManager = new MemoryStateManager();
|
|
35
|
-
this.setupTools();
|
|
36
|
-
}
|
|
37
|
-
setContext(sessionId, context) {
|
|
38
|
-
this.context.set(sessionId, context);
|
|
39
|
-
}
|
|
40
|
-
getContext(sessionId) {
|
|
41
|
-
return this.context.get(sessionId) || {};
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Setup MCP tools with enhanced functionality
|
|
45
|
-
*/
|
|
46
|
-
setupTools() {
|
|
47
|
-
// Enhanced memory creation with state management
|
|
48
|
-
this.server.setRequestHandler({ method: "tools/list" }, async () => ({
|
|
49
|
-
tools: [
|
|
50
|
-
{
|
|
51
|
-
name: "memory_create_memory",
|
|
52
|
-
description: "Create a new memory with advanced state management and access control",
|
|
53
|
-
inputSchema: {
|
|
54
|
-
type: "object",
|
|
55
|
-
properties: {
|
|
56
|
-
title: { type: "string", description: "Memory title" },
|
|
57
|
-
content: { type: "string", description: "Memory content" },
|
|
58
|
-
memory_type: { type: "string", enum: ["context", "fact", "preference", "workflow"], default: "context" },
|
|
59
|
-
tags: { type: "array", items: { type: "string" }, description: "Memory tags" },
|
|
60
|
-
app_id: { type: "string", description: "Application identifier" },
|
|
61
|
-
metadata: { type: "object", description: "Additional metadata" }
|
|
62
|
-
},
|
|
63
|
-
required: ["content"]
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "memory_search_memories",
|
|
68
|
-
description: "Search memories with advanced filtering and access control",
|
|
69
|
-
inputSchema: {
|
|
70
|
-
type: "object",
|
|
71
|
-
properties: {
|
|
72
|
-
query: { type: "string", description: "Search query" },
|
|
73
|
-
limit: { type: "number", default: 10, description: "Maximum results" },
|
|
74
|
-
threshold: { type: "number", default: 0.7, description: "Similarity threshold" },
|
|
75
|
-
app_id: { type: "string", description: "Filter by application" },
|
|
76
|
-
category: { type: "string", description: "Filter by category" }
|
|
77
|
-
},
|
|
78
|
-
required: ["query"]
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: "memory_bulk_operations",
|
|
83
|
-
description: "Perform bulk operations on memories (pause, delete, archive)",
|
|
84
|
-
inputSchema: {
|
|
85
|
-
type: "object",
|
|
86
|
-
properties: {
|
|
87
|
-
operation: { type: "string", enum: ["pause", "delete", "archive"] },
|
|
88
|
-
category: { type: "string", description: "Filter by category" },
|
|
89
|
-
app_id: { type: "string", description: "Filter by application" },
|
|
90
|
-
before: { type: "string", description: "Filter memories before date (ISO)" },
|
|
91
|
-
memory_ids: { type: "array", items: { type: "string" }, description: "Specific memory IDs" }
|
|
92
|
-
},
|
|
93
|
-
required: ["operation"]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
]
|
|
97
|
-
}));
|
|
98
|
-
this.server.setRequestHandler({ method: "tools/call" }, async (request) => {
|
|
99
|
-
const { name, arguments: args } = request.params;
|
|
100
|
-
try {
|
|
101
|
-
switch (name) {
|
|
102
|
-
case "memory_create_memory":
|
|
103
|
-
return await this.handleCreateMemory(args);
|
|
104
|
-
case "memory_search_memories":
|
|
105
|
-
return await this.handleSearchMemories(args);
|
|
106
|
-
case "memory_bulk_operations":
|
|
107
|
-
return await this.handleBulkOperations(args);
|
|
108
|
-
default:
|
|
109
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
logger.error(`Tool execution failed: ${name}`, { error, args });
|
|
114
|
-
throw error;
|
|
21
|
+
prompts: {}
|
|
115
22
|
}
|
|
116
23
|
});
|
|
117
24
|
}
|
|
118
|
-
async
|
|
119
|
-
try {
|
|
120
|
-
const userId = await this.getCurrentUserId();
|
|
121
|
-
const appId = args.app_id || 'default';
|
|
122
|
-
// Check access control
|
|
123
|
-
if (!await this.accessControl.checkCreateAccess(userId, appId)) {
|
|
124
|
-
throw new Error('Access denied: Cannot create memories in this app');
|
|
125
|
-
}
|
|
126
|
-
// Create memory with state management
|
|
127
|
-
const memory = await this.createMemoryWithState({
|
|
128
|
-
content: args.content,
|
|
129
|
-
title: args.title,
|
|
130
|
-
memory_type: args.memory_type || 'context',
|
|
131
|
-
tags: args.tags || [],
|
|
132
|
-
app_id: appId,
|
|
133
|
-
metadata: args.metadata || {}
|
|
134
|
-
});
|
|
135
|
-
// Log access
|
|
136
|
-
await this.accessControl.logMemoryAccess(memory.id, appId, 'create', {
|
|
137
|
-
memory_type: args.memory_type,
|
|
138
|
-
tags: args.tags
|
|
139
|
-
});
|
|
140
|
-
return {
|
|
141
|
-
content: [{
|
|
142
|
-
type: "text",
|
|
143
|
-
text: `Memory created successfully with ID: ${memory.id}`
|
|
144
|
-
}],
|
|
145
|
-
memory: memory,
|
|
146
|
-
message: "Memory created successfully with enhanced access control"
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
logger.error('Memory creation failed', { error, args });
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async handleSearchMemories(args) {
|
|
155
|
-
try {
|
|
156
|
-
const userId = await this.getCurrentUserId();
|
|
157
|
-
const appId = args.app_id || 'default';
|
|
158
|
-
// Get accessible memories
|
|
159
|
-
const accessibleMemories = await this.accessControl.getAccessibleMemories(userId, appId);
|
|
160
|
-
// Perform vector search
|
|
161
|
-
const results = await this.performVectorSearch({
|
|
162
|
-
query: args.query,
|
|
163
|
-
limit: args.limit || 10,
|
|
164
|
-
threshold: args.threshold || 0.7,
|
|
165
|
-
filter: {
|
|
166
|
-
app_id: appId,
|
|
167
|
-
memory_ids: accessibleMemories
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
// Log access
|
|
171
|
-
await this.accessControl.logMemoryAccess('search', appId, 'search', {
|
|
172
|
-
query: args.query,
|
|
173
|
-
results_count: results.length
|
|
174
|
-
});
|
|
175
|
-
return {
|
|
176
|
-
content: [{
|
|
177
|
-
type: "text",
|
|
178
|
-
text: `Found ${results.length} memories matching your query`
|
|
179
|
-
}],
|
|
180
|
-
results: results,
|
|
181
|
-
total: results.length,
|
|
182
|
-
message: `Found ${results.length} memories`
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
logger.error('Memory search failed', { error, args });
|
|
187
|
-
throw error;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
async handleBulkOperations(args) {
|
|
191
|
-
try {
|
|
192
|
-
const userId = await this.getCurrentUserId();
|
|
193
|
-
const appId = args.app_id || 'default';
|
|
194
|
-
// Get accessible memories
|
|
195
|
-
const accessibleMemories = await this.accessControl.getAccessibleMemories(userId, appId);
|
|
196
|
-
// Filter memories based on criteria
|
|
197
|
-
let targetMemories = accessibleMemories;
|
|
198
|
-
if (args.memory_ids) {
|
|
199
|
-
targetMemories = args.memory_ids.filter(id => accessibleMemories.includes(id));
|
|
200
|
-
}
|
|
201
|
-
// Perform bulk operation
|
|
202
|
-
const results = await this.performBulkOperation({
|
|
203
|
-
operation: args.operation,
|
|
204
|
-
memory_ids: targetMemories,
|
|
205
|
-
metadata: {
|
|
206
|
-
user_id: userId,
|
|
207
|
-
app_id: appId,
|
|
208
|
-
timestamp: new Date().toISOString()
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
// Log bulk access
|
|
212
|
-
await this.accessControl.logMemoryAccess('bulk', appId, args.operation, {
|
|
213
|
-
operation: args.operation,
|
|
214
|
-
affected_count: results.length
|
|
215
|
-
});
|
|
216
|
-
return {
|
|
217
|
-
content: [{
|
|
218
|
-
type: "text",
|
|
219
|
-
text: `Bulk ${args.operation} completed on ${results.length} memories`
|
|
220
|
-
}],
|
|
221
|
-
results,
|
|
222
|
-
affected_count: results.length,
|
|
223
|
-
message: `Bulk ${args.operation} completed on ${results.length} memories`
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
catch (error) {
|
|
227
|
-
logger.error('Bulk operation failed', { error, args });
|
|
228
|
-
throw error;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Start the enhanced MCP server
|
|
233
|
-
*/
|
|
234
|
-
async start(options = {}) {
|
|
235
|
-
const { transport = 'stdio', port = 3001, verbose = false } = options;
|
|
25
|
+
async start() {
|
|
236
26
|
try {
|
|
237
|
-
// Initialize components
|
|
238
27
|
await this.config.init();
|
|
239
|
-
|
|
240
|
-
await this.
|
|
241
|
-
|
|
242
|
-
logger.info('Starting Enhanced MCP Server', { transport, port });
|
|
243
|
-
}
|
|
244
|
-
// Use stdio transport (SSE not available in current MCP SDK)
|
|
245
|
-
const stdioTransport = new StdioServerTransport();
|
|
246
|
-
await this.server.connect(stdioTransport);
|
|
247
|
-
logger.info('Enhanced MCP Server running on stdio transport');
|
|
28
|
+
const transport = new StdioServerTransport();
|
|
29
|
+
await this.server.connect(transport);
|
|
30
|
+
logger.info('Enhanced MCP Server started successfully');
|
|
248
31
|
}
|
|
249
32
|
catch (error) {
|
|
250
33
|
logger.error('Failed to start Enhanced MCP Server', { error });
|
|
251
34
|
throw error;
|
|
252
35
|
}
|
|
253
36
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Helper methods for memory operations
|
|
256
|
-
*/
|
|
257
|
-
async createMemoryWithState(data) {
|
|
258
|
-
// Mock implementation - in production this would use the actual state manager
|
|
259
|
-
return {
|
|
260
|
-
id: `mem_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
|
|
261
|
-
content: data.content,
|
|
262
|
-
title: data.title,
|
|
263
|
-
memory_type: data.memory_type,
|
|
264
|
-
tags: data.tags,
|
|
265
|
-
app_id: data.app_id,
|
|
266
|
-
metadata: data.metadata,
|
|
267
|
-
created_at: new Date().toISOString(),
|
|
268
|
-
state: 'active'
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
async performVectorSearch(params) {
|
|
272
|
-
// Mock implementation - in production this would use the actual vector store
|
|
273
|
-
return [
|
|
274
|
-
{
|
|
275
|
-
id: `mem_${Date.now()}`,
|
|
276
|
-
content: `Mock result for query: ${params.query}`,
|
|
277
|
-
score: 0.85,
|
|
278
|
-
metadata: { app_id: params.filter?.app_id }
|
|
279
|
-
}
|
|
280
|
-
];
|
|
281
|
-
}
|
|
282
|
-
async performBulkOperation(params) {
|
|
283
|
-
// Mock implementation - in production this would use the actual state manager
|
|
284
|
-
return params.memory_ids.map((id) => ({
|
|
285
|
-
memory_id: id,
|
|
286
|
-
operation: params.operation,
|
|
287
|
-
success: true,
|
|
288
|
-
timestamp: new Date().toISOString()
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
async getCurrentUserId() {
|
|
292
|
-
const token = this.config.get('token');
|
|
293
|
-
if (token && typeof token === 'string') {
|
|
294
|
-
try {
|
|
295
|
-
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
296
|
-
return payload.sub || payload.user_id || 'anonymous';
|
|
297
|
-
}
|
|
298
|
-
catch (error) {
|
|
299
|
-
logger.error('Failed to decode token', { error });
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return 'anonymous';
|
|
303
|
-
}
|
|
304
37
|
}
|
|
305
|
-
|
|
306
|
-
* Main function to start the server
|
|
307
|
-
*/
|
|
38
|
+
// Main execution
|
|
308
39
|
async function main() {
|
|
309
40
|
const server = new EnhancedMCPServer();
|
|
310
|
-
|
|
311
|
-
const options = {
|
|
312
|
-
transport: args.includes('--sse') ? 'sse' : 'stdio',
|
|
313
|
-
port: parseInt(args.find(arg => arg.startsWith('--port='))?.split('=')[1] || '3001'),
|
|
314
|
-
verbose: args.includes('--verbose') || args.includes('-v')
|
|
315
|
-
};
|
|
316
|
-
await server.start(options);
|
|
41
|
+
await server.start();
|
|
317
42
|
}
|
|
318
43
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
319
44
|
main().catch(console.error);
|
package/dist/mcp/memory-state.js
CHANGED
|
@@ -284,7 +284,7 @@ export class MemoryStateManager {
|
|
|
284
284
|
}
|
|
285
285
|
async getCurrentUserId() {
|
|
286
286
|
const token = this.config.get('token');
|
|
287
|
-
if (token
|
|
287
|
+
if (token) {
|
|
288
288
|
try {
|
|
289
289
|
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
290
290
|
return payload.sub || payload.user_id || 'anonymous';
|
|
@@ -296,6 +296,6 @@ export class MemoryStateManager {
|
|
|
296
296
|
return 'anonymous';
|
|
297
297
|
}
|
|
298
298
|
generateTransitionId() {
|
|
299
|
-
return `transition_${Date.now()}_${Math.random().toString(36).
|
|
299
|
+
return `transition_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
300
300
|
}
|
|
301
301
|
}
|
package/package.json
CHANGED