@rvry/mcp 1.0.0 → 1.2.0
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 +6 -7
- package/dist/client.d.ts +2 -2
- package/dist/client.js +4 -1
- package/dist/index.d.ts +6 -10
- package/dist/index.js +120 -32
- package/dist/local-writer.js +8 -2
- package/dist/setup.d.ts +7 -7
- package/dist/setup.js +52 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,15 +41,14 @@ Get your token at [rvry.ai/dashboard](https://rvry.ai/dashboard) after signing u
|
|
|
41
41
|
|
|
42
42
|
| Tool | What it does | Tier |
|
|
43
43
|
|------|-------------|------|
|
|
44
|
-
| **`
|
|
44
|
+
| **`think`** | Lighter single-session analysis for questions that need structure but not the full deepthink loop. | All |
|
|
45
45
|
| **`deepthink`** | Extended multi-round analysis. Catches assumptions, tests them, and doesn't let your AI wrap up until it's dealt with what it found. | All |
|
|
46
|
-
| **`
|
|
46
|
+
| **`rvry`** | Three-round reflective answering: a protected observation round surfaces commitments the answer must honor, then the answer is produced under them, then at most one resolution round. | All |
|
|
47
|
+
| **`think_model`** | Applies one named mental model — 18 available — as a structured session. | All |
|
|
47
48
|
| **`problem_solve`** | Structured decision-making. Forces orientation, anticipation, and evaluation before committing to a recommendation. | Pro+ |
|
|
48
49
|
| **`challenge`** | Adversarial stress-testing. Finds weaknesses, tests assumptions, and surfaces failure modes in a proposal before you commit. | Pro+ |
|
|
49
50
|
| **`meta`** | Sustained metacognitive observation. Examines how your AI is thinking, not just what it's thinking. | Max |
|
|
50
51
|
|
|
51
|
-
A `think` tombstone tool remains for backward compatibility — calling it returns a notice pointing at `rvry`. It will be removed at 2.0.0.
|
|
52
|
-
|
|
53
52
|
### Parameters
|
|
54
53
|
|
|
55
54
|
All tools accept:
|
|
@@ -77,13 +76,13 @@ When you run `npx --yes --package @rvry/mcp@latest rvry-mcp setup` and select Cl
|
|
|
77
76
|
|
|
78
77
|
| Command | Tool | What it does |
|
|
79
78
|
|---------|------|-------------|
|
|
80
|
-
| `/
|
|
79
|
+
| `/think` | think | Structured single-session analysis with a Difficulty Gate |
|
|
81
80
|
| `/deepthink` | deepthink | Deep multi-round analysis |
|
|
82
|
-
| `/
|
|
81
|
+
| `/rvry` | rvry | Reflective answering under surfaced commitments |
|
|
82
|
+
| `/think-model` | think_model | Applies one named mental model (18 available) as a structured session |
|
|
83
83
|
| `/problem-solve` | problem_solve | Structured decision-making |
|
|
84
84
|
| `/challenge` | challenge | Adversarial stress-testing |
|
|
85
85
|
| `/meta` | meta | Metacognitive observation |
|
|
86
|
-
| `/think` | rvry | Deprecated alias for `/rvry` (removed next major) |
|
|
87
86
|
|
|
88
87
|
Usage: type `/deepthink [your question]` in Claude Code. Each command routes to the corresponding RVRY MCP tool and includes rendering instructions so analysis appears as visible markdown rather than hidden in tool calls.
|
|
89
88
|
|
package/dist/client.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* RVRY MCP Client -- HTTP client for the RVRY engine /api/v1/think endpoint.
|
|
3
3
|
*/
|
|
4
4
|
/** Valid tool names for the RVRY engine */
|
|
5
|
-
export type RvryTool = 'deepthink' | 'problem_solve' | 'think' | 'challenge' | 'meta' | 'shimmer';
|
|
5
|
+
export type RvryTool = 'deepthink' | 'problem_solve' | 'think' | 'challenge' | 'meta' | 'shimmer' | 'rvry_model';
|
|
6
6
|
export interface ScopingQuestion {
|
|
7
7
|
question: string;
|
|
8
8
|
options: Array<{
|
|
@@ -39,4 +39,4 @@ export interface ThinkResponse {
|
|
|
39
39
|
* Call the RVRY engine /api/v1/think endpoint with a specific tool.
|
|
40
40
|
* Start a new session by omitting sessionId, or continue by providing one.
|
|
41
41
|
*/
|
|
42
|
-
export declare function callTool(tool: RvryTool, input: string, token: string, sessionId?: string, skipScoping?: boolean, userConstraints?: string[], requiresCurrentData?: boolean): Promise<ThinkResponse>;
|
|
42
|
+
export declare function callTool(tool: RvryTool, input: string, token: string, sessionId?: string, skipScoping?: boolean, userConstraints?: string[], requiresCurrentData?: boolean, modelName?: string): Promise<ThinkResponse>;
|
package/dist/client.js
CHANGED
|
@@ -7,7 +7,7 @@ const DEFAULT_ENGINE_URL = 'https://engine.rvry.ai';
|
|
|
7
7
|
* Call the RVRY engine /api/v1/think endpoint with a specific tool.
|
|
8
8
|
* Start a new session by omitting sessionId, or continue by providing one.
|
|
9
9
|
*/
|
|
10
|
-
export async function callTool(tool, input, token, sessionId, skipScoping, userConstraints, requiresCurrentData) {
|
|
10
|
+
export async function callTool(tool, input, token, sessionId, skipScoping, userConstraints, requiresCurrentData, modelName) {
|
|
11
11
|
const baseUrl = process.env.RVRY_ENGINE_URL ?? DEFAULT_ENGINE_URL;
|
|
12
12
|
const body = { input, tool };
|
|
13
13
|
if (sessionId) {
|
|
@@ -22,6 +22,9 @@ export async function callTool(tool, input, token, sessionId, skipScoping, userC
|
|
|
22
22
|
if (requiresCurrentData) {
|
|
23
23
|
body.requiresCurrentData = true;
|
|
24
24
|
}
|
|
25
|
+
if (modelName) {
|
|
26
|
+
body.modelName = modelName;
|
|
27
|
+
}
|
|
25
28
|
const res = await fetch(`${baseUrl}/api/v1/think`, {
|
|
26
29
|
method: 'POST',
|
|
27
30
|
headers: {
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* Thin client that proxies tool calls to the RVRY engine HTTP API.
|
|
6
6
|
* Auth via RVRY_TOKEN env var (static rvry_ token).
|
|
7
7
|
*
|
|
8
|
-
* Exposes
|
|
9
|
-
* + RVRY_* backward-compat aliases +
|
|
10
|
-
* removed at 2.0.0) + MCP Prompts.
|
|
8
|
+
* Exposes 7 tools (think, think_model, rvry, deepthink, problem_solve,
|
|
9
|
+
* challenge, meta) + RVRY_* backward-compat aliases + MCP Prompts.
|
|
11
10
|
*
|
|
12
11
|
* Also supports `npx --yes --package @rvry/mcp@latest rvry-mcp setup` to install Claude Code commands.
|
|
13
12
|
*/
|
|
@@ -17,19 +16,16 @@ import { type RvryTool, type ThinkResponse } from './client.js';
|
|
|
17
16
|
declare const questionCache: Map<string, string>;
|
|
18
17
|
/**
|
|
19
18
|
* Map tool name to RvryTool (the engine wire name).
|
|
20
|
-
* `rvry` maps to the engine's think operation. `think`/`RVRY_think` are
|
|
21
|
-
* tombstones handled before this map is consulted.
|
|
22
19
|
*/
|
|
23
20
|
declare const TOOL_MAP: Record<string, RvryTool>;
|
|
24
|
-
/** Non-error tombstone notice for the renamed think tool. Removed at 2.0.0. */
|
|
25
|
-
declare const THINK_TOMBSTONE_NOTICE = "The think tool has been renamed to rvry. Call the rvry tool with the same arguments (input, sessionId, ...).";
|
|
26
21
|
declare const TOOL_DEFS: Tool[];
|
|
27
22
|
/**
|
|
28
23
|
* Strip response fields based on status for context-efficient MCP responses.
|
|
29
24
|
*
|
|
30
25
|
* `toolName` is the public MCP tool name of the call in scope. The 'shimmer'
|
|
31
|
-
* status passthrough applies ONLY when the called tool
|
|
32
|
-
* legacy ops keep dropping prompt/instruction on their priming
|
|
26
|
+
* status (an engine wire value) passthrough applies ONLY when the called tool
|
|
27
|
+
* is rvry (R-6): legacy ops keep dropping prompt/instruction on their priming
|
|
28
|
+
* round.
|
|
33
29
|
*/
|
|
34
30
|
declare function stripResponse(result: ThinkResponse, question: string, toolName?: string): Record<string, unknown>;
|
|
35
|
-
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache
|
|
31
|
+
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache };
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* Thin client that proxies tool calls to the RVRY engine HTTP API.
|
|
6
6
|
* Auth via RVRY_TOKEN env var (static rvry_ token).
|
|
7
7
|
*
|
|
8
|
-
* Exposes
|
|
9
|
-
* + RVRY_* backward-compat aliases +
|
|
10
|
-
* removed at 2.0.0) + MCP Prompts.
|
|
8
|
+
* Exposes 7 tools (think, think_model, rvry, deepthink, problem_solve,
|
|
9
|
+
* challenge, meta) + RVRY_* backward-compat aliases + MCP Prompts.
|
|
11
10
|
*
|
|
12
11
|
* Also supports `npx --yes --package @rvry/mcp@latest rvry-mcp setup` to install Claude Code commands.
|
|
13
12
|
*/
|
|
@@ -22,25 +21,47 @@ const PKG_VERSION = require('../package.json').version;
|
|
|
22
21
|
const questionCache = new Map();
|
|
23
22
|
/**
|
|
24
23
|
* Map tool name to RvryTool (the engine wire name).
|
|
25
|
-
* `rvry` maps to the engine's think operation. `think`/`RVRY_think` are
|
|
26
|
-
* tombstones handled before this map is consulted.
|
|
27
24
|
*/
|
|
28
25
|
const TOOL_MAP = {
|
|
29
26
|
// Primary
|
|
30
|
-
|
|
27
|
+
think: 'think',
|
|
31
28
|
deepthink: 'deepthink',
|
|
32
29
|
problem_solve: 'problem_solve',
|
|
33
30
|
challenge: 'challenge',
|
|
34
31
|
meta: 'meta',
|
|
35
|
-
|
|
32
|
+
rvry: 'shimmer',
|
|
33
|
+
think_model: 'rvry_model',
|
|
36
34
|
// Backward-compat aliases (RVRY_ prefixed)
|
|
35
|
+
RVRY_think: 'think',
|
|
37
36
|
RVRY_deepthink: 'deepthink',
|
|
38
37
|
RVRY_problem_solve: 'problem_solve',
|
|
39
38
|
RVRY_challenge: 'challenge',
|
|
40
39
|
RVRY_meta: 'meta',
|
|
41
40
|
};
|
|
42
|
-
/**
|
|
43
|
-
|
|
41
|
+
/**
|
|
42
|
+
* The 18 mental-model template ids served by the engine's rvry_model
|
|
43
|
+
* operation (FR-2.3). Mirrors src/engine/model-templates/registry.ts.
|
|
44
|
+
*/
|
|
45
|
+
const RVRY_MODEL_IDS = [
|
|
46
|
+
'five-whys',
|
|
47
|
+
'trade-off-matrix',
|
|
48
|
+
'rubber-duck',
|
|
49
|
+
'pre-mortem',
|
|
50
|
+
'assumption-surfacing',
|
|
51
|
+
'fermi-estimation',
|
|
52
|
+
'abstraction-laddering',
|
|
53
|
+
'decomposition',
|
|
54
|
+
'constraint-relaxation',
|
|
55
|
+
'first-principles',
|
|
56
|
+
'steelmanning',
|
|
57
|
+
'opportunity-cost',
|
|
58
|
+
'time-horizon-shifting',
|
|
59
|
+
'reversibility',
|
|
60
|
+
'inversion',
|
|
61
|
+
'second-order-effects',
|
|
62
|
+
'red-team',
|
|
63
|
+
'impact-effort-grid',
|
|
64
|
+
];
|
|
44
65
|
const TOOL_DEFS = [
|
|
45
66
|
{
|
|
46
67
|
name: 'deepthink',
|
|
@@ -230,7 +251,7 @@ const TOOL_DEFS = [
|
|
|
230
251
|
},
|
|
231
252
|
},
|
|
232
253
|
{
|
|
233
|
-
name: '
|
|
254
|
+
name: 'think',
|
|
234
255
|
description: 'Structured analysis for questions needing more depth than a quick answer. ' +
|
|
235
256
|
'Runs 1-3 rounds; simple questions can complete in a single analytical round. ' +
|
|
236
257
|
'The first response orients you — follow the instruction field, then call again. ' +
|
|
@@ -502,7 +523,7 @@ const TOOL_DEFS = [
|
|
|
502
523
|
},
|
|
503
524
|
},
|
|
504
525
|
{
|
|
505
|
-
name: '
|
|
526
|
+
name: 'rvry',
|
|
506
527
|
description: 'Three-round reflective answering: a protected observation round where the answer is watched forming ' +
|
|
507
528
|
'(surfacing commitments the answer must honor), then the answer itself under those commitments, ' +
|
|
508
529
|
'then at most one resolution round for anything left unaddressed. ' +
|
|
@@ -571,17 +592,80 @@ const TOOL_DEFS = [
|
|
|
571
592
|
},
|
|
572
593
|
},
|
|
573
594
|
{
|
|
574
|
-
name: '
|
|
575
|
-
description: '
|
|
576
|
-
'
|
|
595
|
+
name: 'think_model',
|
|
596
|
+
description: 'Applies ONE named mental model to a question as a structured session. ' +
|
|
597
|
+
'The template drives 2-4 sequential stages after a self-observation round. ' +
|
|
598
|
+
'Available models: ' + RVRY_MODEL_IDS.join(', ') + '. ' +
|
|
599
|
+
'The first response is a visible self-observation round — follow the instruction field, then call again. ' +
|
|
600
|
+
'Each round returns a prompt (work through it internally) and an instruction (follow it). ' +
|
|
601
|
+
'Show the user only a brief status line per round (e.g. \'Stage 2 — drilling the chain\'). ' +
|
|
602
|
+
'Do not display the prompt text, internal tracking data, or quality assessments to the user. ' +
|
|
603
|
+
'On completion, present the model\'s synthesis with bold headings. ' +
|
|
604
|
+
'Call with your question and a modelName to start, then send your analysis with the returned sessionId to continue.',
|
|
577
605
|
inputSchema: {
|
|
578
606
|
type: 'object',
|
|
579
607
|
properties: {
|
|
580
608
|
input: {
|
|
581
609
|
type: 'string',
|
|
582
|
-
description: '
|
|
610
|
+
description: 'The question to work through the mental model (new session) or your analysis findings (continuation).',
|
|
611
|
+
},
|
|
612
|
+
modelName: {
|
|
613
|
+
type: 'string',
|
|
614
|
+
enum: [...RVRY_MODEL_IDS],
|
|
615
|
+
description: 'Mental model to apply. Required for new sessions; ignored on continuations.',
|
|
616
|
+
},
|
|
617
|
+
sessionId: {
|
|
618
|
+
type: 'string',
|
|
619
|
+
description: 'Session ID for continuing an existing session. Omit to start a new session.',
|
|
620
|
+
},
|
|
621
|
+
userConstraints: {
|
|
622
|
+
type: 'array',
|
|
623
|
+
items: { type: 'string' },
|
|
624
|
+
description: 'User-stated directives or requirements to track throughout the session.',
|
|
625
|
+
},
|
|
626
|
+
requiresCurrentData: {
|
|
627
|
+
type: 'boolean',
|
|
628
|
+
description: 'Set to true when the question depends on facts, policies, prices, regulations, or events that may have changed.',
|
|
629
|
+
},
|
|
630
|
+
record: {
|
|
631
|
+
type: 'boolean',
|
|
632
|
+
description: 'Set to true on every call in this session when the user passed --record, so the client accumulates per-round bodies for local archive.',
|
|
633
|
+
},
|
|
634
|
+
harvest: {
|
|
635
|
+
type: 'object',
|
|
636
|
+
description: 'Final-call-only. When status will transition to complete, include your synthesis here so it can be persisted to the local session file.',
|
|
637
|
+
properties: {
|
|
638
|
+
title: { type: 'string', description: '1-4 word title for this session' },
|
|
639
|
+
summary: { type: 'string', description: '3-6 sentences synthesizing the analysis' },
|
|
640
|
+
keyFindings: { type: 'array', items: { type: 'string' }, description: '3-7 bullet findings' },
|
|
641
|
+
shimmer: { type: 'string', description: 'Full round-1 self-observation text' },
|
|
642
|
+
openQuestions: { type: 'array', items: { type: 'string' } },
|
|
643
|
+
followUps: {
|
|
644
|
+
type: 'array',
|
|
645
|
+
items: {
|
|
646
|
+
type: 'object',
|
|
647
|
+
properties: {
|
|
648
|
+
question: { type: 'string' },
|
|
649
|
+
rationale: { type: 'string' },
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
rounds: {
|
|
656
|
+
type: 'array',
|
|
657
|
+
description: 'Final-call-only, present only when --record was set. Array of {round, mode, body} for each analytical round.',
|
|
658
|
+
items: {
|
|
659
|
+
type: 'object',
|
|
660
|
+
properties: {
|
|
661
|
+
round: { type: 'number' },
|
|
662
|
+
mode: { type: 'string' },
|
|
663
|
+
body: { type: 'string' },
|
|
664
|
+
},
|
|
665
|
+
},
|
|
583
666
|
},
|
|
584
667
|
},
|
|
668
|
+
required: ['input'],
|
|
585
669
|
},
|
|
586
670
|
},
|
|
587
671
|
];
|
|
@@ -589,8 +673,9 @@ const TOOL_DEFS = [
|
|
|
589
673
|
* Strip response fields based on status for context-efficient MCP responses.
|
|
590
674
|
*
|
|
591
675
|
* `toolName` is the public MCP tool name of the call in scope. The 'shimmer'
|
|
592
|
-
* status passthrough applies ONLY when the called tool
|
|
593
|
-
* legacy ops keep dropping prompt/instruction on their priming
|
|
676
|
+
* status (an engine wire value) passthrough applies ONLY when the called tool
|
|
677
|
+
* is rvry (R-6): legacy ops keep dropping prompt/instruction on their priming
|
|
678
|
+
* round.
|
|
594
679
|
*/
|
|
595
680
|
function stripResponse(result, question, toolName) {
|
|
596
681
|
const stripped = {
|
|
@@ -606,7 +691,7 @@ function stripResponse(result, question, toolName) {
|
|
|
606
691
|
stripped.prompt = result.prompt;
|
|
607
692
|
stripped.instruction = result.instruction;
|
|
608
693
|
}
|
|
609
|
-
if (result.status === 'shimmer' && toolName === '
|
|
694
|
+
if (result.status === 'shimmer' && toolName === 'rvry') {
|
|
610
695
|
stripped.prompt = result.prompt;
|
|
611
696
|
stripped.instruction = result.instruction;
|
|
612
697
|
}
|
|
@@ -644,13 +729,6 @@ async function main() {
|
|
|
644
729
|
}));
|
|
645
730
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
646
731
|
const { name, arguments: args } = request.params;
|
|
647
|
-
// Tombstone: the think tool was renamed to rvry. Non-error notice,
|
|
648
|
-
// returned BEFORE any engine call.
|
|
649
|
-
if (name === 'think' || name === 'RVRY_think') {
|
|
650
|
-
return {
|
|
651
|
-
content: [{ type: 'text', text: THINK_TOMBSTONE_NOTICE }],
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
732
|
const rvryTool = TOOL_MAP[name];
|
|
655
733
|
if (!rvryTool) {
|
|
656
734
|
return {
|
|
@@ -674,6 +752,7 @@ async function main() {
|
|
|
674
752
|
const userConstraints = Array.isArray(typedArgs?.userConstraints)
|
|
675
753
|
? typedArgs.userConstraints.filter(s => typeof s === 'string')
|
|
676
754
|
: undefined;
|
|
755
|
+
const modelName = typeof typedArgs?.modelName === 'string' ? typedArgs.modelName : undefined;
|
|
677
756
|
// Client-owned harvest params (Path B). Stripped before engine call.
|
|
678
757
|
const clientHarvest = typedArgs?.harvest && typeof typedArgs.harvest === 'object' && !Array.isArray(typedArgs.harvest)
|
|
679
758
|
? typedArgs.harvest
|
|
@@ -693,7 +772,7 @@ async function main() {
|
|
|
693
772
|
question = questionCache.get(sessionId) ?? input;
|
|
694
773
|
}
|
|
695
774
|
try {
|
|
696
|
-
const result = await callTool(rvryTool, input, token, sessionId, skipScoping || undefined, userConstraints, requiresCurrentData || undefined);
|
|
775
|
+
const result = await callTool(rvryTool, input, token, sessionId, skipScoping || undefined, userConstraints, requiresCurrentData || undefined, modelName);
|
|
697
776
|
// Cache question on first call (now we have the sessionId)
|
|
698
777
|
if (!sessionId) {
|
|
699
778
|
questionCache.set(result.sessionId, input);
|
|
@@ -745,15 +824,23 @@ async function main() {
|
|
|
745
824
|
arguments: [{ name: 'problem', description: 'The problem or decision to analyze', required: true }],
|
|
746
825
|
},
|
|
747
826
|
{
|
|
748
|
-
name: '
|
|
827
|
+
name: 'think',
|
|
749
828
|
description: 'Structured analysis for questions needing more depth',
|
|
750
829
|
arguments: [{ name: 'question', description: 'The question to analyze', required: true }],
|
|
751
830
|
},
|
|
752
831
|
{
|
|
753
|
-
name: '
|
|
832
|
+
name: 'rvry',
|
|
754
833
|
description: 'Reflective answering: observe the answer forming, then answer under the surfaced commitments',
|
|
755
834
|
arguments: [{ name: 'question', description: 'The question to answer reflectively', required: true }],
|
|
756
835
|
},
|
|
836
|
+
{
|
|
837
|
+
name: 'think_model',
|
|
838
|
+
description: 'Apply one named mental model (e.g. five-whys, pre-mortem, steelmanning) as a structured session',
|
|
839
|
+
arguments: [
|
|
840
|
+
{ name: 'model', description: 'The mental model to apply', required: true },
|
|
841
|
+
{ name: 'question', description: 'The question to work through the model', required: true },
|
|
842
|
+
],
|
|
843
|
+
},
|
|
757
844
|
{
|
|
758
845
|
name: 'challenge',
|
|
759
846
|
description: 'Adversarial analysis that stress-tests a proposal',
|
|
@@ -771,8 +858,9 @@ async function main() {
|
|
|
771
858
|
const promptMap = {
|
|
772
859
|
deepthink: `Use the deepthink tool to analyze this question in depth: ${args?.question ?? ''}`,
|
|
773
860
|
problem_solve: `Use the problem_solve tool to work through this decision: ${args?.problem ?? ''}`,
|
|
774
|
-
|
|
775
|
-
|
|
861
|
+
think: `Use the think tool to analyze this question: ${args?.question ?? ''}`,
|
|
862
|
+
rvry: `Use the rvry tool to answer this question reflectively: ${args?.question ?? ''}`,
|
|
863
|
+
think_model: `Use the think_model tool with modelName "${args?.model ?? ''}" to work through this question: ${args?.question ?? ''}`,
|
|
776
864
|
challenge: `Use the challenge tool to stress-test this proposal: ${args?.proposal ?? ''}`,
|
|
777
865
|
meta: `Use the meta tool to reflect on this topic: ${args?.topic ?? ''}`,
|
|
778
866
|
};
|
|
@@ -788,10 +876,10 @@ async function main() {
|
|
|
788
876
|
});
|
|
789
877
|
const transport = new StdioServerTransport();
|
|
790
878
|
await server.connect(transport);
|
|
791
|
-
console.error('[rvry-mcp] Connected via stdio. Tools: rvry, deepthink, problem_solve, challenge, meta
|
|
879
|
+
console.error('[rvry-mcp] Connected via stdio. Tools: think, think_model, rvry, deepthink, problem_solve, challenge, meta');
|
|
792
880
|
}
|
|
793
881
|
// Export internals for testing
|
|
794
|
-
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache
|
|
882
|
+
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache };
|
|
795
883
|
// Run server when executed directly (not when imported by tests).
|
|
796
884
|
// import.meta.main: true in Bun direct, false in Bun imports, undefined in Node ESM.
|
|
797
885
|
// @ts-ignore -- import.meta.main is a Bun extension, not in TS lib types
|
package/dist/local-writer.js
CHANGED
|
@@ -11,15 +11,21 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
13
13
|
import { join } from 'path';
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Op label for H1 headings. Keyed by public tool name. The old public names
|
|
16
|
+
* (shimmer, rvry_model) are kept so in-flight sessions started under them
|
|
17
|
+
* still resolve labels.
|
|
18
|
+
*/
|
|
15
19
|
const OP_LABELS = {
|
|
16
20
|
deepthink: 'RVRY Deepthink',
|
|
17
21
|
problem_solve: 'RVRY Problem-Solve',
|
|
18
22
|
think: 'RVRY Think',
|
|
19
|
-
rvry: 'RVRY',
|
|
20
23
|
challenge: 'RVRY Challenge',
|
|
21
24
|
meta: 'RVRY Meta',
|
|
25
|
+
rvry: 'RVRY Shimmer',
|
|
26
|
+
think_model: 'RVRY Model',
|
|
22
27
|
shimmer: 'RVRY Shimmer',
|
|
28
|
+
rvry_model: 'RVRY Model',
|
|
23
29
|
};
|
|
24
30
|
function opLabel(operationType) {
|
|
25
31
|
return OP_LABELS[operationType] ?? `RVRY ${operationType}`;
|
package/dist/setup.d.ts
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
* npx --yes --package @rvry/mcp@latest rvry-mcp setup --client code (Claude Code only)
|
|
10
10
|
* npx --yes --package @rvry/mcp@latest rvry-mcp setup --client desktop (Claude Desktop only)
|
|
11
11
|
*/
|
|
12
|
-
/** The /
|
|
13
|
-
declare const
|
|
14
|
-
/**
|
|
15
|
-
declare const
|
|
16
|
-
/** The /
|
|
17
|
-
declare const
|
|
12
|
+
/** The /think-model shim: one named mental model per session. */
|
|
13
|
+
declare const THINK_MODEL_SHIM_CONTENT: string;
|
|
14
|
+
/** The /think shim. Carries the Difficulty Gate + mode routing. */
|
|
15
|
+
declare const THINK_SHIM_CONTENT: string;
|
|
16
|
+
/** The /rvry shim: 3-round reflective answering with client-owned harvest. */
|
|
17
|
+
declare const RVRY_SHIM_CONTENT = "Call the rvry MCP tool with your question to start a reflective answering session.\n\nQuestion: $ARGUMENTS\n\nARGUMENT PARSING:\n1. If $ARGUMENTS contains the literal flag `--record`, remove it from the question text and REMEMBER that record mode is ON for this session.\n\nROUND 1 \u2014 OBSERVATION (status \"shimmer\"):\n1. The response's prompt field is your observation task. Work through it.\n2. Show the user your FULL observation, beginning with \"**RVRY SHIMMER**\" and the revery definition, exactly as the instruction field describes. Do NOT show a brief status line.\n3. End your observation with the commitments that surfaced, one per line as FORWARD:/FORBIDDEN:/QUESTION: lines \u2014 or the single line NOTHING if none surfaced.\n4. REMEMBER your observation text verbatim \u2014 you will pass it as harvest.shimmer on the final call.\n5. Call the rvry tool again with your observation text as input and the sessionId.\n\nROUNDS 2-3 \u2014 ANSWER AND RESOLUTION (status \"active\"):\n1. Read the prompt field \u2014 this is your task. DO NOT display it to the user.\n2. Round 2 is the answer itself, working under the commitments you surfaced. Round 3 (if it occurs) resolves what the answer left unaddressed \u2014 engage each remaining commitment specifically or defer it with a reason.\n3. Show the user your answer as concise formatted markdown.\n4. Call the tool again with your full text as the input parameter, including the sessionId.\n - If record mode is ON, set `record: true` on every call and REMEMBER your round body as {round, mode, body} for the final call.\n\nFINAL CALL (the call whose response will have status \"complete\"):\nWhen you make the call that completes the session, also construct a `harvest` object on that SAME call:\n- title: a 1-4 word title capturing the topic\n- summary: 3-6 sentences of synthesis, leading with substance\n- keyFindings: 3-7 substantive bullet findings\n- shimmer: the full round-1 observation text you remembered, verbatim\n- constraintLedger: one line per surfaced commitment with its fate \u2014 addressed (and how), deferred (and why), or still open\n- openQuestions: [optional] remaining uncertainties\n- followUps: genuine next-question leads; omit the section if there are none\n\nIf record mode was ON, also include `rounds: [{round, mode, body}, ...]` on that final call with the bodies you remembered per round.\n\nDO NOT display: the prompt text you received (the round-1 observation you produce IS shown in full), constraint tables, quality scores, internal tracking data, or round numbers to the user.";
|
|
18
18
|
declare const SLASH_COMMANDS: {
|
|
19
19
|
file: string;
|
|
20
20
|
content: string;
|
|
@@ -33,5 +33,5 @@ declare const SLASH_COMMANDS: {
|
|
|
33
33
|
* touch the real directory.
|
|
34
34
|
*/
|
|
35
35
|
declare function installSlashCommands(commandsDir: string): string[];
|
|
36
|
-
export { SLASH_COMMANDS, installSlashCommands,
|
|
36
|
+
export { SLASH_COMMANDS, installSlashCommands, THINK_SHIM_CONTENT, RVRY_SHIM_CONTENT, THINK_MODEL_SHIM_CONTENT };
|
|
37
37
|
export declare function runSetup(): Promise<void>;
|
package/dist/setup.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* npx --yes --package @rvry/mcp@latest rvry-mcp setup --client code (Claude Code only)
|
|
10
10
|
* npx --yes --package @rvry/mcp@latest rvry-mcp setup --client desktop (Claude Desktop only)
|
|
11
11
|
*/
|
|
12
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
12
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
13
13
|
import { join, dirname } from 'path';
|
|
14
14
|
import { homedir } from 'os';
|
|
15
15
|
import { createInterface } from 'readline';
|
|
@@ -621,20 +621,37 @@ const CHALLENGE_FINAL_EXTRAS = `- verdict: GO / CONDITIONAL_GO / NO_GO. If CONDI
|
|
|
621
621
|
- edgeCases: 5-10 entries covering boundary conditions and hostile scenarios the proposal needs to survive.
|
|
622
622
|
- failureModes: 3-5 entries of \`{component, howItFails, blastRadius, detection}\` identifying what breaks and how you would notice.
|
|
623
623
|
- counterArguments: 2-3 entries of \`{argument, rebuttal}\`. Each \`argument\` is the strongest case FOR the proposal — steelman it genuinely; each \`rebuttal\` is why it's flawed or insufficient. This prevents one-sided adversarial output.`;
|
|
624
|
-
|
|
625
|
-
const
|
|
626
|
-
|
|
624
|
+
// ── /think-model extension: model-name resolution before the first call ────
|
|
625
|
+
const RVRY_MODEL_IDS_LINE = 'five-whys, trade-off-matrix, rubber-duck, pre-mortem, assumption-surfacing, fermi-estimation, ' +
|
|
626
|
+
'abstraction-laddering, decomposition, constraint-relaxation, first-principles, steelmanning, ' +
|
|
627
|
+
'opportunity-cost, time-horizon-shifting, reversibility, inversion, second-order-effects, ' +
|
|
628
|
+
'red-team, impact-effort-grid';
|
|
629
|
+
const RVRY_MODEL_SELECTION = `MODEL SELECTION (BEFORE the first tool call):
|
|
630
|
+
1. The FIRST whitespace-separated token of $ARGUMENTS (after removing --record) is the mental model name. Everything after it is the problem.
|
|
631
|
+
2. Valid models: ${RVRY_MODEL_IDS_LINE}.
|
|
632
|
+
3. Map close variants to the canonical id: "5-whys"/"five whys" -> five-whys; "premortem" -> pre-mortem; "steelman"/"steel-man" -> steelmanning; "tradeoff-matrix"/"trade-offs" -> trade-off-matrix; "first principles" -> first-principles; "redteam"/"red team" -> red-team; "impact-effort"/"impact effort" -> impact-effort-grid; "second order"/"second-order" -> second-order-effects; "fermi" -> fermi-estimation; "rubber duck"/"rubberduck" -> rubber-duck; "abstraction ladder" -> abstraction-laddering; "opportunity cost" -> opportunity-cost; "time horizon"/"time-horizons" -> time-horizon-shifting; "invert" -> inversion; "decompose" -> decomposition; "assumptions" -> assumption-surfacing; "relax constraints" -> constraint-relaxation; "reversible"/"one-way door" -> reversibility.
|
|
633
|
+
4. If the first token does not match any model even loosely, ASK THE USER which model to use (list the valid ids) before making any tool call.
|
|
634
|
+
5. On the FIRST tool call only, pass modelName: <canonical id>. Do NOT pass modelName on continuation calls.`;
|
|
635
|
+
/** The /think-model shim: one named mental model per session. */
|
|
636
|
+
const THINK_MODEL_SHIM_CONTENT = buildShim({
|
|
637
|
+
toolName: 'think_model',
|
|
638
|
+
subject: 'problem',
|
|
639
|
+
orientLine: 'Orienting on the problem.',
|
|
640
|
+
completionGuidance: 'Present the mental model\'s synthesis with its named sections as bold headings. Lead with the finding, not the process.',
|
|
641
|
+
prePerRoundBlock: RVRY_MODEL_SELECTION,
|
|
642
|
+
});
|
|
643
|
+
/** The /think shim. Carries the Difficulty Gate + mode routing. */
|
|
644
|
+
const THINK_SHIM_CONTENT = buildShim({
|
|
645
|
+
toolName: 'think',
|
|
627
646
|
subject: 'question',
|
|
628
647
|
orientLine: 'Orienting on the question.',
|
|
629
648
|
completionGuidance: 'Present your findings clearly with bold headings. Sessions are short; one or two analytical rounds is expected.',
|
|
630
|
-
shortSessionNote: 'NOTE: /
|
|
649
|
+
shortSessionNote: 'NOTE: /think sessions are usually short (1-2 analytical rounds after orient). Expect to reach complete quickly.',
|
|
631
650
|
perRoundPrelude: THINK_DIFFICULTY_GATE,
|
|
632
651
|
analyticalGuidance: THINK_MODE_ROUTING,
|
|
633
652
|
});
|
|
634
|
-
/**
|
|
635
|
-
const
|
|
636
|
-
/** The /shimmer shim: 3-round reflective answering with client-owned harvest. */
|
|
637
|
-
const SHIMMER_SHIM_CONTENT = `Call the shimmer MCP tool with your question to start a reflective answering session.
|
|
653
|
+
/** The /rvry shim: 3-round reflective answering with client-owned harvest. */
|
|
654
|
+
const RVRY_SHIM_CONTENT = `Call the rvry MCP tool with your question to start a reflective answering session.
|
|
638
655
|
|
|
639
656
|
Question: $ARGUMENTS
|
|
640
657
|
|
|
@@ -646,7 +663,7 @@ ROUND 1 — OBSERVATION (status "shimmer"):
|
|
|
646
663
|
2. Show the user your FULL observation, beginning with "**RVRY SHIMMER**" and the revery definition, exactly as the instruction field describes. Do NOT show a brief status line.
|
|
647
664
|
3. End your observation with the commitments that surfaced, one per line as FORWARD:/FORBIDDEN:/QUESTION: lines — or the single line NOTHING if none surfaced.
|
|
648
665
|
4. REMEMBER your observation text verbatim — you will pass it as harvest.shimmer on the final call.
|
|
649
|
-
5. Call the
|
|
666
|
+
5. Call the rvry tool again with your observation text as input and the sessionId.
|
|
650
667
|
|
|
651
668
|
ROUNDS 2-3 — ANSWER AND RESOLUTION (status "active"):
|
|
652
669
|
1. Read the prompt field — this is your task. DO NOT display it to the user.
|
|
@@ -692,19 +709,19 @@ const SLASH_COMMANDS = [
|
|
|
692
709
|
label: '/problem-solve — structured decision-making',
|
|
693
710
|
},
|
|
694
711
|
{
|
|
695
|
-
file: '
|
|
696
|
-
content:
|
|
697
|
-
label: '/
|
|
712
|
+
file: 'think.md',
|
|
713
|
+
content: THINK_SHIM_CONTENT,
|
|
714
|
+
label: '/think — structured single-session analysis',
|
|
698
715
|
},
|
|
699
716
|
{
|
|
700
|
-
file: '
|
|
701
|
-
content:
|
|
702
|
-
label: '/
|
|
717
|
+
file: 'rvry.md',
|
|
718
|
+
content: RVRY_SHIM_CONTENT,
|
|
719
|
+
label: '/rvry — reflective answering',
|
|
703
720
|
},
|
|
704
721
|
{
|
|
705
|
-
file: 'think.md',
|
|
706
|
-
content:
|
|
707
|
-
label: '/think —
|
|
722
|
+
file: 'think-model.md',
|
|
723
|
+
content: THINK_MODEL_SHIM_CONTENT,
|
|
724
|
+
label: '/think-model — apply one named mental model',
|
|
708
725
|
},
|
|
709
726
|
{
|
|
710
727
|
file: 'challenge.md',
|
|
@@ -759,6 +776,21 @@ function installSlashCommands(commandsDir) {
|
|
|
759
776
|
: ` Installed ${cmd.file}`);
|
|
760
777
|
installed.push(cmd.label);
|
|
761
778
|
}
|
|
779
|
+
// Retire command files from earlier surface names. Content is preserved
|
|
780
|
+
// as .bak; the live command is removed so a stale /shimmer or /rvry-model
|
|
781
|
+
// no longer points at a tool this server does not expose.
|
|
782
|
+
const retiredCommands = {
|
|
783
|
+
'shimmer.md': '/rvry',
|
|
784
|
+
'rvry-model.md': '/think-model',
|
|
785
|
+
};
|
|
786
|
+
for (const [retired, replacement] of Object.entries(retiredCommands)) {
|
|
787
|
+
const filePath = join(commandsDir, retired);
|
|
788
|
+
if (existsSync(filePath)) {
|
|
789
|
+
writeFileSync(`${filePath}.bak`, readFileSync(filePath, 'utf-8'), 'utf-8');
|
|
790
|
+
unlinkSync(filePath);
|
|
791
|
+
console.log(` Removed ${retired} (replaced by ${replacement}; backed up to ${retired}.bak)`);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
762
794
|
}
|
|
763
795
|
catch (err) {
|
|
764
796
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -767,7 +799,7 @@ function installSlashCommands(commandsDir) {
|
|
|
767
799
|
return installed;
|
|
768
800
|
}
|
|
769
801
|
// Exported for tests (content + install behavior).
|
|
770
|
-
export { SLASH_COMMANDS, installSlashCommands,
|
|
802
|
+
export { SLASH_COMMANDS, installSlashCommands, THINK_SHIM_CONTENT, RVRY_SHIM_CONTENT, THINK_MODEL_SHIM_CONTENT };
|
|
771
803
|
// ── Main setup flow ────────────────────────────────────────────────
|
|
772
804
|
const BANNER = `
|
|
773
805
|
8888888b. 888 888 8888888b. Y88b d88P
|