@lanonasis/cli 3.7.4 → 3.7.5
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/utils/api.js +16 -15
- package/dist/utils/config.js +16 -11
- package/dist/utils/mcp-client.js +19 -11
- package/package.json +2 -2
package/dist/utils/api.js
CHANGED
|
@@ -2,7 +2,6 @@ import axios from 'axios';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
4
|
import { CLIConfig } from './config.js';
|
|
5
|
-
import { ensureApiKeyHash } from './hash-utils.js';
|
|
6
5
|
export class APIClient {
|
|
7
6
|
client;
|
|
8
7
|
config;
|
|
@@ -31,7 +30,8 @@ export class APIClient {
|
|
|
31
30
|
const vendorKey = this.config.getVendorKey();
|
|
32
31
|
if (vendorKey) {
|
|
33
32
|
// Vendor key authentication (validated server-side)
|
|
34
|
-
|
|
33
|
+
// Send raw key - server handles hashing for comparison
|
|
34
|
+
config.headers['X-API-Key'] = vendorKey;
|
|
35
35
|
config.headers['X-Auth-Method'] = 'vendor_key';
|
|
36
36
|
}
|
|
37
37
|
else if (token) {
|
|
@@ -100,61 +100,62 @@ export class APIClient {
|
|
|
100
100
|
return response.data;
|
|
101
101
|
}
|
|
102
102
|
// Memory operations - aligned with existing schema
|
|
103
|
+
// All memory endpoints use /api/v1/memory path
|
|
103
104
|
async createMemory(data) {
|
|
104
|
-
const response = await this.client.post('/memory', data);
|
|
105
|
+
const response = await this.client.post('/api/v1/memory', data);
|
|
105
106
|
return response.data;
|
|
106
107
|
}
|
|
107
108
|
async getMemories(params = {}) {
|
|
108
|
-
const response = await this.client.get('/memory', { params });
|
|
109
|
+
const response = await this.client.get('/api/v1/memory', { params });
|
|
109
110
|
return response.data;
|
|
110
111
|
}
|
|
111
112
|
async getMemory(id) {
|
|
112
|
-
const response = await this.client.get(`/memory/${id}`);
|
|
113
|
+
const response = await this.client.get(`/api/v1/memory/${id}`);
|
|
113
114
|
return response.data;
|
|
114
115
|
}
|
|
115
116
|
async updateMemory(id, data) {
|
|
116
|
-
const response = await this.client.put(`/memory/${id}`, data);
|
|
117
|
+
const response = await this.client.put(`/api/v1/memory/${id}`, data);
|
|
117
118
|
return response.data;
|
|
118
119
|
}
|
|
119
120
|
async deleteMemory(id) {
|
|
120
|
-
await this.client.delete(`/memory/${id}`);
|
|
121
|
+
await this.client.delete(`/api/v1/memory/${id}`);
|
|
121
122
|
}
|
|
122
123
|
async searchMemories(query, options = {}) {
|
|
123
|
-
const response = await this.client.post('/memory/search', {
|
|
124
|
+
const response = await this.client.post('/api/v1/memory/search', {
|
|
124
125
|
query,
|
|
125
126
|
...options
|
|
126
127
|
});
|
|
127
128
|
return response.data;
|
|
128
129
|
}
|
|
129
130
|
async getMemoryStats() {
|
|
130
|
-
const response = await this.client.get('/memory/stats');
|
|
131
|
+
const response = await this.client.get('/api/v1/memory/stats');
|
|
131
132
|
return response.data;
|
|
132
133
|
}
|
|
133
134
|
async bulkDeleteMemories(memoryIds) {
|
|
134
|
-
const response = await this.client.post('/memory/bulk/delete', {
|
|
135
|
+
const response = await this.client.post('/api/v1/memory/bulk/delete', {
|
|
135
136
|
memory_ids: memoryIds
|
|
136
137
|
});
|
|
137
138
|
return response.data;
|
|
138
139
|
}
|
|
139
140
|
// Topic operations - working with existing memory_topics table
|
|
140
141
|
async createTopic(data) {
|
|
141
|
-
const response = await this.client.post('/topics', data);
|
|
142
|
+
const response = await this.client.post('/api/v1/topics', data);
|
|
142
143
|
return response.data;
|
|
143
144
|
}
|
|
144
145
|
async getTopics() {
|
|
145
|
-
const response = await this.client.get('/topics');
|
|
146
|
+
const response = await this.client.get('/api/v1/topics');
|
|
146
147
|
return response.data;
|
|
147
148
|
}
|
|
148
149
|
async getTopic(id) {
|
|
149
|
-
const response = await this.client.get(`/topics/${id}`);
|
|
150
|
+
const response = await this.client.get(`/api/v1/topics/${id}`);
|
|
150
151
|
return response.data;
|
|
151
152
|
}
|
|
152
153
|
async updateTopic(id, data) {
|
|
153
|
-
const response = await this.client.put(`/topics/${id}`, data);
|
|
154
|
+
const response = await this.client.put(`/api/v1/topics/${id}`, data);
|
|
154
155
|
return response.data;
|
|
155
156
|
}
|
|
156
157
|
async deleteTopic(id) {
|
|
157
|
-
await this.client.delete(`/topics/${id}`);
|
|
158
|
+
await this.client.delete(`/api/v1/topics/${id}`);
|
|
158
159
|
}
|
|
159
160
|
// Health check
|
|
160
161
|
async getHealth() {
|
package/dist/utils/config.js
CHANGED
|
@@ -168,9 +168,11 @@ export class CLIConfig {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
getApiUrl() {
|
|
171
|
-
|
|
171
|
+
const baseUrl = process.env.MEMORY_API_URL ||
|
|
172
172
|
this.config.apiUrl ||
|
|
173
|
-
'https://
|
|
173
|
+
'https://mcp.lanonasis.com';
|
|
174
|
+
// Ensure we don't double-append /api/v1 - strip it if present since APIClient adds it
|
|
175
|
+
return baseUrl.replace(/\/api\/v1\/?$/, '');
|
|
174
176
|
}
|
|
175
177
|
// Get API URLs with fallbacks - try multiple endpoints
|
|
176
178
|
getApiUrlsWithFallbacks() {
|
|
@@ -190,8 +192,8 @@ export class CLIConfig {
|
|
|
190
192
|
if (!this.config.discoveredServices) {
|
|
191
193
|
this.config.discoveredServices = {
|
|
192
194
|
auth_base: 'https://auth.lanonasis.com',
|
|
193
|
-
memory_base: 'https://mcp.lanonasis.com/api/v1
|
|
194
|
-
mcp_base: 'https://mcp.lanonasis.com/api/v1',
|
|
195
|
+
memory_base: 'https://mcp.lanonasis.com', // Base URL without /api/v1
|
|
196
|
+
mcp_base: 'https://mcp.lanonasis.com/api/v1', // Full MCP REST path
|
|
195
197
|
mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
|
|
196
198
|
mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
|
|
197
199
|
project_scope: 'lanonasis-maas'
|
|
@@ -243,13 +245,16 @@ export class CLIConfig {
|
|
|
243
245
|
if (authBase.includes('localhost') || authBase.includes('127.0.0.1')) {
|
|
244
246
|
authBase = 'https://auth.lanonasis.com';
|
|
245
247
|
}
|
|
246
|
-
|
|
248
|
+
// Memory base should be the MCP base URL without /api/v1 suffix
|
|
249
|
+
// The API client will append the path as needed
|
|
250
|
+
const rawMemoryBase = discovered.endpoints?.http || 'https://mcp.lanonasis.com/api/v1';
|
|
251
|
+
const memoryBase = rawMemoryBase.replace(/\/api\/v1\/?$/, '') || 'https://mcp.lanonasis.com';
|
|
247
252
|
this.config.discoveredServices = {
|
|
248
253
|
auth_base: authBase || 'https://auth.lanonasis.com',
|
|
249
254
|
memory_base: memoryBase,
|
|
250
|
-
mcp_base: memoryBase
|
|
255
|
+
mcp_base: `${memoryBase}/api/v1`, // Full path for MCP REST calls
|
|
251
256
|
mcp_ws_base: discovered.endpoints?.websocket || 'wss://mcp.lanonasis.com/ws',
|
|
252
|
-
mcp_sse_base: discovered.endpoints?.sse ||
|
|
257
|
+
mcp_sse_base: discovered.endpoints?.sse || `${memoryBase}/api/v1/events`,
|
|
253
258
|
project_scope: 'lanonasis-maas'
|
|
254
259
|
};
|
|
255
260
|
this.config.apiUrl = memoryBase;
|
|
@@ -366,8 +371,8 @@ export class CLIConfig {
|
|
|
366
371
|
const nodeEnv = (process.env.NODE_ENV ?? '').toLowerCase();
|
|
367
372
|
const isDevEnvironment = nodeEnv === 'development' || nodeEnv === 'test';
|
|
368
373
|
const defaultAuthBase = isDevEnvironment ? 'http://localhost:4000' : 'https://auth.lanonasis.com';
|
|
369
|
-
const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000
|
|
370
|
-
const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1';
|
|
374
|
+
const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000' : 'https://mcp.lanonasis.com'; // Base URL without /api/v1
|
|
375
|
+
const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1'; // Full MCP REST path
|
|
371
376
|
const defaultMcpWsBase = isDevEnvironment ? 'ws://localhost:4100/ws' : 'wss://mcp.lanonasis.com/ws';
|
|
372
377
|
const defaultMcpSseBase = isDevEnvironment ? 'http://localhost:4100/api/v1/events' : 'https://mcp.lanonasis.com/api/v1/events';
|
|
373
378
|
const endpoints = {
|
|
@@ -433,8 +438,8 @@ export class CLIConfig {
|
|
|
433
438
|
}
|
|
434
439
|
const currentServices = this.config.discoveredServices ?? {
|
|
435
440
|
auth_base: 'https://auth.lanonasis.com',
|
|
436
|
-
memory_base: 'https://mcp.lanonasis.com/api/v1
|
|
437
|
-
mcp_base: 'https://mcp.lanonasis.com/api/v1',
|
|
441
|
+
memory_base: 'https://mcp.lanonasis.com', // Base URL without /api/v1
|
|
442
|
+
mcp_base: 'https://mcp.lanonasis.com/api/v1', // Full MCP REST path
|
|
438
443
|
mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
|
|
439
444
|
mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
|
|
440
445
|
project_scope: 'lanonasis-maas'
|
package/dist/utils/mcp-client.js
CHANGED
|
@@ -456,9 +456,11 @@ export class MCPClient {
|
|
|
456
456
|
// Use the proper SSE endpoint from config
|
|
457
457
|
const sseUrl = this.config.getMCPSSEUrl() ?? `${serverUrl}/events`;
|
|
458
458
|
const token = this.config.get('token');
|
|
459
|
-
|
|
459
|
+
const vendorKey = this.config.get('vendorKey');
|
|
460
|
+
const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
|
|
461
|
+
if (authKey) {
|
|
460
462
|
// EventSource doesn't support headers directly, append token to URL
|
|
461
|
-
this.sseConnection = new EventSource(`${sseUrl}?token=${encodeURIComponent(
|
|
463
|
+
this.sseConnection = new EventSource(`${sseUrl}?token=${encodeURIComponent(authKey)}`);
|
|
462
464
|
this.sseConnection.onmessage = (event) => {
|
|
463
465
|
try {
|
|
464
466
|
const data = JSON.parse(event.data);
|
|
@@ -478,7 +480,9 @@ export class MCPClient {
|
|
|
478
480
|
*/
|
|
479
481
|
async initializeWebSocket(wsUrl) {
|
|
480
482
|
const token = this.config.get('token');
|
|
481
|
-
|
|
483
|
+
const vendorKey = this.config.get('vendorKey');
|
|
484
|
+
const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
|
|
485
|
+
if (!authKey) {
|
|
482
486
|
throw new Error('API key required for WebSocket mode. Set LANONASIS_API_KEY or login first.');
|
|
483
487
|
}
|
|
484
488
|
return new Promise((resolve, reject) => {
|
|
@@ -491,8 +495,8 @@ export class MCPClient {
|
|
|
491
495
|
// Create new WebSocket connection with authentication
|
|
492
496
|
this.wsConnection = new WebSocket(wsUrl, [], {
|
|
493
497
|
headers: {
|
|
494
|
-
'Authorization': `Bearer ${
|
|
495
|
-
'X-API-Key':
|
|
498
|
+
'Authorization': `Bearer ${authKey}`,
|
|
499
|
+
'X-API-Key': authKey
|
|
496
500
|
}
|
|
497
501
|
});
|
|
498
502
|
this.wsConnection.on('open', () => {
|
|
@@ -624,15 +628,17 @@ export class MCPClient {
|
|
|
624
628
|
async checkRemoteHealth() {
|
|
625
629
|
const apiUrl = this.config.getMCPRestUrl() ?? 'https://mcp.lanonasis.com/api/v1';
|
|
626
630
|
const token = this.config.get('token');
|
|
627
|
-
|
|
631
|
+
const vendorKey = this.config.get('vendorKey');
|
|
632
|
+
const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
|
|
633
|
+
if (!authKey) {
|
|
628
634
|
throw new Error('No authentication token available');
|
|
629
635
|
}
|
|
630
636
|
try {
|
|
631
637
|
const axios = (await import('axios')).default;
|
|
632
638
|
await axios.get(`${apiUrl}/health`, {
|
|
633
639
|
headers: {
|
|
634
|
-
'Authorization': `Bearer ${
|
|
635
|
-
'
|
|
640
|
+
'Authorization': `Bearer ${authKey}`,
|
|
641
|
+
'X-API-Key': authKey
|
|
636
642
|
},
|
|
637
643
|
timeout: 5000
|
|
638
644
|
});
|
|
@@ -749,7 +755,9 @@ export class MCPClient {
|
|
|
749
755
|
async callRemoteTool(toolName, args) {
|
|
750
756
|
const apiUrl = this.config.getMCPRestUrl() ?? 'https://mcp.lanonasis.com/api/v1';
|
|
751
757
|
const token = this.config.get('token');
|
|
752
|
-
|
|
758
|
+
const vendorKey = this.config.get('vendorKey');
|
|
759
|
+
const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
|
|
760
|
+
if (!authKey) {
|
|
753
761
|
throw new Error('Authentication required. Run "lanonasis auth login" first.');
|
|
754
762
|
}
|
|
755
763
|
// Map MCP tool names to REST API endpoints
|
|
@@ -805,8 +813,8 @@ export class MCPClient {
|
|
|
805
813
|
method: mapping.method,
|
|
806
814
|
url: `${apiUrl}${endpoint}`,
|
|
807
815
|
headers: {
|
|
808
|
-
'Authorization': `Bearer ${
|
|
809
|
-
'
|
|
816
|
+
'Authorization': `Bearer ${authKey}`,
|
|
817
|
+
'X-API-Key': authKey,
|
|
810
818
|
'Content-Type': 'application/json'
|
|
811
819
|
},
|
|
812
820
|
data: mapping.transform ? mapping.transform(args) : undefined,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lanonasis/cli",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@jest/globals": "^29.7.0",
|
|
47
47
|
"@types/cli-progress": "^3.11.6",
|
|
48
48
|
"@types/inquirer": "^9.0.7",
|
|
49
|
-
"@types/node": "^22.
|
|
49
|
+
"@types/node": "^22.19.3",
|
|
50
50
|
"@types/ws": "^8.5.12",
|
|
51
51
|
"jest": "^29.7.0",
|
|
52
52
|
"rimraf": "^5.0.7",
|