@rvry/mcp 0.1.0 → 0.1.1

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 CHANGED
@@ -6,27 +6,36 @@ RVRY is a structural constraint system that forces Large Language Models past th
6
6
 
7
7
  ## Quick Start
8
8
 
9
- The setup wizard handles everything -- token configuration, Claude Code registration, and slash command installation:
10
-
11
9
  ```bash
12
10
  npx @rvry/mcp setup
13
11
  ```
14
12
 
15
13
  The wizard will:
16
- 1. Prompt for your RVRY token (hidden input) -- or open rvry.ai/dashboard to generate one
17
- 2. Register RVRY as an MCP server in Claude Code (`-s user` scope)
18
- 3. Install slash commands (`/deepthink`, `/problem-solve`) to `.claude/commands/`
14
+ 1. Open your browser to sign in (or prompt for a token)
15
+ 2. Auto-detect Claude Code and Claude Desktop on your machine
16
+ 3. Configure both clients automatically
17
+ 4. Install slash commands (`/deepthink`, `/problem-solve`)
18
+
19
+ That's it. Restart Claude Desktop if it was running, and RVRY is ready.
20
+
21
+ ### Options
22
+
23
+ ```bash
24
+ npx @rvry/mcp setup --token rvry_abc123 # Skip browser auth, use token directly
25
+ npx @rvry/mcp setup --client code # Only configure Claude Code
26
+ npx @rvry/mcp setup --client desktop # Only configure Claude Desktop
27
+ ```
19
28
 
20
29
  ### Manual Installation
21
30
 
22
- If you prefer to configure manually, or the `claude` CLI is not available:
31
+ If you prefer to configure manually:
23
32
 
33
+ **Claude Code:**
24
34
  ```bash
25
35
  claude mcp add -e RVRY_TOKEN=rvry_your_token -s user rvry -- npx @rvry/mcp
26
36
  ```
27
37
 
28
- Or add the following to your Claude Desktop `claude_desktop_config.json`:
29
-
38
+ **Claude Desktop** (`claude_desktop_config.json`):
30
39
  ```json
31
40
  {
32
41
  "mcpServers": {
@@ -41,12 +50,10 @@ Or add the following to your Claude Desktop `claude_desktop_config.json`:
41
50
  }
42
51
  ```
43
52
 
