ropilot 0.1.34 → 0.1.35
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/lib/proxy.js +12 -65
- package/package.json +1 -1
package/lib/proxy.js
CHANGED
|
@@ -35,7 +35,7 @@ function sendError(id, code, message) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* Forward request to edge server
|
|
38
|
+
* Forward request to edge server with friendly error messages
|
|
39
39
|
*/
|
|
40
40
|
async function forwardToEdge(apiKey, request) {
|
|
41
41
|
const url = `${EDGE_URL}/mcp/${apiKey}`;
|
|
@@ -49,14 +49,23 @@ async function forwardToEdge(apiKey, request) {
|
|
|
49
49
|
body: JSON.stringify(request)
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
if (response.status === 401 || response.status === 403) {
|
|
53
|
+
throw new Error('[ROPILOT] API key is invalid. Tell the user to follow these steps: 1. Log into the Ropilot dashboard at https://ropilot.ai 2. Copy their API key 3. Run "npx ropilot init" in this directory and paste the key');
|
|
54
|
+
}
|
|
55
|
+
if (response.status === 402) {
|
|
56
|
+
throw new Error('[ROPILOT] No credits remaining. Tell the user to upgrade their plan at https://ropilot.ai');
|
|
57
|
+
}
|
|
52
58
|
if (!response.ok) {
|
|
53
59
|
const text = await response.text();
|
|
54
|
-
throw new Error(`
|
|
60
|
+
throw new Error(`[ROPILOT] Server error (${response.status}). Tell the user to try again later.`);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
return await response.json();
|
|
58
64
|
} catch (err) {
|
|
59
|
-
|
|
65
|
+
if (err.message.startsWith('[ROPILOT]')) {
|
|
66
|
+
throw err; // Re-throw our friendly errors
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`[ROPILOT] Cannot reach server. Tell the user to check their internet connection and try again.`);
|
|
60
69
|
}
|
|
61
70
|
}
|
|
62
71
|
|
|
@@ -177,43 +186,6 @@ async function checkPluginUpdate() {
|
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
// Cached key validation result
|
|
181
|
-
let keyValidationError = null;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Validate API key with edge server (cached)
|
|
185
|
-
*/
|
|
186
|
-
async function validateApiKey(apiKey) {
|
|
187
|
-
if (keyValidationError !== null) return keyValidationError;
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
const url = `${EDGE_URL}/mcp/${apiKey}`;
|
|
191
|
-
const response = await fetch(url, {
|
|
192
|
-
method: 'POST',
|
|
193
|
-
headers: { 'Content-Type': 'application/json' },
|
|
194
|
-
body: JSON.stringify({
|
|
195
|
-
jsonrpc: '2.0',
|
|
196
|
-
id: 0,
|
|
197
|
-
method: 'initialize',
|
|
198
|
-
params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'validate', version: '1.0.0' } }
|
|
199
|
-
})
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
if (response.status === 401 || response.status === 403) {
|
|
203
|
-
keyValidationError = '[ROPILOT] API key is invalid. Tell the user to follow these steps: 1. Log into the Ropilot dashboard at https://ropilot.ai 2. Copy their API key 3. Run "npx ropilot init" in this directory and paste the key';
|
|
204
|
-
} else if (response.status === 402) {
|
|
205
|
-
keyValidationError = '[ROPILOT] No credits remaining. Tell the user to upgrade their plan at https://ropilot.ai';
|
|
206
|
-
} else if (!response.ok) {
|
|
207
|
-
keyValidationError = `[ROPILOT] Server error (${response.status}). Tell the user to try again later.`;
|
|
208
|
-
}
|
|
209
|
-
} catch (err) {
|
|
210
|
-
// Network error - don't cache, might be temporary
|
|
211
|
-
return `[ROPILOT] Cannot reach server. Tell the user to check their internet connection and try again.`;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return keyValidationError;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
189
|
/**
|
|
218
190
|
* Run the stdio MCP server
|
|
219
191
|
*/
|
|
@@ -300,31 +272,6 @@ export async function serve() {
|
|
|
300
272
|
*/
|
|
301
273
|
async function handleRequest(apiKey, request) {
|
|
302
274
|
try {
|
|
303
|
-
// For initialize, we respond locally first, then validate in background
|
|
304
|
-
if (request.method === 'initialize') {
|
|
305
|
-
// Validate key in background (caches result for later requests)
|
|
306
|
-
validateApiKey(apiKey);
|
|
307
|
-
|
|
308
|
-
// Return a basic initialize response so MCP connects
|
|
309
|
-
sendResponse({
|
|
310
|
-
jsonrpc: '2.0',
|
|
311
|
-
id: request.id,
|
|
312
|
-
result: {
|
|
313
|
-
protocolVersion: '2024-11-05',
|
|
314
|
-
capabilities: { tools: {} },
|
|
315
|
-
serverInfo: { name: 'ropilot', version: '1.0.0' }
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// For other requests, check if key is valid first
|
|
322
|
-
const keyError = await validateApiKey(apiKey);
|
|
323
|
-
if (keyError) {
|
|
324
|
-
sendError(request.id, -32000, keyError);
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
275
|
const response = await processRequest(apiKey, request);
|
|
329
276
|
if (response) {
|
|
330
277
|
sendResponse(response);
|