@lanonasis/cli 1.3.0 → 1.4.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/mcp-server.js +402 -164
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -3,17 +3,30 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import { CLIConfig } from './utils/config.js';
|
|
6
|
-
// Redirect all console output to stderr
|
|
7
|
-
|
|
6
|
+
// MCP Protocol Compliance: Redirect all console output to stderr
|
|
7
|
+
// This prevents stdout pollution which breaks JSON-RPC communication
|
|
8
8
|
const originalConsoleError = console.error;
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
console.
|
|
14
|
-
console.
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
// Silent mode for MCP protocol compliance
|
|
10
|
+
const isSilentMode = process.env.LANONASIS_SILENT === 'true' || process.argv.includes('--silent');
|
|
11
|
+
if (isSilentMode) {
|
|
12
|
+
// Completely silence all output except JSON-RPC
|
|
13
|
+
console.log = () => { };
|
|
14
|
+
console.error = () => { };
|
|
15
|
+
console.warn = () => { };
|
|
16
|
+
console.info = () => { };
|
|
17
|
+
console.debug = () => { };
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
// Redirect to stderr for debugging
|
|
21
|
+
console.log = (...args) => originalConsoleError('[MCP-LOG]', ...args);
|
|
22
|
+
console.error = (...args) => originalConsoleError('[MCP-ERROR]', ...args);
|
|
23
|
+
console.warn = (...args) => originalConsoleError('[MCP-WARN]', ...args);
|
|
24
|
+
console.info = (...args) => originalConsoleError('[MCP-INFO]', ...args);
|
|
25
|
+
}
|
|
26
|
+
// Disable colors and verbose output for MCP protocol compliance
|
|
27
|
+
process.env.FORCE_COLOR = '0';
|
|
28
|
+
process.env.DEBUG = '';
|
|
29
|
+
process.env.NODE_ENV = process.env.NODE_ENV || 'production';
|
|
17
30
|
class LanonasisMCPServer {
|
|
18
31
|
server;
|
|
19
32
|
config;
|
|
@@ -21,42 +34,47 @@ class LanonasisMCPServer {
|
|
|
21
34
|
this.config = new CLIConfig();
|
|
22
35
|
this.server = new Server({
|
|
23
36
|
name: 'lanonasis-mcp-server',
|
|
24
|
-
version: '1.
|
|
37
|
+
version: '1.3.0',
|
|
25
38
|
}, {
|
|
26
39
|
capabilities: {
|
|
27
40
|
tools: {},
|
|
41
|
+
resources: {},
|
|
28
42
|
},
|
|
29
43
|
});
|
|
30
44
|
this.setupHandlers();
|
|
31
45
|
}
|
|
32
46
|
setupHandlers() {
|
|
33
|
-
// List available tools
|
|
47
|
+
// List available tools - Comprehensive MCP toolset matching legacy CLI
|
|
34
48
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
35
49
|
return {
|
|
36
50
|
tools: [
|
|
51
|
+
// Memory Management Tools
|
|
37
52
|
{
|
|
38
53
|
name: 'create_memory',
|
|
39
|
-
description: 'Create a new memory entry',
|
|
54
|
+
description: 'Create a new memory entry with vector embedding',
|
|
40
55
|
inputSchema: {
|
|
41
56
|
type: 'object',
|
|
42
57
|
properties: {
|
|
43
58
|
title: { type: 'string', description: 'Memory title' },
|
|
44
59
|
content: { type: 'string', description: 'Memory content' },
|
|
45
|
-
memory_type: { type: 'string', description: 'Type of memory', enum: ['
|
|
46
|
-
tags: { type: 'array', items: { type: 'string' }, description: 'Memory tags' }
|
|
60
|
+
memory_type: { type: 'string', description: 'Type of memory', enum: ['context', 'project', 'knowledge', 'reference', 'personal', 'workflow'] },
|
|
61
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Memory tags' },
|
|
62
|
+
topic_id: { type: 'string', description: 'Topic ID for organization' }
|
|
47
63
|
},
|
|
48
64
|
required: ['title', 'content']
|
|
49
65
|
}
|
|
50
66
|
},
|
|
51
67
|
{
|
|
52
68
|
name: 'search_memories',
|
|
53
|
-
description: 'Search through memories',
|
|
69
|
+
description: 'Search through memories with semantic vector search',
|
|
54
70
|
inputSchema: {
|
|
55
71
|
type: 'object',
|
|
56
72
|
properties: {
|
|
57
73
|
query: { type: 'string', description: 'Search query' },
|
|
58
74
|
memory_type: { type: 'string', description: 'Filter by memory type' },
|
|
59
|
-
limit: { type: 'number', description: 'Maximum results to return', default: 10 }
|
|
75
|
+
limit: { type: 'number', description: 'Maximum results to return', default: 10 },
|
|
76
|
+
threshold: { type: 'number', description: 'Similarity threshold (0.0-1.0)', default: 0.7 },
|
|
77
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' }
|
|
60
78
|
},
|
|
61
79
|
required: ['query']
|
|
62
80
|
}
|
|
@@ -97,175 +115,395 @@ class LanonasisMCPServer {
|
|
|
97
115
|
},
|
|
98
116
|
required: ['id']
|
|
99
117
|
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'list_memories',
|
|
121
|
+
description: 'List memories with pagination and filters',
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
limit: { type: 'number', description: 'Number of memories to return', default: 20 },
|
|
126
|
+
offset: { type: 'number', description: 'Offset for pagination', default: 0 },
|
|
127
|
+
memory_type: { type: 'string', description: 'Filter by memory type' },
|
|
128
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' }
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
// API Key Management Tools
|
|
133
|
+
{
|
|
134
|
+
name: 'create_api_key',
|
|
135
|
+
description: 'Create a new API key',
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
name: { type: 'string', description: 'API key name' },
|
|
140
|
+
description: { type: 'string', description: 'API key description' },
|
|
141
|
+
project_id: { type: 'string', description: 'Project ID' },
|
|
142
|
+
access_level: { type: 'string', description: 'Access level', enum: ['public', 'authenticated', 'team', 'admin', 'enterprise'] },
|
|
143
|
+
expires_in_days: { type: 'number', description: 'Expiration in days', default: 365 }
|
|
144
|
+
},
|
|
145
|
+
required: ['name']
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'list_api_keys',
|
|
150
|
+
description: 'List API keys',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
project_id: { type: 'string', description: 'Filter by project ID' },
|
|
155
|
+
active_only: { type: 'boolean', description: 'Show only active keys', default: true }
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'rotate_api_key',
|
|
161
|
+
description: 'Rotate an API key',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
key_id: { type: 'string', description: 'API key ID to rotate' }
|
|
166
|
+
},
|
|
167
|
+
required: ['key_id']
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'delete_api_key',
|
|
172
|
+
description: 'Delete an API key',
|
|
173
|
+
inputSchema: {
|
|
174
|
+
type: 'object',
|
|
175
|
+
properties: {
|
|
176
|
+
key_id: { type: 'string', description: 'API key ID to delete' }
|
|
177
|
+
},
|
|
178
|
+
required: ['key_id']
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
// Project Management Tools
|
|
182
|
+
{
|
|
183
|
+
name: 'create_project',
|
|
184
|
+
description: 'Create a new project',
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: 'object',
|
|
187
|
+
properties: {
|
|
188
|
+
name: { type: 'string', description: 'Project name' },
|
|
189
|
+
description: { type: 'string', description: 'Project description' },
|
|
190
|
+
organization_id: { type: 'string', description: 'Organization ID' }
|
|
191
|
+
},
|
|
192
|
+
required: ['name']
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'list_projects',
|
|
197
|
+
description: 'List projects',
|
|
198
|
+
inputSchema: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
organization_id: { type: 'string', description: 'Filter by organization ID' }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
// Organization Management Tools
|
|
206
|
+
{
|
|
207
|
+
name: 'get_organization_info',
|
|
208
|
+
description: 'Get organization information',
|
|
209
|
+
inputSchema: {
|
|
210
|
+
type: 'object',
|
|
211
|
+
properties: {}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
// Authentication Tools
|
|
215
|
+
{
|
|
216
|
+
name: 'get_auth_status',
|
|
217
|
+
description: 'Get authentication status',
|
|
218
|
+
inputSchema: {
|
|
219
|
+
type: 'object',
|
|
220
|
+
properties: {}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
// Configuration Tools
|
|
224
|
+
{
|
|
225
|
+
name: 'get_config',
|
|
226
|
+
description: 'Get configuration settings',
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
key: { type: 'string', description: 'Specific config key to retrieve' }
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: 'set_config',
|
|
236
|
+
description: 'Set configuration setting',
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: 'object',
|
|
239
|
+
properties: {
|
|
240
|
+
key: { type: 'string', description: 'Configuration key' },
|
|
241
|
+
value: { type: 'string', description: 'Configuration value' }
|
|
242
|
+
},
|
|
243
|
+
required: ['key', 'value']
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
// Health and Status Tools
|
|
247
|
+
{
|
|
248
|
+
name: 'get_health_status',
|
|
249
|
+
description: 'Get system health status',
|
|
250
|
+
inputSchema: {
|
|
251
|
+
type: 'object',
|
|
252
|
+
properties: {}
|
|
253
|
+
}
|
|
100
254
|
}
|
|
101
255
|
]
|
|
102
256
|
};
|
|
103
257
|
});
|
|
104
|
-
// Handle tool calls
|
|
258
|
+
// Handle tool calls - Comprehensive implementation
|
|
105
259
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
106
260
|
const { name, arguments: args } = request.params;
|
|
107
261
|
try {
|
|
262
|
+
const apiKey = process.env.LANONASIS_API_KEY;
|
|
263
|
+
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
264
|
+
if (!apiKey) {
|
|
265
|
+
return {
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: 'text',
|
|
269
|
+
text: 'Error: LANONASIS_API_KEY environment variable is required'
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const headers = {
|
|
275
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
276
|
+
'Content-Type': 'application/json',
|
|
277
|
+
'User-Agent': 'lanonasis-mcp-server/1.3.0'
|
|
278
|
+
};
|
|
108
279
|
switch (name) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
280
|
+
// Memory Management Tools
|
|
281
|
+
case 'create_memory': {
|
|
282
|
+
const response = await fetch(`${apiUrl}/api/memory`, {
|
|
283
|
+
method: 'POST',
|
|
284
|
+
headers,
|
|
285
|
+
body: JSON.stringify(args)
|
|
286
|
+
});
|
|
287
|
+
if (!response.ok) {
|
|
288
|
+
const errorText = await response.text();
|
|
289
|
+
throw new Error(`Memory creation failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
290
|
+
}
|
|
291
|
+
const result = await response.json();
|
|
292
|
+
return {
|
|
293
|
+
content: [
|
|
294
|
+
{
|
|
295
|
+
type: 'text',
|
|
296
|
+
text: `✅ Memory created successfully:\n${JSON.stringify(result, null, 2)}`
|
|
297
|
+
}
|
|
298
|
+
]
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
case 'search_memories': {
|
|
302
|
+
const queryParams = new URLSearchParams();
|
|
303
|
+
if (args.query)
|
|
304
|
+
queryParams.append('query', String(args.query));
|
|
305
|
+
if (args.memory_type)
|
|
306
|
+
queryParams.append('memory_type', String(args.memory_type));
|
|
307
|
+
if (args.limit)
|
|
308
|
+
queryParams.append('limit', args.limit.toString());
|
|
309
|
+
if (args.threshold)
|
|
310
|
+
queryParams.append('threshold', args.threshold.toString());
|
|
311
|
+
if (args.tags && Array.isArray(args.tags)) {
|
|
312
|
+
args.tags.forEach((tag) => queryParams.append('tags', String(tag)));
|
|
313
|
+
}
|
|
314
|
+
const response = await fetch(`${apiUrl}/api/memory/search?${queryParams}`, {
|
|
315
|
+
method: 'GET',
|
|
316
|
+
headers
|
|
317
|
+
});
|
|
318
|
+
if (!response.ok) {
|
|
319
|
+
const errorText = await response.text();
|
|
320
|
+
throw new Error(`Memory search failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
321
|
+
}
|
|
322
|
+
const result = await response.json();
|
|
323
|
+
return {
|
|
324
|
+
content: [
|
|
325
|
+
{
|
|
326
|
+
type: 'text',
|
|
327
|
+
text: `🔍 Search results (${result.length || 0} found):\n${JSON.stringify(result, null, 2)}`
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
case 'get_memory': {
|
|
333
|
+
const response = await fetch(`${apiUrl}/api/memory/${args.id}`, {
|
|
334
|
+
method: 'GET',
|
|
335
|
+
headers
|
|
336
|
+
});
|
|
337
|
+
if (!response.ok) {
|
|
338
|
+
const errorText = await response.text();
|
|
339
|
+
throw new Error(`Memory retrieval failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
340
|
+
}
|
|
341
|
+
const result = await response.json();
|
|
342
|
+
return {
|
|
343
|
+
content: [
|
|
344
|
+
{
|
|
345
|
+
type: 'text',
|
|
346
|
+
text: `📄 Memory details:\n${JSON.stringify(result, null, 2)}`
|
|
347
|
+
}
|
|
348
|
+
]
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
case 'update_memory': {
|
|
352
|
+
const { id, ...updateData } = args;
|
|
353
|
+
const response = await fetch(`${apiUrl}/api/memory/${id}`, {
|
|
354
|
+
method: 'PUT',
|
|
355
|
+
headers,
|
|
356
|
+
body: JSON.stringify(updateData)
|
|
357
|
+
});
|
|
358
|
+
if (!response.ok) {
|
|
359
|
+
const errorText = await response.text();
|
|
360
|
+
throw new Error(`Memory update failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
361
|
+
}
|
|
362
|
+
const result = await response.json();
|
|
363
|
+
return {
|
|
364
|
+
content: [
|
|
365
|
+
{
|
|
366
|
+
type: 'text',
|
|
367
|
+
text: `✏️ Memory updated successfully:\n${JSON.stringify(result, null, 2)}`
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
case 'delete_memory': {
|
|
373
|
+
const response = await fetch(`${apiUrl}/api/memory/${args.id}`, {
|
|
374
|
+
method: 'DELETE',
|
|
375
|
+
headers
|
|
376
|
+
});
|
|
377
|
+
if (!response.ok) {
|
|
378
|
+
const errorText = await response.text();
|
|
379
|
+
throw new Error(`Memory deletion failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
content: [
|
|
383
|
+
{
|
|
384
|
+
type: 'text',
|
|
385
|
+
text: `🗑️ Memory deleted successfully (ID: ${args.id})`
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
case 'list_memories': {
|
|
391
|
+
const queryParams = new URLSearchParams();
|
|
392
|
+
if (args.limit)
|
|
393
|
+
queryParams.append('limit', args.limit.toString());
|
|
394
|
+
if (args.offset)
|
|
395
|
+
queryParams.append('offset', args.offset.toString());
|
|
396
|
+
if (args.memory_type)
|
|
397
|
+
queryParams.append('memory_type', String(args.memory_type));
|
|
398
|
+
if (args.tags && Array.isArray(args.tags)) {
|
|
399
|
+
args.tags.forEach((tag) => queryParams.append('tags', String(tag)));
|
|
400
|
+
}
|
|
401
|
+
const response = await fetch(`${apiUrl}/api/memory?${queryParams}`, {
|
|
402
|
+
method: 'GET',
|
|
403
|
+
headers
|
|
404
|
+
});
|
|
405
|
+
if (!response.ok) {
|
|
406
|
+
const errorText = await response.text();
|
|
407
|
+
throw new Error(`Memory listing failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
408
|
+
}
|
|
409
|
+
const result = await response.json();
|
|
410
|
+
return {
|
|
411
|
+
content: [
|
|
412
|
+
{
|
|
413
|
+
type: 'text',
|
|
414
|
+
text: `📋 Memory list (${result.length || 0} items):\n${JSON.stringify(result, null, 2)}`
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
// API Key Management Tools
|
|
420
|
+
case 'create_api_key': {
|
|
421
|
+
const response = await fetch(`${apiUrl}/api/api-keys`, {
|
|
422
|
+
method: 'POST',
|
|
423
|
+
headers,
|
|
424
|
+
body: JSON.stringify(args)
|
|
425
|
+
});
|
|
426
|
+
if (!response.ok) {
|
|
427
|
+
const errorText = await response.text();
|
|
428
|
+
throw new Error(`API key creation failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
429
|
+
}
|
|
430
|
+
const result = await response.json();
|
|
431
|
+
return {
|
|
432
|
+
content: [
|
|
433
|
+
{
|
|
434
|
+
type: 'text',
|
|
435
|
+
text: `🔑 API key created successfully:\n${JSON.stringify(result, null, 2)}`
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
case 'list_api_keys': {
|
|
441
|
+
const queryParams = new URLSearchParams();
|
|
442
|
+
if (args.project_id)
|
|
443
|
+
queryParams.append('project_id', String(args.project_id));
|
|
444
|
+
if (args.active_only !== undefined)
|
|
445
|
+
queryParams.append('active_only', args.active_only.toString());
|
|
446
|
+
const response = await fetch(`${apiUrl}/api/api-keys?${queryParams}`, {
|
|
447
|
+
method: 'GET',
|
|
448
|
+
headers
|
|
449
|
+
});
|
|
450
|
+
if (!response.ok) {
|
|
451
|
+
const errorText = await response.text();
|
|
452
|
+
throw new Error(`API key listing failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
453
|
+
}
|
|
454
|
+
const result = await response.json();
|
|
455
|
+
return {
|
|
456
|
+
content: [
|
|
457
|
+
{
|
|
458
|
+
type: 'text',
|
|
459
|
+
text: `🔑 API keys (${result.length || 0} found):\n${JSON.stringify(result, null, 2)}`
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
case 'get_health_status': {
|
|
465
|
+
const response = await fetch(`${apiUrl}/api/health`, {
|
|
466
|
+
method: 'GET',
|
|
467
|
+
headers
|
|
468
|
+
});
|
|
469
|
+
if (!response.ok) {
|
|
470
|
+
const errorText = await response.text();
|
|
471
|
+
throw new Error(`Health check failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
472
|
+
}
|
|
473
|
+
const result = await response.json();
|
|
474
|
+
return {
|
|
475
|
+
content: [
|
|
476
|
+
{
|
|
477
|
+
type: 'text',
|
|
478
|
+
text: `💚 System health status:\n${JSON.stringify(result, null, 2)}`
|
|
479
|
+
}
|
|
480
|
+
]
|
|
481
|
+
};
|
|
482
|
+
}
|
|
119
483
|
default:
|
|
120
|
-
|
|
484
|
+
return {
|
|
485
|
+
content: [
|
|
486
|
+
{
|
|
487
|
+
type: 'text',
|
|
488
|
+
text: `❌ Unknown tool: ${name}. Available tools: create_memory, search_memories, get_memory, update_memory, delete_memory, list_memories, create_api_key, list_api_keys, get_health_status`
|
|
489
|
+
}
|
|
490
|
+
]
|
|
491
|
+
};
|
|
121
492
|
}
|
|
122
493
|
}
|
|
123
494
|
catch (error) {
|
|
495
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
124
496
|
return {
|
|
125
497
|
content: [
|
|
126
498
|
{
|
|
127
499
|
type: 'text',
|
|
128
|
-
text:
|
|
500
|
+
text: `❌ Error: ${errorMessage}`
|
|
129
501
|
}
|
|
130
502
|
]
|
|
131
503
|
};
|
|
132
504
|
}
|
|
133
505
|
});
|
|
134
506
|
}
|
|
135
|
-
async createMemory(args) {
|
|
136
|
-
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
137
|
-
const apiKey = process.env.LANONASIS_API_KEY || this.config.get('token');
|
|
138
|
-
if (!apiKey) {
|
|
139
|
-
throw new Error('No API key found. Please authenticate first.');
|
|
140
|
-
}
|
|
141
|
-
const response = await fetch(`${apiUrl}/api/memories`, {
|
|
142
|
-
method: 'POST',
|
|
143
|
-
headers: {
|
|
144
|
-
'Content-Type': 'application/json',
|
|
145
|
-
'Authorization': `Bearer ${apiKey}`
|
|
146
|
-
},
|
|
147
|
-
body: JSON.stringify(args)
|
|
148
|
-
});
|
|
149
|
-
if (!response.ok) {
|
|
150
|
-
throw new Error(`API request failed: ${response.statusText}`);
|
|
151
|
-
}
|
|
152
|
-
const result = await response.json();
|
|
153
|
-
return {
|
|
154
|
-
content: [
|
|
155
|
-
{
|
|
156
|
-
type: 'text',
|
|
157
|
-
text: `Memory created successfully with ID: ${result.id}`
|
|
158
|
-
}
|
|
159
|
-
]
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
async searchMemories(args) {
|
|
163
|
-
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
164
|
-
const apiKey = process.env.LANONASIS_API_KEY || this.config.get('token');
|
|
165
|
-
if (!apiKey) {
|
|
166
|
-
throw new Error('No API key found. Please authenticate first.');
|
|
167
|
-
}
|
|
168
|
-
const params = new URLSearchParams();
|
|
169
|
-
if (args.query)
|
|
170
|
-
params.append('query', args.query);
|
|
171
|
-
if (args.memory_type)
|
|
172
|
-
params.append('memory_type', args.memory_type);
|
|
173
|
-
if (args.limit)
|
|
174
|
-
params.append('limit', args.limit.toString());
|
|
175
|
-
const response = await fetch(`${apiUrl}/api/memories/search?${params}`, {
|
|
176
|
-
headers: {
|
|
177
|
-
'Authorization': `Bearer ${apiKey}`
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
if (!response.ok) {
|
|
181
|
-
throw new Error(`API request failed: ${response.statusText}`);
|
|
182
|
-
}
|
|
183
|
-
const results = await response.json();
|
|
184
|
-
return {
|
|
185
|
-
content: [
|
|
186
|
-
{
|
|
187
|
-
type: 'text',
|
|
188
|
-
text: `Found ${results.length} memories:\n\n${results.map((m) => `ID: ${m.id}\nTitle: ${m.title}\nType: ${m.memory_type}\nContent: ${m.content.substring(0, 100)}...\n`).join('\n')}`
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
async getMemory(args) {
|
|
194
|
-
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
195
|
-
const apiKey = process.env.LANONASIS_API_KEY || this.config.get('token');
|
|
196
|
-
if (!apiKey) {
|
|
197
|
-
throw new Error('No API key found. Please authenticate first.');
|
|
198
|
-
}
|
|
199
|
-
const response = await fetch(`${apiUrl}/api/memories/${args.id}`, {
|
|
200
|
-
headers: {
|
|
201
|
-
'Authorization': `Bearer ${apiKey}`
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
if (!response.ok) {
|
|
205
|
-
throw new Error(`API request failed: ${response.statusText}`);
|
|
206
|
-
}
|
|
207
|
-
const memory = await response.json();
|
|
208
|
-
return {
|
|
209
|
-
content: [
|
|
210
|
-
{
|
|
211
|
-
type: 'text',
|
|
212
|
-
text: `Memory Details:\nID: ${memory.id}\nTitle: ${memory.title}\nType: ${memory.memory_type}\nContent: ${memory.content}\nTags: ${memory.tags?.join(', ') || 'None'}\nCreated: ${memory.created_at}`
|
|
213
|
-
}
|
|
214
|
-
]
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
async updateMemory(args) {
|
|
218
|
-
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
219
|
-
const apiKey = process.env.LANONASIS_API_KEY || this.config.get('token');
|
|
220
|
-
if (!apiKey) {
|
|
221
|
-
throw new Error('No API key found. Please authenticate first.');
|
|
222
|
-
}
|
|
223
|
-
const { id, ...updateData } = args;
|
|
224
|
-
const response = await fetch(`${apiUrl}/api/memories/${id}`, {
|
|
225
|
-
method: 'PUT',
|
|
226
|
-
headers: {
|
|
227
|
-
'Content-Type': 'application/json',
|
|
228
|
-
'Authorization': `Bearer ${apiKey}`
|
|
229
|
-
},
|
|
230
|
-
body: JSON.stringify(updateData)
|
|
231
|
-
});
|
|
232
|
-
if (!response.ok) {
|
|
233
|
-
throw new Error(`API request failed: ${response.statusText}`);
|
|
234
|
-
}
|
|
235
|
-
const result = await response.json();
|
|
236
|
-
return {
|
|
237
|
-
content: [
|
|
238
|
-
{
|
|
239
|
-
type: 'text',
|
|
240
|
-
text: `Memory ${id} updated successfully`
|
|
241
|
-
}
|
|
242
|
-
]
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
async deleteMemory(args) {
|
|
246
|
-
const apiUrl = process.env.LANONASIS_API_URL || 'https://api.lanonasis.com';
|
|
247
|
-
const apiKey = process.env.LANONASIS_API_KEY || this.config.get('token');
|
|
248
|
-
if (!apiKey) {
|
|
249
|
-
throw new Error('No API key found. Please authenticate first.');
|
|
250
|
-
}
|
|
251
|
-
const response = await fetch(`${apiUrl}/api/memories/${args.id}`, {
|
|
252
|
-
method: 'DELETE',
|
|
253
|
-
headers: {
|
|
254
|
-
'Authorization': `Bearer ${apiKey}`
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
if (!response.ok) {
|
|
258
|
-
throw new Error(`API request failed: ${response.statusText}`);
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
content: [
|
|
262
|
-
{
|
|
263
|
-
type: 'text',
|
|
264
|
-
text: `Memory ${args.id} deleted successfully`
|
|
265
|
-
}
|
|
266
|
-
]
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
507
|
async run() {
|
|
270
508
|
const transport = new StdioServerTransport();
|
|
271
509
|
await this.server.connect(transport);
|
package/package.json
CHANGED