@lanonasis/cli 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +357 -80
- package/dist/commands/auth.js +151 -1
- package/dist/commands/mcp.js +37 -30
- package/dist/commands/memory.js +78 -53
- package/dist/index-simple.js +189 -522
- package/dist/index.js +221 -327
- package/dist/utils/api.d.ts +2 -12
- package/dist/utils/api.js +0 -17
- package/dist/utils/completions.d.ts +28 -0
- package/dist/utils/completions.js +276 -0
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.js +13 -0
- package/dist/utils/formatting.d.ts +0 -2
- package/dist/utils/formatting.js +0 -13
- package/dist/utils/mcp-client.d.ts +6 -49
- package/dist/utils/mcp-client.js +82 -161
- package/dist/utils/mcp-client.test.d.ts +1 -0
- package/dist/utils/mcp-client.test.js +125 -0
- package/dist/utils/output.d.ts +23 -0
- package/dist/utils/output.js +97 -0
- package/dist/utils/websocket-mcp-client.d.ts +60 -0
- package/dist/utils/websocket-mcp-client.js +182 -0
- package/dist/utils/websocket-mcp-client.test.d.ts +1 -0
- package/dist/utils/websocket-mcp-client.test.js +126 -0
- package/package.json +10 -17
- package/dist/commands/api-keys.d.ts +0 -3
- package/dist/commands/api-keys.js +0 -812
- package/dist/mcp-server.d.ts +0 -2
- package/dist/mcp-server.js +0 -519
package/dist/mcp-server.d.ts
DELETED
package/dist/mcp-server.js
DELETED
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
-
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
-
import { CLIConfig } from './utils/config.js';
|
|
6
|
-
// MCP Protocol Compliance: Redirect all console output to stderr
|
|
7
|
-
// This prevents stdout pollution which breaks JSON-RPC communication
|
|
8
|
-
const originalConsoleError = console.error;
|
|
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';
|
|
30
|
-
class LanonasisMCPServer {
|
|
31
|
-
server;
|
|
32
|
-
config;
|
|
33
|
-
constructor() {
|
|
34
|
-
this.config = new CLIConfig();
|
|
35
|
-
this.server = new Server({
|
|
36
|
-
name: 'lanonasis-mcp-server',
|
|
37
|
-
version: '1.3.0',
|
|
38
|
-
}, {
|
|
39
|
-
capabilities: {
|
|
40
|
-
tools: {},
|
|
41
|
-
resources: {},
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
this.setupHandlers();
|
|
45
|
-
}
|
|
46
|
-
setupHandlers() {
|
|
47
|
-
// List available tools - Comprehensive MCP toolset matching legacy CLI
|
|
48
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
49
|
-
return {
|
|
50
|
-
tools: [
|
|
51
|
-
// Memory Management Tools
|
|
52
|
-
{
|
|
53
|
-
name: 'create_memory',
|
|
54
|
-
description: 'Create a new memory entry with vector embedding',
|
|
55
|
-
inputSchema: {
|
|
56
|
-
type: 'object',
|
|
57
|
-
properties: {
|
|
58
|
-
title: { type: 'string', description: 'Memory title' },
|
|
59
|
-
content: { type: 'string', description: 'Memory content' },
|
|
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' }
|
|
63
|
-
},
|
|
64
|
-
required: ['title', 'content']
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: 'search_memories',
|
|
69
|
-
description: 'Search through memories with semantic vector search',
|
|
70
|
-
inputSchema: {
|
|
71
|
-
type: 'object',
|
|
72
|
-
properties: {
|
|
73
|
-
query: { type: 'string', description: 'Search query' },
|
|
74
|
-
memory_type: { type: 'string', description: 'Filter by memory type' },
|
|
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' }
|
|
78
|
-
},
|
|
79
|
-
required: ['query']
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
name: 'get_memory',
|
|
84
|
-
description: 'Get a specific memory by ID',
|
|
85
|
-
inputSchema: {
|
|
86
|
-
type: 'object',
|
|
87
|
-
properties: {
|
|
88
|
-
id: { type: 'string', description: 'Memory ID' }
|
|
89
|
-
},
|
|
90
|
-
required: ['id']
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'update_memory',
|
|
95
|
-
description: 'Update an existing memory',
|
|
96
|
-
inputSchema: {
|
|
97
|
-
type: 'object',
|
|
98
|
-
properties: {
|
|
99
|
-
id: { type: 'string', description: 'Memory ID' },
|
|
100
|
-
title: { type: 'string', description: 'Memory title' },
|
|
101
|
-
content: { type: 'string', description: 'Memory content' },
|
|
102
|
-
memory_type: { type: 'string', description: 'Type of memory' },
|
|
103
|
-
tags: { type: 'array', items: { type: 'string' }, description: 'Memory tags' }
|
|
104
|
-
},
|
|
105
|
-
required: ['id']
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: 'delete_memory',
|
|
110
|
-
description: 'Delete a memory by ID',
|
|
111
|
-
inputSchema: {
|
|
112
|
-
type: 'object',
|
|
113
|
-
properties: {
|
|
114
|
-
id: { type: 'string', description: 'Memory ID' }
|
|
115
|
-
},
|
|
116
|
-
required: ['id']
|
|
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
|
-
}
|
|
254
|
-
}
|
|
255
|
-
]
|
|
256
|
-
};
|
|
257
|
-
});
|
|
258
|
-
// Handle tool calls - Comprehensive implementation
|
|
259
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
260
|
-
const { name, arguments: args } = request.params;
|
|
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
|
-
};
|
|
279
|
-
switch (name) {
|
|
280
|
-
// Memory Management Tools
|
|
281
|
-
case 'create_memory': {
|
|
282
|
-
const response = await fetch(`${apiUrl}/api/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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
|
-
}
|
|
483
|
-
default:
|
|
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
|
-
};
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
catch (error) {
|
|
495
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
496
|
-
return {
|
|
497
|
-
content: [
|
|
498
|
-
{
|
|
499
|
-
type: 'text',
|
|
500
|
-
text: `❌ Error: ${errorMessage}`
|
|
501
|
-
}
|
|
502
|
-
]
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
async run() {
|
|
508
|
-
const transport = new StdioServerTransport();
|
|
509
|
-
await this.server.connect(transport);
|
|
510
|
-
// Log to stderr that server is ready
|
|
511
|
-
console.error('[MCP-INFO] Lanonasis MCP Server started and ready');
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
// Start the server
|
|
515
|
-
const server = new LanonasisMCPServer();
|
|
516
|
-
server.run().catch((error) => {
|
|
517
|
-
console.error('[MCP-ERROR] Failed to start server:', error);
|
|
518
|
-
process.exit(1);
|
|
519
|
-
});
|