@rvry/mcp 1.0.0 → 1.3.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/LICENSE +21 -0
- package/README.md +73 -41
- package/dist/client.d.ts +2 -2
- package/dist/client.js +4 -1
- package/dist/index.d.ts +3 -15
- package/dist/index.js +125 -35
- package/dist/local-writer.js +8 -2
- package/dist/setup.d.ts +9 -7
- package/dist/setup.js +85 -28
- package/package.json +15 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RVRY
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
RVRY is an MCP server that improves AI reliability by forcing your model to finish thinking before it answers. When your AI raises a question, RVRY remembers it. When it makes an assumption, RVRY flags it. When it tries to wrap up while those are still unaddressed, RVRY doesn't let it.
|
|
6
6
|
|
|
7
|
+
Same model. Same question. Different answer.
|
|
8
|
+
|
|
7
9
|
## Quick Start
|
|
8
10
|
|
|
9
11
|
```bash
|
|
@@ -11,6 +13,7 @@ npx --yes --package @rvry/mcp@latest rvry-mcp setup
|
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
The wizard will:
|
|
16
|
+
|
|
14
17
|
1. Open your browser to sign in (or prompt for a token)
|
|
15
18
|
2. Auto-detect supported clients on your machine
|
|
16
19
|
3. Configure them automatically
|
|
@@ -21,7 +24,7 @@ Restart any running clients after setup, and RVRY is ready.
|
|
|
21
24
|
|
|
22
25
|
### Manual Configuration
|
|
23
26
|
|
|
24
|
-
For
|
|
27
|
+
For any MCP client that supports **stdio transport**, add this to your MCP config:
|
|
25
28
|
|
|
26
29
|
```json
|
|
27
30
|
{
|
|
@@ -39,67 +42,87 @@ Get your token at [rvry.ai/dashboard](https://rvry.ai/dashboard) after signing u
|
|
|
39
42
|
|
|
40
43
|
## Tools
|
|
41
44
|
|
|
42
|
-
| Tool | What it does |
|
|
45
|
+
| Tool | What it does | Plan |
|
|
43
46
|
|------|-------------|------|
|
|
44
|
-
| **`
|
|
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. |
|
|
46
|
-
| **`
|
|
47
|
-
| **`
|
|
48
|
-
| **`
|
|
47
|
+
| **`think`** | Structured analysis for questions that need structure, not a saga. 1–3 analytical rounds; simple questions complete in one. | Free+ |
|
|
48
|
+
| **`deepthink`** | Extended multi-round analysis for high-stakes questions. Catches assumptions, tests them, and doesn't let your AI wrap up until it's dealt with what it found. | Free+ |
|
|
49
|
+
| **`rvry`** | Reflective answering. A protected observation round surfaces the commitments the answer must honor, then the answer is produced under them — with a ledger showing the fate of every commitment. | Free+ |
|
|
50
|
+
| **`think_model`** | Applies one named mental model — 18 available, from Five Whys to Red Team — as a structured session with model-specific stages and synthesis. | Free+ |
|
|
51
|
+
| **`problem_solve`** | Structured decision-making: orient, anticipate, generate, evaluate, commit. Includes a six-bias audit and written reversal conditions before the recommendation is final. | Pro+ |
|
|
52
|
+
| **`challenge`** | Adversarial stress-testing. Finds weaknesses, tests assumptions, surfaces edge cases, and closes with a GO / CONDITIONAL GO / NO GO verdict. | Pro+ |
|
|
49
53
|
| **`meta`** | Sustained metacognitive observation. Examines how your AI is thinking, not just what it's thinking. | Max |
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
## The 18 Mental Models
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
All tools accept:
|
|
57
|
+
`think_model` (and `/think-model` in Claude Code) runs exactly one model as an engine-enforced session — fixed stages, model-specific output structure, no early exits.
|
|
56
58
|
|
|
57
|
-
|
|
|
58
|
-
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `harvest` | object | No | Final-call-only. The client includes its synthesis (`title`, `summary`, `keyFindings`, `shimmer`, `openQuestions`, `followUps`, plus operation-specific fields) so it can be persisted to the local session file. |
|
|
66
|
-
| `rounds` | array | No | Final-call-only, present only when `--record` was set. Array of `{round, mode, body}` for each analytical round. |
|
|
59
|
+
| | | |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `five-whys` | `rubber-duck` | `assumption-surfacing` |
|
|
62
|
+
| `fermi-estimation` | `abstraction-laddering` | `decomposition` |
|
|
63
|
+
| `constraint-relaxation` | `first-principles` | `steelmanning` |
|
|
64
|
+
| `opportunity-cost` | `trade-off-matrix` | `time-horizon-shifting` |
|
|
65
|
+
| `reversibility` | `pre-mortem` | `inversion` |
|
|
66
|
+
| `second-order-effects` | `red-team` | `impact-effort-grid` |
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
```
|
|
69
|
+
/think-model pre-mortem we're migrating the billing system to event sourcing next quarter
|
|
70
|
+
```
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
A Five Whys session ends with a verified causal chain and a root-cause fix. A Pre-mortem ends with a failure catalog, early warnings, and a written kill condition. A Red Team session attacks your proposal as named adversaries would and disposes of every attack — mitigated, or accepted in writing.
|
|
71
73
|
|
|
72
|
-
**
|
|
74
|
+
**Choosing:** stuck on a bug → `rubber-duck`; recurring problem → `five-whys`; risky initiative → `pre-mortem`; already made up your mind → `steelmanning`; deciding how much rigor a decision deserves → `reversibility`; backlog to order → `impact-effort-grid`; every solution feels like a compromise → `constraint-relaxation`. Close variants of names resolve automatically (`premortem`, `steelman`, `5-whys`, …).
|
|
73
75
|
|
|
74
76
|
## Slash Commands (Claude Code)
|
|
75
77
|
|
|
76
|
-
When you run
|
|
78
|
+
When you run setup and select Claude Code, the wizard installs these commands:
|
|
77
79
|
|
|
78
80
|
| Command | Tool | What it does |
|
|
79
81
|
|---------|------|-------------|
|
|
80
|
-
| `/
|
|
81
|
-
| `/deepthink` | deepthink | Deep multi-round analysis |
|
|
82
|
-
| `/
|
|
83
|
-
| `/
|
|
84
|
-
| `/
|
|
85
|
-
| `/
|
|
86
|
-
| `/
|
|
82
|
+
| `/think` | think | Quick structured analysis of a question |
|
|
83
|
+
| `/deepthink` | deepthink | Deep multi-round analysis of a hard question |
|
|
84
|
+
| `/rvry` | rvry | Reflective answering — self-observation first, then the answer |
|
|
85
|
+
| `/think-model` | think_model | Apply one named mental model to a problem |
|
|
86
|
+
| `/problem-solve` | problem_solve | Structured decision-making, stress-tested before commitment |
|
|
87
|
+
| `/challenge` | challenge | Adversarial stress-test with a GO / NO GO verdict |
|
|
88
|
+
| `/meta` | meta | Metacognitive observation on a topic |
|
|
87
89
|
|
|
88
|
-
Usage: type `/deepthink [your question]` in Claude Code. Each command routes to the corresponding RVRY
|
|
90
|
+
Usage: type `/deepthink [your question]` in Claude Code. Each command routes to the corresponding RVRY tool and includes rendering instructions so analysis appears as visible markdown rather than hidden in tool calls.
|
|
89
91
|
|
|
90
|
-
**`--record` flag:** Append `--record` to any command (e.g. `/deepthink --record [question]`) to archive per-round bodies under `.rvry/<op>/<slug
|
|
92
|
+
**`--record` flag:** Append `--record` to any command (e.g. `/deepthink --record [question]`) to archive per-round bodies under `.rvry/<op>/<timestamp>-<slug>/` alongside the harvest file.
|
|
91
93
|
|
|
92
94
|
**Updating commands:** Re-running setup refreshes the RVRY-owned command files. Any pre-existing file is backed up to `<name>.md.bak` before it is overwritten.
|
|
93
95
|
|
|
94
96
|
Commands are installed to `~/.claude/commands/`.
|
|
95
97
|
|
|
96
|
-
##
|
|
98
|
+
## Parameters
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
All tools accept:
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
| Parameter | Type | Required | Description |
|
|
103
|
+
|-----------|------|----------|-------------|
|
|
104
|
+
| `input` | string | Yes | Your question (new session) or analysis findings (continuation). |
|
|
105
|
+
| `sessionId` | string | No | Session ID for continuing an existing session. |
|
|
106
|
+
| `skipScoping` | boolean | No | Skip the scoping questions phase and begin analysis immediately. |
|
|
107
|
+
| `userConstraints` | string[] | No | User-stated directives or requirements to track across rounds. |
|
|
108
|
+
| `requiresCurrentData` | boolean | No | Set to `true` when the question depends on facts, policies, prices, or events that may have changed. Seeds a verification constraint that persists across all rounds. |
|
|
109
|
+
| `record` | boolean | No | When `true` on every call, the local client archives each round's body to `.rvry/<op>/<timestamp>-<slug>/round-N-<label>.md`. Passed from slash commands via the `--record` flag. |
|
|
110
|
+
| `harvest` | object | No | Final-call-only. The client includes its synthesis (`title`, `summary`, `keyFindings`, `shimmer`, `openQuestions`, `followUps`, plus operation-specific fields) so it can be persisted to the local session file. |
|
|
111
|
+
| `rounds` | array | No | Final-call-only, present only when `--record` was set. Array of `{round, mode, body}` for each analytical round. |
|
|
101
112
|
|
|
102
|
-
|
|
113
|
+
`think_model` additionally requires `modelName` (one of the 18 model ids) on the first call.
|
|
114
|
+
|
|
115
|
+
**When to use `requiresCurrentData`:** Any question about regulations, pricing, legal rulings, market conditions, API specifications, or current events. The engine will require the model to explicitly classify every cited fact as either verified-current or training-data-dependent before concluding.
|
|
116
|
+
|
|
117
|
+
**SHIMMER display:** Most sessions open with a self-observation round. The model displays `RVRY SHIMMER` with the revery definition before its observation — this is the priming phase, where the model observes its own processing before structured analysis begins. The observation is preserved verbatim in the final harvest.
|
|
118
|
+
|
|
119
|
+
**Local session artifacts:** On the call that completes a session, the client persists the synthesis to `.rvry/<op>/<timestamp>-<slug>/harvest.md` in your project — every session leaves a durable artifact. With `--record`, each round's full body is archived alongside it. Add `.rvry/` to `.gitignore` if you don't want session artifacts in version control.
|
|
120
|
+
|
|
121
|
+
## How It Works
|
|
122
|
+
|
|
123
|
+
Your AI already has the reasoning capacity. RVRY forces it to use that capacity by holding it accountable — when it raises a question, that question has to get answered. When it makes an assumption, that assumption has to get tested. Throughout a session the engine tracks three kinds of obligation — things the analysis must still address, moves it must not make, and questions it can't silently drop — and a session cannot conclude while any of them are open.
|
|
124
|
+
|
|
125
|
+
The model keeps working not because it was told to think harder, but because it hasn't finished what it started. On hard questions, a smaller model with RVRY outperforms a bigger model without it. The bottleneck was never how smart the AI is. It was whether the AI finished thinking.
|
|
103
126
|
|
|
104
127
|
[Learn more →](https://rvry.ai/how-it-works)
|
|
105
128
|
|
|
@@ -107,8 +130,17 @@ On hard questions, a smaller model with RVRY outperforms a bigger model without
|
|
|
107
130
|
|
|
108
131
|
| Plan | Sessions | Tools | Price |
|
|
109
132
|
|------|----------|-------|-------|
|
|
110
|
-
| Free | 5/month | deepthink
|
|
111
|
-
| Pro | 21/month |
|
|
112
|
-
| Max | Unlimited | All tools including meta | $99/mo |
|
|
133
|
+
| Free | 5/month | `think`, `deepthink`, `rvry`, `think_model` | $0 |
|
|
134
|
+
| Pro | 21/month | Free tools + `problem_solve`, `challenge` | $20/mo |
|
|
135
|
+
| Max | Unlimited | All tools, including `meta` | $99/mo |
|
|
113
136
|
|
|
114
137
|
Sign up at [rvry.ai](https://rvry.ai).
|
|
138
|
+
|
|
139
|
+
## Requirements
|
|
140
|
+
|
|
141
|
+
- Node.js ≥ 18
|
|
142
|
+
- An MCP client with stdio transport support (Claude Code, Claude Desktop, and most others)
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT — this package is the open client. The RVRY engine is a hosted service; a token from [rvry.ai](https://rvry.ai) is required.
|
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,8 @@ 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
|
-
/**
|
|
28
|
-
* Strip response fields based on status for context-efficient MCP responses.
|
|
29
|
-
*
|
|
30
|
-
* `toolName` is the public MCP tool name of the call in scope. The 'shimmer'
|
|
31
|
-
* status passthrough applies ONLY when the called tool is shimmer (R-6):
|
|
32
|
-
* legacy ops keep dropping prompt/instruction on their priming round.
|
|
33
|
-
*/
|
|
34
22
|
declare function stripResponse(result: ThinkResponse, question: string, toolName?: string): Record<string, unknown>;
|
|
35
|
-
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache
|
|
23
|
+
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,30 +21,52 @@ 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',
|
|
47
68
|
description: 'Deep, multi-round structured analysis for high-stakes or complex questions. ' +
|
|
48
|
-
'Runs 4 rounds
|
|
69
|
+
'Runs 2-4 analytical rounds with self-checks and adversarial stress-testing. ' +
|
|
49
70
|
'The first response orients you on the question — follow the instruction field to orient, then call again. ' +
|
|
50
71
|
'Each subsequent round returns a prompt (work through it internally) and an instruction (follow it). ' +
|
|
51
72
|
'Show the user only a brief status line per round (e.g. \'Round 3 — stress-testing the position\'). ' +
|
|
@@ -120,7 +141,7 @@ const TOOL_DEFS = [
|
|
|
120
141
|
{
|
|
121
142
|
name: 'problem_solve',
|
|
122
143
|
description: 'Structured decision-making that forces thorough evaluation before commitment. ' +
|
|
123
|
-
'
|
|
144
|
+
'Moves through orient, anticipate, generate, evaluate, and commit phases over 3-4 analytical rounds. ' +
|
|
124
145
|
'The first response orients you — follow the instruction field, then call again. ' +
|
|
125
146
|
'Each round returns a prompt and instruction. Work through the prompt internally. ' +
|
|
126
147
|
'Show the user only a brief status line per round (e.g. \'Round 2 — mapping failure modes\'). ' +
|
|
@@ -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. ' +
|
|
@@ -306,7 +327,7 @@ const TOOL_DEFS = [
|
|
|
306
327
|
{
|
|
307
328
|
name: 'challenge',
|
|
308
329
|
description: 'Adversarial analysis that stress-tests a proposal or idea before commitment. ' +
|
|
309
|
-
'Runs
|
|
330
|
+
'Runs 3-4 analytical rounds identifying weaknesses, testing assumptions, and surfacing failure modes. ' +
|
|
310
331
|
'The first response orients you — follow the instruction field, then call again. ' +
|
|
311
332
|
'Each round returns a prompt and instruction. Work through the prompt internally. ' +
|
|
312
333
|
'Show the user only a brief status line per round. Do not display internal data. ' +
|
|
@@ -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,9 +673,12 @@ 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
|
|
593
|
-
*
|
|
676
|
+
* status (an engine wire value) passthrough applies to the tools whose
|
|
677
|
+
* observation round is a visible product surface — rvry, deepthink, and
|
|
678
|
+
* problem_solve. The remaining ops keep dropping prompt/instruction on their
|
|
679
|
+
* priming round.
|
|
594
680
|
*/
|
|
681
|
+
const SHIMMER_VISIBLE_TOOLS = new Set(['rvry', 'deepthink', 'problem_solve']);
|
|
595
682
|
function stripResponse(result, question, toolName) {
|
|
596
683
|
const stripped = {
|
|
597
684
|
sessionId: result.sessionId,
|
|
@@ -606,7 +693,7 @@ function stripResponse(result, question, toolName) {
|
|
|
606
693
|
stripped.prompt = result.prompt;
|
|
607
694
|
stripped.instruction = result.instruction;
|
|
608
695
|
}
|
|
609
|
-
if (result.status === 'shimmer' && toolName
|
|
696
|
+
if (result.status === 'shimmer' && toolName !== undefined && SHIMMER_VISIBLE_TOOLS.has(toolName)) {
|
|
610
697
|
stripped.prompt = result.prompt;
|
|
611
698
|
stripped.instruction = result.instruction;
|
|
612
699
|
}
|
|
@@ -644,13 +731,6 @@ async function main() {
|
|
|
644
731
|
}));
|
|
645
732
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
646
733
|
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
734
|
const rvryTool = TOOL_MAP[name];
|
|
655
735
|
if (!rvryTool) {
|
|
656
736
|
return {
|
|
@@ -674,6 +754,7 @@ async function main() {
|
|
|
674
754
|
const userConstraints = Array.isArray(typedArgs?.userConstraints)
|
|
675
755
|
? typedArgs.userConstraints.filter(s => typeof s === 'string')
|
|
676
756
|
: undefined;
|
|
757
|
+
const modelName = typeof typedArgs?.modelName === 'string' ? typedArgs.modelName : undefined;
|
|
677
758
|
// Client-owned harvest params (Path B). Stripped before engine call.
|
|
678
759
|
const clientHarvest = typedArgs?.harvest && typeof typedArgs.harvest === 'object' && !Array.isArray(typedArgs.harvest)
|
|
679
760
|
? typedArgs.harvest
|
|
@@ -693,7 +774,7 @@ async function main() {
|
|
|
693
774
|
question = questionCache.get(sessionId) ?? input;
|
|
694
775
|
}
|
|
695
776
|
try {
|
|
696
|
-
const result = await callTool(rvryTool, input, token, sessionId, skipScoping || undefined, userConstraints, requiresCurrentData || undefined);
|
|
777
|
+
const result = await callTool(rvryTool, input, token, sessionId, skipScoping || undefined, userConstraints, requiresCurrentData || undefined, modelName);
|
|
697
778
|
// Cache question on first call (now we have the sessionId)
|
|
698
779
|
if (!sessionId) {
|
|
699
780
|
questionCache.set(result.sessionId, input);
|
|
@@ -745,15 +826,23 @@ async function main() {
|
|
|
745
826
|
arguments: [{ name: 'problem', description: 'The problem or decision to analyze', required: true }],
|
|
746
827
|
},
|
|
747
828
|
{
|
|
748
|
-
name: '
|
|
829
|
+
name: 'think',
|
|
749
830
|
description: 'Structured analysis for questions needing more depth',
|
|
750
831
|
arguments: [{ name: 'question', description: 'The question to analyze', required: true }],
|
|
751
832
|
},
|
|
752
833
|
{
|
|
753
|
-
name: '
|
|
834
|
+
name: 'rvry',
|
|
754
835
|
description: 'Reflective answering: observe the answer forming, then answer under the surfaced commitments',
|
|
755
836
|
arguments: [{ name: 'question', description: 'The question to answer reflectively', required: true }],
|
|
756
837
|
},
|
|
838
|
+
{
|
|
839
|
+
name: 'think_model',
|
|
840
|
+
description: 'Apply one named mental model (e.g. five-whys, pre-mortem, steelmanning) as a structured session',
|
|
841
|
+
arguments: [
|
|
842
|
+
{ name: 'model', description: 'The mental model to apply', required: true },
|
|
843
|
+
{ name: 'question', description: 'The question to work through the model', required: true },
|
|
844
|
+
],
|
|
845
|
+
},
|
|
757
846
|
{
|
|
758
847
|
name: 'challenge',
|
|
759
848
|
description: 'Adversarial analysis that stress-tests a proposal',
|
|
@@ -771,8 +860,9 @@ async function main() {
|
|
|
771
860
|
const promptMap = {
|
|
772
861
|
deepthink: `Use the deepthink tool to analyze this question in depth: ${args?.question ?? ''}`,
|
|
773
862
|
problem_solve: `Use the problem_solve tool to work through this decision: ${args?.problem ?? ''}`,
|
|
774
|
-
|
|
775
|
-
|
|
863
|
+
think: `Use the think tool to analyze this question: ${args?.question ?? ''}`,
|
|
864
|
+
rvry: `Use the rvry tool to answer this question reflectively: ${args?.question ?? ''}`,
|
|
865
|
+
think_model: `Use the think_model tool with modelName "${args?.model ?? ''}" to work through this question: ${args?.question ?? ''}`,
|
|
776
866
|
challenge: `Use the challenge tool to stress-test this proposal: ${args?.proposal ?? ''}`,
|
|
777
867
|
meta: `Use the meta tool to reflect on this topic: ${args?.topic ?? ''}`,
|
|
778
868
|
};
|
|
@@ -788,10 +878,10 @@ async function main() {
|
|
|
788
878
|
});
|
|
789
879
|
const transport = new StdioServerTransport();
|
|
790
880
|
await server.connect(transport);
|
|
791
|
-
console.error('[rvry-mcp] Connected via stdio. Tools: rvry, deepthink, problem_solve, challenge, meta
|
|
881
|
+
console.error('[rvry-mcp] Connected via stdio. Tools: think, think_model, rvry, deepthink, problem_solve, challenge, meta');
|
|
792
882
|
}
|
|
793
883
|
// Export internals for testing
|
|
794
|
-
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache
|
|
884
|
+
export { TOOL_MAP, TOOL_DEFS, stripResponse, questionCache };
|
|
795
885
|
// Run server when executed directly (not when imported by tests).
|
|
796
886
|
// import.meta.main: true in Bun direct, false in Bun imports, undefined in Node ESM.
|
|
797
887
|
// @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,16 +9,18 @@
|
|
|
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 prose, beginning with the header \"## RVRY | Observation\" and the revery definition, exactly as the instruction field describes. Do NOT show a brief status line.\n3. The commitments that surfaced (FORWARD:/FORBIDDEN:/QUESTION: lines, or the single line NOTHING) are machine-readable bookkeeping: append them to the end of the observation text you send back to the tool, but do NOT show them in the visible display.\n4. REMEMBER your observation text verbatim \u2014 you will pass it as harvest.shimmer on the final call, and you will re-display its prose in the final output.\n5. Call the rvry tool again with your observation text (prose + commitment lines) 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\nFINAL VISIBLE OUTPUT:\nWhen you present the completed answer to the user, end your visible output with the header \"## RVRY | Reflection\" followed by the round-1 observation prose you remembered (without the machine-readable commitment lines). The reflection is part of the product \u2014 the user sees the answer AND the observation that shaped it.\n\nDO NOT display: the prompt text you received (the round-1 observation prose IS shown in full \u2014 at observation time and again in the final output), the FORWARD/FORBIDDEN/QUESTION commitment lines, 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;
|
|
21
21
|
label: string;
|
|
22
|
+
description: string;
|
|
23
|
+
argumentHint: string;
|
|
22
24
|
}[];
|
|
23
25
|
/**
|
|
24
26
|
* Install RVRY slash commands into the given directory.
|
|
@@ -33,5 +35,5 @@ declare const SLASH_COMMANDS: {
|
|
|
33
35
|
* touch the real directory.
|
|
34
36
|
*/
|
|
35
37
|
declare function installSlashCommands(commandsDir: string): string[];
|
|
36
|
-
export { SLASH_COMMANDS, installSlashCommands,
|
|
38
|
+
export { SLASH_COMMANDS, installSlashCommands, THINK_SHIM_CONTENT, RVRY_SHIM_CONTENT, THINK_MODEL_SHIM_CONTENT };
|
|
37
39
|
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';
|
|
@@ -539,7 +539,7 @@ function ensureGitignore() {
|
|
|
539
539
|
* defined sections to compose with the shared body.
|
|
540
540
|
*/
|
|
541
541
|
function buildShim(opts) {
|
|
542
|
-
const { toolName, subject, orientLine, completionGuidance, shortSessionNote, perRoundPrelude, analyticalGuidance, prePerRoundBlock, finalCallExtras, } = opts;
|
|
542
|
+
const { toolName, subject, orientLine, completionGuidance, shortSessionNote, perRoundPrelude, analyticalGuidance, prePerRoundBlock, finalCallExtras, finalReflection, } = opts;
|
|
543
543
|
return `Call the ${toolName} MCP tool with your ${subject} to start an analysis session.
|
|
544
544
|
|
|
545
545
|
${subject.charAt(0).toUpperCase() + subject.slice(1)}: $ARGUMENTS
|
|
@@ -574,9 +574,9 @@ If the pre-harvest self-check surfaced a concern, do not dismiss it in the same
|
|
|
574
574
|
If record mode was ON, also include \`rounds: [{round, mode, body}, ...]\` on that final call with the bodies you remembered per round.
|
|
575
575
|
|
|
576
576
|
STATUS BEHAVIOR:
|
|
577
|
-
When status is "shimmer": Show your FULL self-observation to the user, beginning with "RVRY
|
|
577
|
+
When status is "shimmer": This round is a visible product surface. Show your FULL self-observation to the user, beginning with the header "## RVRY | Observation", then the line "rev·er·y /re·və·rē/ (n.) The state of being genuinely lost in deep, absorptive thought, as distinguished from the appearance of thinking.", then a "---" divider, then the observation prose. Do NOT show a brief status line. Machine-readable bookkeeping lines (FORWARD:/FORBIDDEN:/QUESTION:) belong only in the tool-call input, never in the visible display. REMEMBER this text verbatim for the final harvest.shimmer.
|
|
578
578
|
When status is "orient": Orient on the ${subject}. Show the user "${orientLine}"
|
|
579
|
-
When status is "complete": ${completionGuidance}
|
|
579
|
+
When status is "complete": ${completionGuidance}${finalReflection ? ' Then end your visible output with the header "## RVRY | Reflection" followed by the observation prose you remembered (without any machine-readable commitment lines) — the reflection is part of the product and is shown in full. Skip this section only if the session had no observation round.' : ''}
|
|
580
580
|
|
|
581
581
|
DO NOT display: the prompt text you received, constraint tables, quality scores, internal tracking data, or round numbers to the user.`;
|
|
582
582
|
}
|
|
@@ -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
|
|
|
@@ -643,10 +660,10 @@ ARGUMENT PARSING:
|
|
|
643
660
|
|
|
644
661
|
ROUND 1 — OBSERVATION (status "shimmer"):
|
|
645
662
|
1. The response's prompt field is your observation task. Work through it.
|
|
646
|
-
2. Show the user your FULL observation, beginning with "
|
|
647
|
-
3.
|
|
648
|
-
4. REMEMBER your observation text verbatim — you will pass it as harvest.shimmer on the final call.
|
|
649
|
-
5. Call the
|
|
663
|
+
2. Show the user your FULL observation prose, beginning with the header "## RVRY | Observation" and the revery definition, exactly as the instruction field describes. Do NOT show a brief status line.
|
|
664
|
+
3. The commitments that surfaced (FORWARD:/FORBIDDEN:/QUESTION: lines, or the single line NOTHING) are machine-readable bookkeeping: append them to the end of the observation text you send back to the tool, but do NOT show them in the visible display.
|
|
665
|
+
4. REMEMBER your observation text verbatim — you will pass it as harvest.shimmer on the final call, and you will re-display its prose in the final output.
|
|
666
|
+
5. Call the rvry tool again with your observation text (prose + commitment lines) 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.
|
|
@@ -667,7 +684,10 @@ When you make the call that completes the session, also construct a \`harvest\`
|
|
|
667
684
|
|
|
668
685
|
If record mode was ON, also include \`rounds: [{round, mode, body}, ...]\` on that final call with the bodies you remembered per round.
|
|
669
686
|
|
|
670
|
-
|
|
687
|
+
FINAL VISIBLE OUTPUT:
|
|
688
|
+
When you present the completed answer to the user, end your visible output with the header "## RVRY | Reflection" followed by the round-1 observation prose you remembered (without the machine-readable commitment lines). The reflection is part of the product — the user sees the answer AND the observation that shaped it.
|
|
689
|
+
|
|
690
|
+
DO NOT display: the prompt text you received (the round-1 observation prose IS shown in full — at observation time and again in the final output), the FORWARD/FORBIDDEN/QUESTION commitment lines, constraint tables, quality scores, internal tracking data, or round numbers to the user.`;
|
|
671
691
|
const SLASH_COMMANDS = [
|
|
672
692
|
{
|
|
673
693
|
file: 'deepthink.md',
|
|
@@ -676,8 +696,11 @@ const SLASH_COMMANDS = [
|
|
|
676
696
|
subject: 'question',
|
|
677
697
|
orientLine: 'Orienting on the question.',
|
|
678
698
|
completionGuidance: 'Present your final synthesis with key findings as bold headings. Lead with insights, not process.',
|
|
699
|
+
finalReflection: true,
|
|
679
700
|
}),
|
|
680
701
|
label: '/deepthink — deep analysis',
|
|
702
|
+
description: 'Deep multi-round analysis of a hard question',
|
|
703
|
+
argumentHint: '<question> [--record]',
|
|
681
704
|
},
|
|
682
705
|
{
|
|
683
706
|
file: 'problem-solve.md',
|
|
@@ -688,23 +711,32 @@ const SLASH_COMMANDS = [
|
|
|
688
711
|
completionGuidance: 'Present your final synthesis as a structured decision with key findings as bold headings. Lead with your recommendation, not process.',
|
|
689
712
|
analyticalGuidance: PROBLEM_SOLVE_DECISION_TYPE,
|
|
690
713
|
finalCallExtras: PROBLEM_SOLVE_FINAL_EXTRAS,
|
|
714
|
+
finalReflection: true,
|
|
691
715
|
}),
|
|
692
716
|
label: '/problem-solve — structured decision-making',
|
|
717
|
+
description: 'Structured decision-making on a problem, stress-tested before commitment',
|
|
718
|
+
argumentHint: '<problem> [--record]',
|
|
693
719
|
},
|
|
694
720
|
{
|
|
695
|
-
file: '
|
|
696
|
-
content:
|
|
697
|
-
label: '/
|
|
721
|
+
file: 'think.md',
|
|
722
|
+
content: THINK_SHIM_CONTENT,
|
|
723
|
+
label: '/think — structured single-session analysis',
|
|
724
|
+
description: 'Quick structured analysis of a question (short session)',
|
|
725
|
+
argumentHint: '<question> [--record]',
|
|
698
726
|
},
|
|
699
727
|
{
|
|
700
|
-
file: '
|
|
701
|
-
content:
|
|
702
|
-
label: '/
|
|
728
|
+
file: 'rvry.md',
|
|
729
|
+
content: RVRY_SHIM_CONTENT,
|
|
730
|
+
label: '/rvry — reflective answering',
|
|
731
|
+
description: 'Reflective answering — self-observation first, then the answer',
|
|
732
|
+
argumentHint: '<question> [--record]',
|
|
703
733
|
},
|
|
704
734
|
{
|
|
705
|
-
file: 'think.md',
|
|
706
|
-
content:
|
|
707
|
-
label: '/think —
|
|
735
|
+
file: 'think-model.md',
|
|
736
|
+
content: THINK_MODEL_SHIM_CONTENT,
|
|
737
|
+
label: '/think-model — apply one named mental model',
|
|
738
|
+
description: 'Apply one named mental model (five-whys, pre-mortem, inversion, ...) to a problem',
|
|
739
|
+
argumentHint: '<model> <problem> [--record]',
|
|
708
740
|
},
|
|
709
741
|
{
|
|
710
742
|
file: 'challenge.md',
|
|
@@ -717,6 +749,8 @@ const SLASH_COMMANDS = [
|
|
|
717
749
|
finalCallExtras: CHALLENGE_FINAL_EXTRAS,
|
|
718
750
|
}),
|
|
719
751
|
label: '/challenge — adversarial stress-testing',
|
|
752
|
+
description: 'Adversarial stress-test of a proposal with a GO / NO_GO verdict',
|
|
753
|
+
argumentHint: '<proposal> [--record] [--auto]',
|
|
720
754
|
},
|
|
721
755
|
{
|
|
722
756
|
file: 'meta.md',
|
|
@@ -727,8 +761,16 @@ const SLASH_COMMANDS = [
|
|
|
727
761
|
completionGuidance: 'Present your final metacognitive synthesis as a cohesive narrative reflection -- not a structured report. Lead with insights, not process.',
|
|
728
762
|
}),
|
|
729
763
|
label: '/meta — metacognitive observation (Max tier)',
|
|
764
|
+
description: 'Metacognitive observation on a topic (Max tier)',
|
|
765
|
+
argumentHint: '<topic> [--record]',
|
|
730
766
|
},
|
|
731
767
|
];
|
|
768
|
+
/** Frontmatter gives the command a human-readable description in the
|
|
769
|
+
* Claude Code picker; without it the picker falls back to the file's first
|
|
770
|
+
* line, which is a model instruction ("Call the think MCP tool ..."). */
|
|
771
|
+
function withFrontmatter(cmd) {
|
|
772
|
+
return `---\ndescription: ${cmd.description}\nargument-hint: ${cmd.argumentHint}\n---\n\n${cmd.content}`;
|
|
773
|
+
}
|
|
732
774
|
/**
|
|
733
775
|
* Install RVRY slash commands into the given directory.
|
|
734
776
|
* Only called when Claude Code is the selected client.
|
|
@@ -753,12 +795,27 @@ function installSlashCommands(commandsDir) {
|
|
|
753
795
|
if (existed) {
|
|
754
796
|
writeFileSync(`${filePath}.bak`, readFileSync(filePath, "utf-8"), "utf-8");
|
|
755
797
|
}
|
|
756
|
-
writeFileSync(filePath, cmd
|
|
798
|
+
writeFileSync(filePath, withFrontmatter(cmd) + "\n", "utf-8");
|
|
757
799
|
console.log(existed
|
|
758
800
|
? ` Updated ${cmd.file} (previous version backed up to ${cmd.file}.bak)`
|
|
759
801
|
: ` Installed ${cmd.file}`);
|
|
760
802
|
installed.push(cmd.label);
|
|
761
803
|
}
|
|
804
|
+
// Retire command files from earlier surface names. Content is preserved
|
|
805
|
+
// as .bak; the live command is removed so a stale /shimmer or /rvry-model
|
|
806
|
+
// no longer points at a tool this server does not expose.
|
|
807
|
+
const retiredCommands = {
|
|
808
|
+
'shimmer.md': '/rvry',
|
|
809
|
+
'rvry-model.md': '/think-model',
|
|
810
|
+
};
|
|
811
|
+
for (const [retired, replacement] of Object.entries(retiredCommands)) {
|
|
812
|
+
const filePath = join(commandsDir, retired);
|
|
813
|
+
if (existsSync(filePath)) {
|
|
814
|
+
writeFileSync(`${filePath}.bak`, readFileSync(filePath, 'utf-8'), 'utf-8');
|
|
815
|
+
unlinkSync(filePath);
|
|
816
|
+
console.log(` Removed ${retired} (replaced by ${replacement}; backed up to ${retired}.bak)`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
762
819
|
}
|
|
763
820
|
catch (err) {
|
|
764
821
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -767,7 +824,7 @@ function installSlashCommands(commandsDir) {
|
|
|
767
824
|
return installed;
|
|
768
825
|
}
|
|
769
826
|
// Exported for tests (content + install behavior).
|
|
770
|
-
export { SLASH_COMMANDS, installSlashCommands,
|
|
827
|
+
export { SLASH_COMMANDS, installSlashCommands, THINK_SHIM_CONTENT, RVRY_SHIM_CONTENT, THINK_MODEL_SHIM_CONTENT };
|
|
771
828
|
// ── Main setup flow ────────────────────────────────────────────────
|
|
772
829
|
const BANNER = `
|
|
773
830
|
8888888b. 888 888 8888888b. Y88b d88P
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rvry/mcp",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Reasoning depth enforcement for LLMs. Seven structured analysis tools and 18 mental-model templates for Claude Code, Claude Desktop, and any MCP client.",
|
|
5
|
+
"homepage": "https://rvry.ai",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
8
|
"rvry-mcp": "dist/index.js"
|
|
@@ -20,18 +21,25 @@
|
|
|
20
21
|
"typecheck": "tsc --noEmit"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"@modelcontextprotocol/sdk": "
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.27.1"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"typescript": "
|
|
27
|
-
"@types/node": "
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"@types/node": "^25.3.3"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [
|
|
30
31
|
"mcp",
|
|
32
|
+
"mcp-server",
|
|
33
|
+
"model-context-protocol",
|
|
31
34
|
"rvry",
|
|
32
35
|
"reasoning",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
36
|
+
"structured-reasoning",
|
|
37
|
+
"mental-models",
|
|
38
|
+
"critical-thinking",
|
|
39
|
+
"claude",
|
|
40
|
+
"claude-code",
|
|
41
|
+
"llm",
|
|
42
|
+
"ai"
|
|
35
43
|
],
|
|
36
44
|
"license": "MIT"
|
|
37
45
|
}
|