@rvry/mcp 0.1.3 → 0.1.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/index.js +4 -1
- package/dist/setup.js +284 -130
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -13,6 +13,9 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
13
13
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
14
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
15
15
|
import { callTool } from './client.js';
|
|
16
|
+
import { createRequire } from 'module';
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const PKG_VERSION = require('../package.json').version;
|
|
16
19
|
/** Cache original question per session for response enrichment */
|
|
17
20
|
const questionCache = new Map();
|
|
18
21
|
/**
|
|
@@ -198,7 +201,7 @@ async function main() {
|
|
|
198
201
|
console.error('[rvry-mcp] Generate one at https://rvry.ai/dashboard');
|
|
199
202
|
process.exit(1);
|
|
200
203
|
}
|
|
201
|
-
const server = new Server({ name: 'RVRY', version:
|
|
204
|
+
const server = new Server({ name: 'RVRY', version: PKG_VERSION }, { capabilities: { tools: {}, prompts: {} } });
|
|
202
205
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
203
206
|
tools: TOOL_DEFS,
|
|
204
207
|
}));
|
package/dist/setup.js
CHANGED
|
@@ -15,6 +15,9 @@ import { homedir } from 'os';
|
|
|
15
15
|
import { createInterface } from 'readline';
|
|
16
16
|
import { execSync } from 'child_process';
|
|
17
17
|
import { platform } from 'os';
|
|
18
|
+
import { createRequire } from 'module';
|
|
19
|
+
const require = createRequire(import.meta.url);
|
|
20
|
+
const PKG_VERSION = require('../package.json').version;
|
|
18
21
|
const ENGINE_URL = 'https://engine.rvry.ai';
|
|
19
22
|
const COMMAND_FILES = [
|
|
20
23
|
'deepthink.md',
|
|
@@ -177,9 +180,6 @@ function openBrowser(url) {
|
|
|
177
180
|
return false;
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
|
-
/**
|
|
181
|
-
* Check if the `claude` CLI is available in PATH.
|
|
182
|
-
*/
|
|
183
183
|
function isClaudeCLIAvailable() {
|
|
184
184
|
try {
|
|
185
185
|
const cmd = platform() === 'win32' ? 'where claude' : 'which claude';
|
|
@@ -190,9 +190,6 @@ function isClaudeCLIAvailable() {
|
|
|
190
190
|
return false;
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
|
-
/**
|
|
194
|
-
* Get the platform-specific Claude Desktop config file path.
|
|
195
|
-
*/
|
|
196
193
|
function getDesktopConfigPath() {
|
|
197
194
|
const plat = platform();
|
|
198
195
|
if (plat === 'darwin') {
|
|
@@ -203,19 +200,10 @@ function getDesktopConfigPath() {
|
|
|
203
200
|
}
|
|
204
201
|
return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
|
|
205
202
|
}
|
|
206
|
-
/**
|
|
207
|
-
* Check if Claude Desktop config directory exists (app is installed).
|
|
208
|
-
*/
|
|
209
203
|
function isClaudeDesktopInstalled() {
|
|
210
204
|
const configPath = getDesktopConfigPath();
|
|
211
|
-
|
|
212
|
-
return existsSync(configDir);
|
|
205
|
+
return existsSync(dirname(configPath));
|
|
213
206
|
}
|
|
214
|
-
/**
|
|
215
|
-
* Configure Claude Desktop by merging RVRY into the existing config.
|
|
216
|
-
* Creates the config file if it doesn't exist. Preserves other MCP servers.
|
|
217
|
-
* Returns 'created' | 'updated' | 'unchanged' | 'error'.
|
|
218
|
-
*/
|
|
219
207
|
function configureDesktop(token) {
|
|
220
208
|
const configPath = getDesktopConfigPath();
|
|
221
209
|
try {
|
|
@@ -232,29 +220,23 @@ function configureDesktop(token) {
|
|
|
232
220
|
config = {};
|
|
233
221
|
}
|
|
234
222
|
}
|
|
235
|
-
// Ensure mcpServers object exists
|
|
236
223
|
if (!config.mcpServers || typeof config.mcpServers !== 'object') {
|
|
237
224
|
config.mcpServers = {};
|
|
238
225
|
}
|
|
239
226
|
const servers = config.mcpServers;
|
|
240
|
-
const newEntry = RVRY_SERVER_ENTRY(token);
|
|
241
|
-
// Check if RVRY is already configured with the same token
|
|
242
227
|
const existing = servers.RVRY;
|
|
243
228
|
if (existing) {
|
|
244
229
|
const existingEnv = existing.env;
|
|
245
|
-
if (existingEnv?.RVRY_TOKEN === token)
|
|
230
|
+
if (existingEnv?.RVRY_TOKEN === token)
|
|
246
231
|
return 'unchanged';
|
|
247
|
-
}
|
|
248
232
|
}
|
|
249
233
|
const wasNew = !existing;
|
|
250
|
-
servers.RVRY =
|
|
251
|
-
// Write config with clean formatting
|
|
234
|
+
servers.RVRY = RVRY_SERVER_ENTRY(token);
|
|
252
235
|
const configDir = dirname(configPath);
|
|
253
|
-
if (!existsSync(configDir))
|
|
236
|
+
if (!existsSync(configDir))
|
|
254
237
|
mkdirSync(configDir, { recursive: true });
|
|
255
|
-
}
|
|
256
238
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
257
|
-
return wasNew ? '
|
|
239
|
+
return wasNew ? 'ok' : 'updated';
|
|
258
240
|
}
|
|
259
241
|
catch (err) {
|
|
260
242
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -262,27 +244,221 @@ function configureDesktop(token) {
|
|
|
262
244
|
return 'error';
|
|
263
245
|
}
|
|
264
246
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Register RVRY as an MCP server in Claude Code.
|
|
267
|
-
* Removes existing registration first for idempotency.
|
|
268
|
-
*/
|
|
269
247
|
function registerClaudeCode(token) {
|
|
270
248
|
try {
|
|
271
|
-
// Remove existing (ignore error if not registered)
|
|
272
249
|
try {
|
|
273
250
|
execSync('claude mcp remove rvry', { stdio: 'pipe' });
|
|
274
251
|
}
|
|
275
|
-
catch {
|
|
276
|
-
// Not registered yet, that's fine
|
|
277
|
-
}
|
|
278
|
-
// Add with token
|
|
252
|
+
catch { /* not registered */ }
|
|
279
253
|
execSync(`claude mcp add -e RVRY_TOKEN="${token}" -s user rvry -- npx @rvry/mcp`, { stdio: 'inherit' });
|
|
280
|
-
return
|
|
254
|
+
return 'ok';
|
|
281
255
|
}
|
|
282
256
|
catch {
|
|
283
|
-
return
|
|
257
|
+
return 'error';
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Write RVRY server entry into a generic MCP JSON config file.
|
|
262
|
+
* Used by clients that follow the Desktop-style config format (Codex, Gemini, etc.)
|
|
263
|
+
*/
|
|
264
|
+
function configureJsonMcp(configPath, token) {
|
|
265
|
+
try {
|
|
266
|
+
let config = {};
|
|
267
|
+
if (existsSync(configPath)) {
|
|
268
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
269
|
+
try {
|
|
270
|
+
config = JSON.parse(raw);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
writeFileSync(configPath + '.backup', raw, 'utf-8');
|
|
274
|
+
config = {};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!config.mcpServers || typeof config.mcpServers !== 'object') {
|
|
278
|
+
config.mcpServers = {};
|
|
279
|
+
}
|
|
280
|
+
const servers = config.mcpServers;
|
|
281
|
+
const existing = servers.RVRY;
|
|
282
|
+
if (existing) {
|
|
283
|
+
const existingEnv = existing.env;
|
|
284
|
+
if (existingEnv?.RVRY_TOKEN === token)
|
|
285
|
+
return 'unchanged';
|
|
286
|
+
}
|
|
287
|
+
const wasNew = !existing;
|
|
288
|
+
servers.RVRY = RVRY_SERVER_ENTRY(token);
|
|
289
|
+
const dir = dirname(configPath);
|
|
290
|
+
if (!existsSync(dir))
|
|
291
|
+
mkdirSync(dir, { recursive: true });
|
|
292
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
293
|
+
return wasNew ? 'ok' : 'updated';
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
297
|
+
console.log(` Error writing config: ${msg}`);
|
|
298
|
+
return 'error';
|
|
284
299
|
}
|
|
285
300
|
}
|
|
301
|
+
/** All supported clients. Add new clients here. */
|
|
302
|
+
const CLIENT_REGISTRY = [
|
|
303
|
+
{
|
|
304
|
+
name: 'Claude Code',
|
|
305
|
+
id: 'code',
|
|
306
|
+
detect: isClaudeCLIAvailable,
|
|
307
|
+
configure: registerClaudeCode,
|
|
308
|
+
notInstalledHint: 'CLI not found (https://docs.anthropic.com/en/docs/claude-code)',
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'Claude Desktop / Claude Co-Work',
|
|
312
|
+
id: 'desktop',
|
|
313
|
+
detect: isClaudeDesktopInstalled,
|
|
314
|
+
configure: (token) => configureDesktop(token),
|
|
315
|
+
notInstalledHint: 'Not installed',
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: 'Anti-Gravity',
|
|
319
|
+
id: 'antigravity',
|
|
320
|
+
detect: () => {
|
|
321
|
+
// OR-logic: binary (agy or antigravity), config dir, or macOS app bundle
|
|
322
|
+
try {
|
|
323
|
+
const cmd = platform() === 'win32' ? 'where agy' : 'which agy';
|
|
324
|
+
execSync(cmd, { stdio: 'pipe' });
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
catch { /* not on PATH */ }
|
|
328
|
+
if (platform() !== 'win32') {
|
|
329
|
+
try {
|
|
330
|
+
execSync('which antigravity', { stdio: 'pipe' });
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
catch { /* not on PATH */ }
|
|
334
|
+
}
|
|
335
|
+
if (existsSync(join(homedir(), '.gemini', 'antigravity')))
|
|
336
|
+
return true;
|
|
337
|
+
if (platform() === 'darwin' && existsSync('/Applications/Google Antigravity.app'))
|
|
338
|
+
return true;
|
|
339
|
+
return false;
|
|
340
|
+
},
|
|
341
|
+
configure: (token) => configureJsonMcp(join(homedir(), '.gemini', 'antigravity', 'mcp_config.json'), token),
|
|
342
|
+
notInstalledHint: 'Not installed (https://antigravity.google)',
|
|
343
|
+
},
|
|
344
|
+
];
|
|
345
|
+
/**
|
|
346
|
+
* Interactive multi-select picker with arrow keys + space + enter.
|
|
347
|
+
* Returns indices of selected items.
|
|
348
|
+
*/
|
|
349
|
+
function multiSelect(items) {
|
|
350
|
+
return new Promise((resolve) => {
|
|
351
|
+
const stdin = process.stdin;
|
|
352
|
+
const wasRaw = stdin.isRaw;
|
|
353
|
+
if (typeof stdin.setRawMode === 'function')
|
|
354
|
+
stdin.setRawMode(true);
|
|
355
|
+
stdin.resume();
|
|
356
|
+
stdin.setEncoding('utf8');
|
|
357
|
+
let cursor = items.findIndex((i) => i.available);
|
|
358
|
+
if (cursor === -1)
|
|
359
|
+
cursor = 0;
|
|
360
|
+
const render = () => {
|
|
361
|
+
// Move cursor up to overwrite previous render (except first render)
|
|
362
|
+
for (let i = 0; i < items.length; i++) {
|
|
363
|
+
process.stdout.write('\x1b[2K'); // clear line
|
|
364
|
+
if (i < items.length - 1)
|
|
365
|
+
process.stdout.write('\x1b[1A'); // move up
|
|
366
|
+
}
|
|
367
|
+
process.stdout.write('\r');
|
|
368
|
+
for (let i = 0; i < items.length; i++) {
|
|
369
|
+
const item = items[i];
|
|
370
|
+
const pointer = i === cursor ? '›' : ' ';
|
|
371
|
+
const checkbox = !item.available
|
|
372
|
+
? '\x1b[2m[ ]\x1b[0m'
|
|
373
|
+
: item.selected
|
|
374
|
+
? '\x1b[32m[x]\x1b[0m'
|
|
375
|
+
: '[ ]';
|
|
376
|
+
const label = !item.available
|
|
377
|
+
? `\x1b[2m${item.label}\x1b[0m`
|
|
378
|
+
: item.label;
|
|
379
|
+
const hint = !item.available && item.hint
|
|
380
|
+
? ` \x1b[2m${item.hint}\x1b[0m`
|
|
381
|
+
: '';
|
|
382
|
+
process.stdout.write(` ${pointer} ${checkbox} ${label}${hint}`);
|
|
383
|
+
if (i < items.length - 1)
|
|
384
|
+
process.stdout.write('\n');
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
// Initial render: print blank lines then render
|
|
388
|
+
for (let i = 0; i < items.length; i++) {
|
|
389
|
+
process.stdout.write(i < items.length - 1 ? '\n' : '');
|
|
390
|
+
}
|
|
391
|
+
render();
|
|
392
|
+
const cleanup = () => {
|
|
393
|
+
if (typeof stdin.setRawMode === 'function')
|
|
394
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
395
|
+
stdin.removeListener('data', onData);
|
|
396
|
+
stdin.pause();
|
|
397
|
+
};
|
|
398
|
+
const onData = (key) => {
|
|
399
|
+
// Ctrl+C
|
|
400
|
+
if (key === '\x03') {
|
|
401
|
+
cleanup();
|
|
402
|
+
process.stdout.write('\n');
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
// Enter — confirm selection
|
|
406
|
+
if (key === '\r' || key === '\n') {
|
|
407
|
+
cleanup();
|
|
408
|
+
process.stdout.write('\n');
|
|
409
|
+
const selected = [];
|
|
410
|
+
for (let i = 0; i < items.length; i++) {
|
|
411
|
+
if (items[i].selected && items[i].available)
|
|
412
|
+
selected.push(i);
|
|
413
|
+
}
|
|
414
|
+
resolve(selected);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
// Space — toggle current item
|
|
418
|
+
if (key === ' ') {
|
|
419
|
+
if (items[cursor].available) {
|
|
420
|
+
items[cursor].selected = !items[cursor].selected;
|
|
421
|
+
render();
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
// Arrow keys (escape sequences)
|
|
426
|
+
if (key === '\x1b[A' || key === 'k') {
|
|
427
|
+
// Up
|
|
428
|
+
let next = cursor - 1;
|
|
429
|
+
while (next >= 0 && !items[next].available)
|
|
430
|
+
next--;
|
|
431
|
+
if (next >= 0) {
|
|
432
|
+
cursor = next;
|
|
433
|
+
render();
|
|
434
|
+
}
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (key === '\x1b[B' || key === 'j') {
|
|
438
|
+
// Down
|
|
439
|
+
let next = cursor + 1;
|
|
440
|
+
while (next < items.length && !items[next].available)
|
|
441
|
+
next++;
|
|
442
|
+
if (next < items.length) {
|
|
443
|
+
cursor = next;
|
|
444
|
+
render();
|
|
445
|
+
}
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
// 'a' — select all available
|
|
449
|
+
if (key === 'a') {
|
|
450
|
+
const allSelected = items.filter((i) => i.available).every((i) => i.selected);
|
|
451
|
+
for (const item of items) {
|
|
452
|
+
if (item.available)
|
|
453
|
+
item.selected = !allSelected;
|
|
454
|
+
}
|
|
455
|
+
render();
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
stdin.on('data', onData);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
286
462
|
/**
|
|
287
463
|
* Verify token by hitting the engine /api/usage endpoint.
|
|
288
464
|
* Returns tier info on success, null on failure.
|
|
@@ -454,16 +630,18 @@ async function installCommands() {
|
|
|
454
630
|
}
|
|
455
631
|
// ── Main setup flow ────────────────────────────────────────────────
|
|
456
632
|
const BANNER = `
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
633
|
+
8888888b. 888 888 8888888b. Y88b d88P
|
|
634
|
+
888 Y88b 888 888 888 Y88b Y88b d88P
|
|
635
|
+
888 888 888 888 888 888 Y88o88P
|
|
636
|
+
888 d88P Y88b d88P 888 d88P Y888P
|
|
637
|
+
8888888P" Y88b d88P 8888888P" 888
|
|
638
|
+
888 T88b Y88o88P 888 T88b 888
|
|
639
|
+
888 T88b Y888P 888 T88b 888
|
|
640
|
+
888 T88b Y8P 888 T88b 888
|
|
463
641
|
`;
|
|
464
642
|
export async function runSetup() {
|
|
465
643
|
console.log(BANNER);
|
|
466
|
-
console.log(
|
|
644
|
+
console.log(`Setup v${PKG_VERSION}`);
|
|
467
645
|
console.log('');
|
|
468
646
|
// Parse flags
|
|
469
647
|
const tokenFlagIndex = process.argv.indexOf('--token');
|
|
@@ -517,93 +695,68 @@ export async function runSetup() {
|
|
|
517
695
|
}
|
|
518
696
|
console.log('');
|
|
519
697
|
// ── Step 2: Detect clients ──────────────────────────────────────
|
|
520
|
-
console.log('[2/4] Detecting
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
|
|
698
|
+
console.log('[2/4] Detecting clients');
|
|
699
|
+
// Filter registry if --client was passed
|
|
700
|
+
const clients = clientFilter
|
|
701
|
+
? CLIENT_REGISTRY.filter((c) => c.id === clientFilter)
|
|
702
|
+
: CLIENT_REGISTRY;
|
|
703
|
+
const detected = clients.map((c) => ({
|
|
704
|
+
client: c,
|
|
705
|
+
available: c.detect(),
|
|
706
|
+
}));
|
|
707
|
+
const anyDetected = detected.some((d) => d.available);
|
|
708
|
+
for (const d of detected) {
|
|
709
|
+
if (d.available) {
|
|
710
|
+
console.log(` Found: ${d.client.name}`);
|
|
711
|
+
}
|
|
531
712
|
}
|
|
532
|
-
if (!
|
|
533
|
-
console.log(' No
|
|
713
|
+
if (!anyDetected) {
|
|
714
|
+
console.log(' No supported clients detected.');
|
|
534
715
|
}
|
|
535
716
|
console.log('');
|
|
536
717
|
// ── Step 3: Configure clients ───────────────────────────────────
|
|
537
|
-
console.log('[3/4]
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if (hasDesktop && wantDesktop) {
|
|
566
|
-
const rl = createRL();
|
|
567
|
-
const answer = await ask(rl, ' Install for Claude Desktop / Co-Work? [Y/n] ');
|
|
568
|
-
rl.close();
|
|
569
|
-
if (answer.toLowerCase() !== 'n') {
|
|
570
|
-
desktopConfigured = configureDesktop(token);
|
|
571
|
-
switch (desktopConfigured) {
|
|
572
|
-
case 'created':
|
|
573
|
-
neitherConfigured = false;
|
|
574
|
-
console.log(' Claude Desktop: Added RVRY to config');
|
|
575
|
-
break;
|
|
576
|
-
case 'updated':
|
|
577
|
-
neitherConfigured = false;
|
|
578
|
-
console.log(' Claude Desktop: Updated RVRY token in config');
|
|
579
|
-
break;
|
|
580
|
-
case 'unchanged':
|
|
581
|
-
neitherConfigured = false;
|
|
582
|
-
console.log(' Claude Desktop: Already configured with this token');
|
|
583
|
-
break;
|
|
584
|
-
case 'error':
|
|
585
|
-
console.log(' Claude Desktop: Failed to write config (see error above)');
|
|
586
|
-
break;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
console.log(' Claude Desktop: Skipped');
|
|
591
|
-
}
|
|
718
|
+
console.log('[3/4] Select apps to add RVRY MCP configuration');
|
|
719
|
+
console.log(' Use \x1b[1m↑↓\x1b[0m to navigate, \x1b[1mspace\x1b[0m to toggle, \x1b[1ma\x1b[0m to toggle all, \x1b[1menter\x1b[0m to confirm');
|
|
720
|
+
console.log('');
|
|
721
|
+
const pickerItems = detected.map((d) => ({
|
|
722
|
+
label: d.client.name,
|
|
723
|
+
selected: d.available, // pre-select detected clients
|
|
724
|
+
available: d.available,
|
|
725
|
+
hint: d.available ? undefined : d.client.notInstalledHint,
|
|
726
|
+
}));
|
|
727
|
+
const selectedIndices = await multiSelect(pickerItems);
|
|
728
|
+
const configuredClients = [];
|
|
729
|
+
let anyConfigured = false;
|
|
730
|
+
console.log('');
|
|
731
|
+
for (const idx of selectedIndices) {
|
|
732
|
+
const { client } = detected[idx];
|
|
733
|
+
const result = client.configure(token);
|
|
734
|
+
const statusMap = {
|
|
735
|
+
ok: 'Configured',
|
|
736
|
+
updated: 'Updated token',
|
|
737
|
+
unchanged: 'Already configured',
|
|
738
|
+
error: 'Failed',
|
|
739
|
+
};
|
|
740
|
+
const status = statusMap[result] ?? result;
|
|
741
|
+
const icon = result === 'error' ? '✗' : '✓';
|
|
742
|
+
console.log(` ${icon} ${client.name}: ${status}`);
|
|
743
|
+
configuredClients.push({ name: client.name, status });
|
|
744
|
+
if (result !== 'error')
|
|
745
|
+
anyConfigured = true;
|
|
592
746
|
}
|
|
593
|
-
|
|
594
|
-
console.log('
|
|
747
|
+
if (selectedIndices.length === 0) {
|
|
748
|
+
console.log(' No clients selected.');
|
|
595
749
|
}
|
|
596
750
|
// Fallback: print manual config if nothing was configured
|
|
597
|
-
if (
|
|
751
|
+
if (!anyConfigured) {
|
|
598
752
|
console.log('');
|
|
599
753
|
console.log(' Manual configuration:');
|
|
600
754
|
console.log('');
|
|
601
755
|
console.log(' Option A — Claude Code (if you install it later):');
|
|
602
756
|
console.log(` claude mcp add -e RVRY_TOKEN="${token}" -s user rvry -- npx @rvry/mcp`);
|
|
603
757
|
console.log('');
|
|
604
|
-
console.log(' Option B — Claude Desktop
|
|
758
|
+
console.log(' Option B — JSON config (Claude Desktop, Codex, etc.):');
|
|
605
759
|
const manualConfig = { mcpServers: { RVRY: RVRY_SERVER_ENTRY(token) } };
|
|
606
|
-
console.log(` File: ${desktopConfigPath}`);
|
|
607
760
|
console.log('');
|
|
608
761
|
for (const line of JSON.stringify(manualConfig, null, 2).split('\n')) {
|
|
609
762
|
console.log(` ${line}`);
|
|
@@ -626,35 +779,36 @@ export async function runSetup() {
|
|
|
626
779
|
console.log('RVRY Setup Complete');
|
|
627
780
|
console.log('');
|
|
628
781
|
console.log(` Token: ${maskToken(token)}${usage ? ` (${usage.tier})` : ''}`);
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (desktopConfigured !== 'skipped' && desktopConfigured !== 'error') {
|
|
633
|
-
console.log(' Claude Desktop: Configured');
|
|
782
|
+
for (const c of configuredClients) {
|
|
783
|
+
const pad = ' '.repeat(Math.max(1, 16 - c.name.length));
|
|
784
|
+
console.log(` ${c.name}:${pad}${c.status}`);
|
|
634
785
|
}
|
|
635
786
|
console.log(` Commands: ${commandCount} installed`);
|
|
636
787
|
console.log('');
|
|
637
788
|
// Client-specific next steps
|
|
789
|
+
const configuredNames = new Set(configuredClients.map((c) => c.name));
|
|
790
|
+
const hasDesktopStyle = configuredNames.has('Claude Desktop / Claude Co-Work')
|
|
791
|
+
|| configuredNames.has('Anti-Gravity');
|
|
792
|
+
const hasCodeStyle = configuredNames.has('Claude Code');
|
|
638
793
|
console.log('Next steps:');
|
|
639
|
-
const desktopOk = desktopConfigured !== 'skipped' && desktopConfigured !== 'error';
|
|
640
794
|
let step = 1;
|
|
641
|
-
if (
|
|
642
|
-
console.log(` ${step}. Restart
|
|
795
|
+
if (hasDesktopStyle) {
|
|
796
|
+
console.log(` ${step}. Restart desktop apps for the new MCP server to load`);
|
|
643
797
|
step++;
|
|
644
798
|
}
|
|
645
|
-
if (
|
|
799
|
+
if (hasCodeStyle) {
|
|
646
800
|
console.log(` ${step}. In Claude Code, try:`);
|
|
647
801
|
console.log(' /deepthink "your question"');
|
|
648
802
|
console.log(' /problem-solve "your decision"');
|
|
649
803
|
step++;
|
|
650
804
|
}
|
|
651
|
-
if (
|
|
652
|
-
console.log(` ${step}. In
|
|
805
|
+
if (hasDesktopStyle) {
|
|
806
|
+
console.log(` ${step}. In desktop clients, use natural language:`);
|
|
653
807
|
console.log(' "Use deepthink to analyze..." or "Use problem-solve for..."');
|
|
654
808
|
step++;
|
|
655
809
|
}
|
|
656
|
-
if (!
|
|
657
|
-
console.log(' 1. Configure a
|
|
810
|
+
if (!anyConfigured) {
|
|
811
|
+
console.log(' 1. Configure a client using the manual instructions above');
|
|
658
812
|
console.log(' 2. Then try: /deepthink "your question"');
|
|
659
813
|
}
|
|
660
814
|
console.log('');
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rvry/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "RVRY reasoning depth enforcement (RDE) engine client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"rvry-mcp": "
|
|
7
|
+
"rvry-mcp": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"files": [
|