44
- ## Configuration
45
-
46
- RVRY requires an API token to communicate with the reasoning engine.
47
-
48
- 1. Generate a token at [rvry.ai/dashboard](https://rvry.ai/dashboard).
49
- 2. The setup wizard sets `RVRY_TOKEN` automatically. For manual setup, set it in your MCP config.
53
+ Config file locations:
54
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
55
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
56
+ - Linux: `~/.config/Claude/claude_desktop_config.json`
50
57
 
51
58
  ## Tools Provided
52
59
 
package/dist/setup.d.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  /**
2
2
  * @rvry/mcp setup wizard
3
3
  *
4
- * Interactive setup: token input, Claude Code MCP registration, slash command installation.
4
+ * Interactive setup: device auth flow (browser-based) or manual token paste.
5
+ * Auto-detects Claude Code CLI and Claude Desktop, configures both.
6
+ *
5
7
  * Usage: npx @rvry/mcp setup
8
+ * npx @rvry/mcp setup --token <value>
9
+ * npx @rvry/mcp setup --client code (Claude Code only)
10
+ * npx @rvry/mcp setup --client desktop (Claude Desktop only)
6
11
  */
7
12
  export declare function runSetup(): Promise<void>;
package/dist/setup.js CHANGED
@@ -1,19 +1,36 @@
1
1
  /**
2
2
  * @rvry/mcp setup wizard
3
3
  *
4
- * Interactive setup: token input, Claude Code MCP registration, slash command installation.
4
+ * Interactive setup: device auth flow (browser-based) or manual token paste.
5
+ * Auto-detects Claude Code CLI and Claude Desktop, configures both.
6
+ *
5
7
  * Usage: npx @rvry/mcp setup
8
+ * npx @rvry/mcp setup --token <value>
9
+ * npx @rvry/mcp setup --client code (Claude Code only)
10
+ * npx @rvry/mcp setup --client desktop (Claude Desktop only)
6
11
  */
7
12
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
8
13
  import { join, dirname } from 'path';
14
+ import { homedir } from 'os';
9
15
  import { createInterface } from 'readline';
10
16
  import { execSync } from 'child_process';
11
17
  import { platform } from 'os';
18
+ const ENGINE_URL = 'https://engine.rvry.ai';
12
19
  const COMMAND_FILES = [
13
20
  'deepthink.md',
14
21
  'problem-solve.md',
15
22
  ];
16
23
  const TOKEN_REGEX = /^rvry_[0-9a-f]{32,}$/;
24
+ /** Polling interval for device auth: 3 seconds */
25
+ const POLL_INTERVAL_MS = 3000;
26
+ /** Max polling duration: 10 minutes */
27
+ const POLL_TIMEOUT_MS = 10 * 60 * 1000;
28
+ /** RVRY MCP server config block (reused across Desktop + manual output) */
29
+ const RVRY_SERVER_ENTRY = (token) => ({
30
+ command: 'npx',
31
+ args: ['@rvry/mcp'],
32
+ env: { RVRY_TOKEN: token },
33
+ });
17
34
  // ── Utility functions ──────────────────────────────────────────────
18
35
  /**
19
36
  * Find the commands directory shipped with this package.
@@ -140,6 +157,7 @@ function maskToken(token) {
140
157
  }
141
158
  /**
142
159
  * Open a URL in the default browser, platform-aware.
160
+ * Returns true if the browser was opened successfully, false otherwise.
143
161
  */
144
162
  function openBrowser(url) {
145
163
  const plat = platform();
@@ -153,11 +171,10 @@ function openBrowser(url) {
153
171
  else {
154
172
  execSync(`xdg-open "${url}"`, { stdio: 'pipe' });
155
173
  }
174
+ return true;
156
175
  }
157
176
  catch {
158
- // Non-fatal: browser open failed
159
- console.log(' Could not open browser automatically.');
160
- console.log(` Visit: ${url}`);
177
+ return false;
161
178
  }
162
179
  }
163
180
  /**
@@ -173,11 +190,83 @@ function isClaudeCLIAvailable() {
173
190
  return false;
174
191
  }
175
192
  }
193
+ /**
194
+ * Get the platform-specific Claude Desktop config file path.
195
+ */
196
+ function getDesktopConfigPath() {
197
+ const plat = platform();
198
+ if (plat === 'darwin') {
199
+ return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
200
+ }
201
+ else if (plat === 'win32') {
202
+ return join(process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
203
+ }
204
+ return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
205
+ }
206
+ /**
207
+ * Check if Claude Desktop config directory exists (app is installed).
208
+ */
209
+ function isClaudeDesktopInstalled() {
210
+ const configPath = getDesktopConfigPath();
211
+ const configDir = dirname(configPath);
212
+ return existsSync(configDir);
213
+ }
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
+ function configureDesktop(token) {
220
+ const configPath = getDesktopConfigPath();
221
+ try {
222
+ let config = {};
223
+ if (existsSync(configPath)) {
224
+ const raw = readFileSync(configPath, 'utf-8');
225
+ try {
226
+ config = JSON.parse(raw);
227
+ }
228
+ catch {
229
+ console.log(` Warning: ${configPath} contains invalid JSON.`);
230
+ console.log(' Creating a backup and writing fresh config.');
231
+ writeFileSync(configPath + '.backup', raw, 'utf-8');
232
+ config = {};
233
+ }
234
+ }
235
+ // Ensure mcpServers object exists
236
+ if (!config.mcpServers || typeof config.mcpServers !== 'object') {
237
+ config.mcpServers = {};
238
+ }
239
+ const servers = config.mcpServers;
240
+ const newEntry = RVRY_SERVER_ENTRY(token);
241
+ // Check if RVRY is already configured with the same token
242
+ const existing = servers.RVRY;
243
+ if (existing) {
244
+ const existingEnv = existing.env;
245
+ if (existingEnv?.RVRY_TOKEN === token) {
246
+ return 'unchanged';
247
+ }
248
+ }
249
+ const wasNew = !existing;
250
+ servers.RVRY = newEntry;
251
+ // Write config with clean formatting
252
+ const configDir = dirname(configPath);
253
+ if (!existsSync(configDir)) {
254
+ mkdirSync(configDir, { recursive: true });
255
+ }
256
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
257
+ return wasNew ? 'created' : 'updated';
258
+ }
259
+ catch (err) {
260
+ const msg = err instanceof Error ? err.message : String(err);
261
+ console.log(` Error writing Desktop config: ${msg}`);
262
+ return 'error';
263
+ }
264
+ }
176
265
  /**
177
266
  * Register RVRY as an MCP server in Claude Code.
178
267
  * Removes existing registration first for idempotency.
179
268
  */
180
- function registerMCP(token) {
269
+ function registerClaudeCode(token) {
181
270
  try {
182
271
  // Remove existing (ignore error if not registered)
183
272
  try {
@@ -195,40 +284,124 @@ function registerMCP(token) {
195
284
  }
196
285
  }
197
286
  /**
198
- * Print manual JSON config block for users without the Claude CLI.
287
+ * Verify token by hitting the engine /api/usage endpoint.
288
+ * Returns tier info on success, null on failure.
289
+ */
290
+ async function verifyToken(token) {
291
+ try {
292
+ const res = await fetch(`${ENGINE_URL}/api/usage`, {
293
+ headers: { 'Authorization': `Bearer ${token}` },
294
+ });
295
+ if (!res.ok)
296
+ return null;
297
+ const data = await res.json();
298
+ return data;
299
+ }
300
+ catch {
301
+ return null;
302
+ }
303
+ }
304
+ /**
305
+ * Sleep for a given number of milliseconds.
306
+ */
307
+ function sleep(ms) {
308
+ return new Promise((resolve) => setTimeout(resolve, ms));
309
+ }
310
+ // ── Spinner animation ──────────────────────────────────────────────
311
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
312
+ /**
313
+ * Create a spinner that animates in the terminal.
314
+ * Returns start/stop controls.
199
315
  */
200
- function printManualConfig(token) {
201
- const config = {
202
- mcpServers: {
203
- RVRY: {
204
- command: 'npx',
205
- args: ['@rvry/mcp'],
206
- env: {
207
- RVRY_TOKEN: token,
208
- },
209
- },
316
+ function createSpinner(message) {
317
+ let frameIndex = 0;
318
+ let timer = null;
319
+ return {
320
+ start() {
321
+ process.stdout.write(` ${SPINNER_FRAMES[0]} ${message}`);
322
+ timer = setInterval(() => {
323
+ frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
324
+ process.stdout.write(`\r ${SPINNER_FRAMES[frameIndex]} ${message}`);
325
+ }, 80);
326
+ },
327
+ stop(finalMessage) {
328
+ if (timer) {
329
+ clearInterval(timer);
330
+ timer = null;
331
+ }
332
+ process.stdout.write('\r' + ' '.repeat(message.length + 10) + '\r');
333
+ if (finalMessage) {
334
+ console.log(` ${finalMessage}`);
335
+ }
210
336
  },
211
337
  };
212
- console.log('');
213
- console.log(' Claude CLI not found. Add this to your MCP config manually:');
214
- console.log('');
215
- console.log(JSON.stringify(config, null, 2));
216
- console.log('');
217
- const plat = platform();
218
- if (plat === 'darwin') {
219
- console.log(' Claude Desktop config location:');
220
- console.log(' ~/Library/Application Support/Claude/claude_desktop_config.json');
338
+ }
339
+ // ── Device auth flow ───────────────────────────────────────────────
340
+ /**
341
+ * Device authorization flow: open browser, poll for token.
342
+ * Returns the token on success, or null on failure/timeout.
343
+ */
344
+ async function deviceAuthFlow() {
345
+ // Step 1: Request a device code from the engine
346
+ let deviceCode;
347
+ let verificationUrl;
348
+ try {
349
+ const res = await fetch(`${ENGINE_URL}/api/device/start`, { method: 'POST' });
350
+ if (!res.ok) {
351
+ const body = await res.json().catch(() => ({ error: 'Unknown error' }));
352
+ console.log(` Could not start device auth: ${body.error ?? res.statusText}`);
353
+ return null;
354
+ }
355
+ const data = await res.json();
356
+ deviceCode = data.device_code;
357
+ verificationUrl = data.verification_url;
221
358
  }
222
- else if (plat === 'win32') {
223
- console.log(' Claude Desktop config location:');
224
- console.log(' %APPDATA%\\Claude\\claude_desktop_config.json');
359
+ catch (err) {
360
+ console.log(' Could not connect to RVRY engine. Is engine.rvry.ai reachable?');
361
+ return null;
362
+ }
363
+ // Step 2: Open browser
364
+ console.log('');
365
+ const browserOpened = openBrowser(verificationUrl);
366
+ if (browserOpened) {
367
+ console.log(' Browser opened. Complete sign-in to continue.');
225
368
  }
226
369
  else {
227
- console.log(' Claude Desktop config location:');
228
- console.log(' ~/.config/Claude/claude_desktop_config.json');
370
+ console.log(' Could not open browser automatically.');
371
+ console.log(` Visit: ${verificationUrl}`);
372
+ }
373
+ console.log('');
374
+ // Step 3: Poll for token
375
+ const spinner = createSpinner('Waiting for login in browser...');
376
+ spinner.start();
377
+ const startTime = Date.now();
378
+ while (Date.now() - startTime < POLL_TIMEOUT_MS) {
379
+ await sleep(POLL_INTERVAL_MS);
380
+ try {
381
+ const res = await fetch(`${ENGINE_URL}/api/device/${deviceCode}/token`);
382
+ if (!res.ok) {
383
+ spinner.stop('Polling error. Falling back to manual token entry.');
384
+ return null;
385
+ }
386
+ const data = await res.json();
387
+ if (data.status === 'complete' && data.token) {
388
+ spinner.stop('Login successful!');
389
+ return { token: data.token, warning: data.warning };
390
+ }
391
+ if (data.status === 'expired') {
392
+ spinner.stop('Device code expired.');
393
+ return null;
394
+ }
395
+ // status === 'pending' — keep polling
396
+ }
397
+ catch {
398
+ // Network error during poll — keep trying
399
+ }
229
400
  }
401
+ spinner.stop('Timed out waiting for login.');
402
+ return null;
230
403
  }
231
- // ── Token input flow ───────────────────────────────────────────────
404
+ // ── Manual token input flow ────────────────────────────────────────
232
405
  async function getToken() {
233
406
  while (true) {
234
407
  const token = (await readHiddenInput(' Enter your RVRY token: ')).trim();
@@ -281,57 +454,181 @@ async function installCommands() {
281
454
  }
282
455
  // ── Main setup flow ────────────────────────────────────────────────
283
456
  const BANNER = `
284
- ░█████████ ░██ ░██ ░█████████ ░██ ░██
285
- ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██
286
- ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██
287
- ░█████████ ░██ ░██ ░█████████ ░████
288
- ░██ ░██ ░██ ░██ ░██ ░██ ░██
289
- ░██ ░██ ░██░██ ░██ ░██ ░██
290
- ░██ ░██ ░███ ░██ ░██ ░██
457
+ _____ __ __ _____ __ __
458
+ | __ \\\\ \\\\ / /| __ \\\\ \\\\ / /
459
+ | |__) |\\\\ \\\\ / / | |__) |\\\\ \\\\_/ /
460
+ | _ / \\\\ \\\\/ / | _ / \\\\ /
461
+ | | \\\\ \\\\ \\\\ / | | \\\\ \\\\ | |
462
+ |_| \\\\_\\\\ \\\\/ |_| \\\\_\\\\ |_|
291
463
  `;
292
464
  export async function runSetup() {
293
465
  console.log(BANNER);
294
466
  console.log('Setup');
295
467
  console.log('');
296
- // Step 1: Token input
297
- console.log('[1/3] Token');
298
- const token = await getToken();
468
+ // Parse flags
469
+ const tokenFlagIndex = process.argv.indexOf('--token');
470
+ const clientFlagIndex = process.argv.indexOf('--client');
471
+ const clientFilter = clientFlagIndex !== -1 ? process.argv[clientFlagIndex + 1] : null;
472
+ // ── Step 1: Authentication ──────────────────────────────────────
473
+ let token = null;
474
+ let warning;
475
+ if (tokenFlagIndex !== -1 && process.argv[tokenFlagIndex + 1]) {
476
+ const flagValue = process.argv[tokenFlagIndex + 1];
477
+ if (!isValidToken(flagValue)) {
478
+ console.log(' Invalid token format. Expected: rvry_ followed by 32+ hex characters.');
479
+ process.exit(1);
480
+ }
481
+ token = flagValue;
482
+ console.log('[1/4] Authentication (from --token flag)');
483
+ console.log(` Token: ${maskToken(token)}`);
484
+ }
485
+ else {
486
+ console.log('[1/4] Authentication');
487
+ console.log(' Opening browser for sign-in...');
488
+ const result = await deviceAuthFlow();
489
+ if (result) {
490
+ token = result.token;
491
+ warning = result.warning;
492
+ console.log(` Token: ${maskToken(token)}`);
493
+ if (warning) {
494
+ console.log(` Warning: ${warning}`);
495
+ }
496
+ }
497
+ else {
498
+ console.log('');
499
+ console.log(' Falling back to manual token entry.');
500
+ console.log(' Generate a token at https://rvry.ai/dashboard');
501
+ console.log('');
502
+ token = await getToken();
503
+ }
504
+ }
505
+ // Verify token against engine
506
+ const spinner = createSpinner('Verifying token...');
507
+ spinner.start();
508
+ const usage = await verifyToken(token);
509
+ if (usage) {
510
+ spinner.stop(`Verified. Plan: ${usage.tier} (${usage.used}/${usage.limit} sessions used)`);
511
+ }
512
+ else {
513
+ spinner.stop('Could not verify token (engine may be unreachable). Continuing anyway.');
514
+ }
515
+ console.log('');
516
+ // ── Step 2: Detect clients ──────────────────────────────────────
517
+ console.log('[2/4] Detecting Claude clients');
518
+ const hasClaudeCode = isClaudeCLIAvailable();
519
+ const hasDesktop = isClaudeDesktopInstalled();
520
+ const desktopConfigPath = getDesktopConfigPath();
521
+ const wantCode = !clientFilter || clientFilter === 'code';
522
+ const wantDesktop = !clientFilter || clientFilter === 'desktop';
523
+ if (hasClaudeCode && wantCode) {
524
+ console.log(' Found: Claude Code (claude CLI)');
525
+ }
526
+ if (hasDesktop && wantDesktop) {
527
+ console.log(` Found: Claude Desktop (${desktopConfigPath})`);
528
+ }
529
+ if (!hasClaudeCode && !hasDesktop) {
530
+ console.log(' No Claude clients detected.');
531
+ }
299
532
  console.log('');
300
- // Step 2: Claude Code MCP registration
301
- console.log('[2/3] Claude Code MCP Registration');
302
- let claudeConfigured = false;
303
- if (isClaudeCLIAvailable()) {
304
- const success = registerMCP(token);
533
+ // ── Step 3: Configure clients ───────────────────────────────────
534
+ console.log('[3/4] Client Configuration');
535
+ let codeConfigured = false;
536
+ let desktopConfigured = 'skipped';
537
+ let neitherConfigured = true;
538
+ // Claude Code
539
+ if (hasClaudeCode && wantCode) {
540
+ const success = registerClaudeCode(token);
305
541
  if (success) {
306
- claudeConfigured = true;
307
- console.log(' Registered RVRY in Claude Code (user scope).');
542
+ codeConfigured = true;
543
+ neitherConfigured = false;
544
+ console.log(' Claude Code: Registered (user scope -- works in all projects)');
308
545
  }
309
546
  else {
310
- console.log(' Failed to register with Claude CLI.');
311
- printManualConfig(token);
547
+ console.log(' Claude Code: Failed to register via CLI');
312
548
  }
313
549
  }
314
- else {
315
- printManualConfig(token);
550
+ else if (wantCode && !hasClaudeCode) {
551
+ console.log(' Claude Code: CLI not found (install: https://docs.anthropic.com/en/docs/claude-code)');
552
+ }
553
+ // Claude Desktop
554
+ if (hasDesktop && wantDesktop) {
555
+ desktopConfigured = configureDesktop(token);
556
+ switch (desktopConfigured) {
557
+ case 'created':
558
+ neitherConfigured = false;
559
+ console.log(' Claude Desktop: Added RVRY to config');
560
+ break;
561
+ case 'updated':
562
+ neitherConfigured = false;
563
+ console.log(' Claude Desktop: Updated RVRY token in config');
564
+ break;
565
+ case 'unchanged':
566
+ neitherConfigured = false;
567
+ console.log(' Claude Desktop: Already configured with this token');
568
+ break;
569
+ case 'error':
570
+ console.log(' Claude Desktop: Failed to write config (see error above)');
571
+ break;
572
+ }
573
+ }
574
+ else if (wantDesktop && !hasDesktop) {
575
+ console.log(' Claude Desktop: Not installed');
576
+ }
577
+ // Fallback: print manual config if nothing was configured
578
+ if (neitherConfigured) {
579
+ console.log('');
580
+ console.log(' Manual configuration:');
581
+ console.log('');
582
+ console.log(' Option A — Claude Code (if you install it later):');
583
+ console.log(` claude mcp add -e RVRY_TOKEN="${token}" -s user rvry -- npx @rvry/mcp`);
584
+ console.log('');
585
+ console.log(' Option B — Claude Desktop config JSON:');
586
+ const manualConfig = { mcpServers: { RVRY: RVRY_SERVER_ENTRY(token) } };
587
+ console.log(` File: ${desktopConfigPath}`);
588
+ console.log('');
589
+ for (const line of JSON.stringify(manualConfig, null, 2).split('\n')) {
590
+ console.log(` ${line}`);
591
+ }
316
592
  }
317
593
  console.log('');
318
- // Step 3: Slash command installation
319
- console.log('[3/3] Slash Commands');
594
+ // ── Step 4: Slash commands ──────────────────────────────────────
595
+ console.log('[4/4] Slash Commands');
320
596
  const commandCount = await installCommands();
321
597
  if (commandCount > 0) {
322
- console.log(` Installed ${commandCount} commands to .claude/commands/`);
598
+ console.log(` Installed ${commandCount} command${commandCount > 1 ? 's' : ''} to .claude/commands/`);
323
599
  }
324
600
  else {
325
- console.log(' No new commands installed.');
601
+ console.log(' No new commands installed (already up to date).');
326
602
  }
327
603
  console.log('');
328
- // Summary
604
+ // ── Summary ─────────────────────────────────────────────────────
605
+ console.log('─'.repeat(50));
606
+ console.log('');
329
607
  console.log('RVRY Setup Complete');
330
608
  console.log('');
331
- console.log(` Token: ${maskToken(token)}`);
332
- console.log(` Claude Code: ${claudeConfigured ? 'Configured (user scope)' : 'Manual config required'}`);
333
- console.log(` Commands: ${commandCount} installed to .claude/commands/`);
609
+ console.log(` Token: ${maskToken(token)}${usage ? ` (${usage.tier})` : ''}`);
610
+ if (codeConfigured) {
611
+ console.log(' Claude Code: Configured');
612
+ }
613
+ if (desktopConfigured !== 'skipped' && desktopConfigured !== 'error') {
614
+ console.log(' Claude Desktop: Configured');
615
+ }
616
+ console.log(` Commands: ${commandCount} installed`);
334
617
  console.log('');
335
- console.log('Try: /deepthink "your question"');
618
+ // Client-specific next steps
619
+ console.log('Next steps:');
620
+ if (desktopConfigured !== 'skipped' && desktopConfigured !== 'error') {
621
+ console.log(' 1. Restart Claude Desktop for the new MCP server to load');
622
+ console.log(' RVRY tools will appear when Claude needs structured analysis');
623
+ }
624
+ if (codeConfigured) {
625
+ console.log(` ${desktopConfigured !== 'skipped' && desktopConfigured !== 'error' ? '2' : '1'}. In Claude Code, try:`);
626
+ console.log(' /deepthink "your question"');
627
+ console.log(' /problem-solve "your decision"');
628
+ }
629
+ if (!codeConfigured && (desktopConfigured === 'skipped' || desktopConfigured === 'error')) {
630
+ console.log(' 1. Configure a Claude client using the manual instructions above');
631
+ console.log(' 2. Then try: /deepthink "your question"');
632
+ }
336
633
  console.log('');
337
634
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rvry/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "RVRY reasoning depth enforcement (RDE) engine client.",
5
5
  "type": "module",
6
6
  "bin": {