ropilot 0.1.31 → 0.1.33

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.
Files changed (2) hide show
  1. package/lib/proxy.js +64 -2
  2. package/package.json +1 -1
package/lib/proxy.js CHANGED
@@ -177,6 +177,43 @@ async function checkPluginUpdate() {
177
177
  }
178
178
  }
179
179
 
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 = 'Invalid API key. Run "npx ropilot init" to update your key.';
204
+ } else if (response.status === 402) {
205
+ keyValidationError = 'No credits remaining. Upgrade at https://ropilot.ai';
206
+ } else if (!response.ok) {
207
+ keyValidationError = `Ropilot server error (${response.status}). Try again later.`;
208
+ }
209
+ } catch (err) {
210
+ // Network error - don't cache, might be temporary
211
+ return `Cannot reach Ropilot server: ${err.message}`;
212
+ }
213
+
214
+ return keyValidationError;
215
+ }
216
+
180
217
  /**
181
218
  * Run the stdio MCP server
182
219
  */
@@ -184,8 +221,8 @@ export async function serve() {
184
221
  const apiKey = getApiKey();
185
222
 
186
223
  if (!apiKey) {
187
- console.error('No API key configured.');
188
- console.error('Run "npx ropilot init" to set up Ropilot.');
224
+ console.error('[Ropilot] No API key configured.');
225
+ console.error('[Ropilot] Run "npx ropilot init" to set up Ropilot.');
189
226
  process.exit(1);
190
227
  }
191
228
 
@@ -263,6 +300,31 @@ export async function serve() {
263
300
  */
264
301
  async function handleRequest(apiKey, request) {
265
302
  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
+
266
328
  const response = await processRequest(apiKey, request);
267
329
  if (response) {
268
330
  sendResponse(response);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ropilot",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "AI-powered Roblox development assistant - MCP CLI",
5
5
  "author": "whut",
6
6
  "license": "MIT",