@rvry/mcp 0.2.0 → 0.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.
@@ -15,32 +15,54 @@ allowed-tools:
15
15
  - If `$ARGUMENTS` is empty or `--help`: display usage ("Usage: /deepthink [--auto] <your question>") and stop
16
16
  - If `$ARGUMENTS` contains `--auto`: set AUTO_MODE, strip `--auto` from input
17
17
 
18
- ## Phase 1: Start Session
18
+ ## Phase 1: ORIENT (before calling the engine)
19
19
 
20
- Call `mcp__rvry-dev__deepthink` with `{ "input": "<cleaned input>", "skipScoping": <true if AUTO_MODE> }`.
20
+ Orient directly -- no engine calls yet. Analyze the user's question and identify:
21
21
 
22
- ### If status is "scoping" (and not AUTO_MODE):
22
+ 1. **What I know**: Key facts, evidence, and context apparent from the question
23
+ 2. **What I'm uncertain about**: Gaps, assumptions, unknowns (list each specifically)
24
+ 3. **What I'm avoiding**: Uncomfortable angles, taboo options, things that would be inconvenient if true
23
25
 
24
- The engine has returned scoping questions to help calibrate the analysis.
26
+ Translate each uncertainty into a binary question with a smart default. Generate up to 3 questions, each with exactly 2 options. The recommended option comes first.
25
27
 
26
- **IMPORTANT: You MUST call AskUserQuestion as a tool to collect answers. Do NOT render the questions as plain text — the user's answers will be lost.**
28
+ ### If AUTO_MODE:
27
29
 
28
- Call `AskUserQuestion` with the scoping questions mapped to its format. Each `scopingQuestions` entry becomes a question:
30
+ State your assumptions visibly in your reasoning (e.g., "Assuming focus on architectural trade-offs rather than implementation details. Assuming risk analysis is more valuable than landscape mapping."). Proceed directly to Phase 1b.
31
+
32
+ ### If NOT AUTO_MODE:
33
+
34
+ Ask scope questions via `AskUserQuestion` (up to 3 questions, each with 2 options, smart default first marked "(Recommended)").
29
35
 
30
36
  ```
31
37
  AskUserQuestion({
32
- questions: scopingQuestions.map(sq => ({
33
- question: sq.question,
34
- header: sq.question.slice(0, 12), // short label
35
- options: sq.options.map(o => ({ label: o.label, description: o.description })),
36
- multiSelect: false
37
- }))
38
+ questions: [
39
+ {
40
+ question: "<derived from uncertainty>",
41
+ header: "<short label>",
42
+ options: [
43
+ { label: "<recommended option> (Recommended)", description: "<why this is the smart default>" },
44
+ { label: "<alternative option>", description: "<when this makes sense>" }
45
+ ],
46
+ multiSelect: false
47
+ }
48
+ ]
38
49
  })
39
50
  ```
40
51
 
41
- After collecting all answers from AskUserQuestion, format them as a brief context summary (e.g., "Stakes: High. Looking for: risks and failure modes.") and call `mcp__rvry-dev__deepthink` with `{ "input": "<formatted scoping answers>", "sessionId": "<sessionId from previous response>" }`.
52
+ If AskUserQuestion returns blank or fails, state assumptions visibly and proceed.
53
+
54
+ Record the answers (or stated assumptions) as a brief context summary.
55
+
56
+ ## Phase 1b: Start Engine Session
42
57
 
43
- ### If status is "active":
58
+ Format the user's original question enriched with scope context.
59
+
60
+ Call `mcp__rvry-dev__deepthink` with:
61
+ ```
62
+ {
63
+ "input": "<original question>\n\nContext: <brief summary of scope answers, e.g. 'Focus: architectural trade-offs. Priority: risk analysis. No time constraint.'>"
64
+ }
65
+ ```
44
66
 
45
67
  Proceed to Phase 2.
46
68
 
@@ -49,13 +71,21 @@ Proceed to Phase 2.
49
71
 
50
72
  Repeat until `status === "complete"`:
51
73
 
52
- 1. Read the engine's `prompt` and `instruction` these guide YOUR analysis. **Do not show either to the user.**
74
+ 1. Read the engine's `question` field -- this is the analytical direction for this round. Read `constraints`, `gate`, and `detection` to understand the engine's assessment. Read `constraintBlock` for constraint update instructions. **Do not show any of these to the user.**
53
75
  2. Show the user a brief status line:
54
- - Format: `Round {round} {what you're doing this round}`
55
- - Example: `Round 3 stress-testing the current position`
56
- - Derive the description from the engine's phase indicator or your own summary of the round's focus. One line only.
57
- 3. Perform your analysis in your internal reasoning. The engine's prompt contains analytical framings, self-check questions, and constraint tracking — use all of these to guide your thinking, but they are YOUR instructions, not user output.
58
- 4. In your internal reasoning, end your analysis with the constraint update block the engine expects:
76
+ - Format: `Round {round} -- {what you're doing this round}`
77
+ - Example: `Round 3 -- stress-testing the current position`
78
+ - Derive the description from the engine's question focus. One line only.
79
+ 3. Perform your analysis in your internal reasoning. The engine's question and constraint data guide your thinking, but they are YOUR instructions, not user output.
80
+ 4. Run a 7-question self-check internally (not shown to user):
81
+ - Is this shallow or predictable?
82
+ - What am I avoiding?
83
+ - Why not the uncomfortable option?
84
+ - What would I critique if someone else wrote this?
85
+ - What would a skeptical expert challenge?
86
+ - Any verifiable claims that should be checked?
87
+ - What factual premise have I not verified?
88
+ 5. In your internal reasoning, end your analysis with the constraint update block the engine expects:
59
89
  ```
60
90
  Constraint Updates
61
91
  RESOLVE: C1, C2
@@ -64,16 +94,15 @@ Repeat until `status === "complete"`:
64
94
  MILESTONE: <milestone> | <evidence>
65
95
  End Constraint Updates
66
96
  ```
67
- 5. Call the engine tool with your full analysis (including constraint updates) as the `input`. **The full analysis text goes ONLY in the tool call, never in visible output.**
97
+ 6. Call the engine tool with your full analysis (including constraint updates) as the `input`. **The full analysis text goes ONLY in the tool call, never in visible output.**
68
98
 
69
99
  ### What NEVER appears in user-visible output:
70
- - The engine's `prompt` field content
71
- - Constraint tables (`C1 [ACTIVE] FORWARD: ...`)
72
- - Constraint update blocks (`RESOLVE: C1`, `MILESTONE: ...`)
100
+ - The engine's `question` field content
101
+ - Constraint views or constraint update blocks
73
102
  - Self-check questions or responses
74
- - Gate verdicts (`SOFT_FAIL`, `HARD_FAIL`, `PASS`)
103
+ - Gate verdicts or detection results
75
104
  - Milestone markers
76
- - Protocol surface elements (session awareness text, phase indicators from engine)
105
+ - The `constraintBlock` content
77
106
 
78
107
  ### What the user sees per round:
79
108
  - The one-line status (step 2 above)
@@ -83,7 +112,7 @@ Repeat until `status === "complete"`:
83
112
 
84
113
  When `status === "complete"`:
85
114
 
86
- Synthesize the analysis for the user based on your accumulated reasoning across all rounds. Do NOT simply echo the engine's `harvest` fields they are structured data, not a finished presentation.
115
+ Synthesize the analysis for the user based on your accumulated reasoning across all rounds. Do NOT simply echo the engine's `harvest` fields -- they are structured data, not a finished presentation.
87
116
 
88
117
  Present to the user:
89
118
  1. **Default Starting Point**: What the obvious answer was and why it was insufficient
@@ -91,4 +120,4 @@ Present to the user:
91
120
  3. **Open Questions**: What remains genuinely uncertain (if any)
92
121
  4. **Suggested Next Steps**: Concrete follow-up actions or investigations
93
122
 
94
- Use the engine's `harvest.summary`, `harvest.keyFindings`, `harvest.openQuestions`, and `harvest.followUps` as source material, but write the synthesis in your own words with the depth your analysis produced. The harvest fields are often terse your synthesis should reflect the full depth of the multi-round analysis.
123
+ Use the engine's `harvest.summary`, `harvest.keyFindings`, `harvest.openQuestions`, and `harvest.followUps` as source material, but write the synthesis in your own words with the depth your analysis produced. The harvest fields are often terse -- your synthesis should reflect the full depth of the multi-round analysis.
@@ -15,32 +15,54 @@ allowed-tools:
15
15
  - If `$ARGUMENTS` is empty or `--help`: display usage ("Usage: /problem-solve [--auto] <your problem or decision>") and stop
16
16
  - If `$ARGUMENTS` contains `--auto`: set AUTO_MODE, strip `--auto` from input
17
17
 
18
- ## Phase 1: Start Session
18
+ ## Phase 1: ORIENT (before calling the engine)
19
19
 
20
- Call `mcp__rvry-dev__problem_solve` with `{ "input": "<cleaned input>", "skipScoping": <true if AUTO_MODE> }`.
20
+ Orient directly -- no engine calls yet. Analyze the user's problem and identify:
21
21
 
22
- ### If status is "scoping" (and not AUTO_MODE):
22
+ 1. **What I know**: Key facts, constraints, and context apparent from the problem statement
23
+ 2. **What I'm uncertain about**: Gaps, assumptions, unknowns (list each specifically)
24
+ 3. **What I'm avoiding**: Uncomfortable options, risky paths, things that would be inconvenient if true
23
25
 
24
- The engine has returned scoping questions to help calibrate the analysis.
26
+ Translate each uncertainty into a binary question with a smart default. Generate up to 3 questions, each with exactly 2 options. The recommended option comes first.
25
27
 
26
- **IMPORTANT: You MUST call AskUserQuestion as a tool to collect answers. Do NOT render the questions as plain text — the user's answers will be lost.**
28
+ ### If AUTO_MODE:
27
29
 
28
- Call `AskUserQuestion` with the scoping questions mapped to its format. Each `scopingQuestions` entry becomes a question:
30
+ State your assumptions visibly in your reasoning (e.g., "Assuming risk minimization over speed. Assuming known options need evaluation rather than generating new alternatives."). Proceed directly to Phase 1b.
31
+
32
+ ### If NOT AUTO_MODE:
33
+
34
+ Ask scope questions via `AskUserQuestion` (up to 3 questions, each with 2 options, smart default first marked "(Recommended)").
29
35
 
30
36
  ```
31
37
  AskUserQuestion({
32
- questions: scopingQuestions.map(sq => ({
33
- question: sq.question,
34
- header: sq.question.slice(0, 12), // short label
35
- options: sq.options.map(o => ({ label: o.label, description: o.description })),
36
- multiSelect: false
37
- }))
38
+ questions: [
39
+ {
40
+ question: "<derived from uncertainty>",
41
+ header: "<short label>",
42
+ options: [
43
+ { label: "<recommended option> (Recommended)", description: "<why this is the smart default>" },
44
+ { label: "<alternative option>", description: "<when this makes sense>" }
45
+ ],
46
+ multiSelect: false
47
+ }
48
+ ]
38
49
  })
39
50
  ```
40
51
 
41
- After collecting all answers from AskUserQuestion, format them as a brief context summary (e.g., "Options: multiple, need to narrow. Priority: risk minimization.") and call `mcp__rvry-dev__problem_solve` with `{ "input": "<formatted scoping answers>", "sessionId": "<sessionId from previous response>" }`.
52
+ If AskUserQuestion returns blank or fails, state assumptions visibly and proceed.
53
+
54
+ Record the answers (or stated assumptions) as a brief context summary.
55
+
56
+ ## Phase 1b: Start Engine Session
42
57
 
43
- ### If status is "active":
58
+ Format the user's original problem enriched with scope context.
59
+
60
+ Call `mcp__rvry-dev__problem_solve` with:
61
+ ```
62
+ {
63
+ "input": "<original problem>\n\nContext: <brief summary of scope answers, e.g. 'Priority: risk minimization. Options: evaluate known ones. Single decision-maker.'>"
64
+ }
65
+ ```
44
66
 
45
67
  Proceed to Phase 2.
46
68
 
@@ -49,12 +71,12 @@ Proceed to Phase 2.
49
71
 
50
72
  Repeat until `status === "complete"`:
51
73
 
52
- 1. Read the engine's `prompt` and `instruction` these guide YOUR analysis. **Do not show either to the user.**
74
+ 1. Read the engine's `question` field -- this is the analytical direction for this round. Read `constraints`, `gate`, and `detection` to understand the engine's assessment. Read `constraintBlock` for constraint update instructions. **Do not show any of these to the user.**
53
75
  2. Show the user a brief status line:
54
- - Format: `Round {round} {what you're doing this round}`
55
- - Example: `Round 3 stress-testing the current position`
56
- - Derive the description from the engine's phase indicator or your own summary of the round's focus. One line only.
57
- 3. Perform your analysis in your internal reasoning. The engine's prompt contains analytical framings, self-check questions, and constraint tracking — use all of these to guide your thinking, but they are YOUR instructions, not user output.
76
+ - Format: `Round {round} -- {what you're doing this round}`
77
+ - Example: `Round 3 -- stress-testing the current position`
78
+ - Derive the description from the engine's question focus. One line only.
79
+ 3. Perform your analysis in your internal reasoning. The engine's question and constraint data guide your thinking, but they are YOUR instructions, not user output.
58
80
  4. In your internal reasoning, end your analysis with the constraint update block the engine expects:
59
81
  ```
60
82
  Constraint Updates
@@ -67,13 +89,12 @@ Repeat until `status === "complete"`:
67
89
  5. Call the engine tool with your full analysis (including constraint updates) as the `input`. **The full analysis text goes ONLY in the tool call, never in visible output.**
68
90
 
69
91
  ### What NEVER appears in user-visible output:
70
- - The engine's `prompt` field content
71
- - Constraint tables (`C1 [ACTIVE] FORWARD: ...`)
72
- - Constraint update blocks (`RESOLVE: C1`, `MILESTONE: ...`)
92
+ - The engine's `question` field content
93
+ - Constraint views or constraint update blocks
73
94
  - Self-check questions or responses
74
- - Gate verdicts (`SOFT_FAIL`, `HARD_FAIL`, `PASS`)
95
+ - Gate verdicts or detection results
75
96
  - Milestone markers
76
- - Protocol surface elements (session awareness text, phase indicators from engine)
97
+ - The `constraintBlock` content
77
98
 
78
99
  ### What the user sees per round:
79
100
  - The one-line status (step 2 above)
@@ -83,7 +104,7 @@ Repeat until `status === "complete"`:
83
104
 
84
105
  When `status === "complete"`:
85
106
 
86
- Synthesize the analysis for the user based on your accumulated reasoning across all rounds. Do NOT simply echo the engine's `harvest` fields they are structured data, not a finished presentation.
107
+ Synthesize the analysis for the user based on your accumulated reasoning across all rounds. Do NOT simply echo the engine's `harvest` fields -- they are structured data, not a finished presentation.
87
108
 
88
109
  Present to the user:
89
110
  1. **Default Starting Point**: What the obvious answer was and why it was insufficient
@@ -91,4 +112,4 @@ Present to the user:
91
112
  3. **Open Questions**: What remains genuinely uncertain (if any)
92
113
  4. **Suggested Next Steps**: Concrete follow-up actions or investigations
93
114
 
94
- Use the engine's `harvest.summary`, `harvest.keyFindings`, `harvest.openQuestions`, and `harvest.followUps` as source material, but write the synthesis in your own words with the depth your analysis produced. The harvest fields are often terse your synthesis should reflect the full depth of the multi-round analysis.
115
+ Use the engine's `harvest.summary`, `harvest.keyFindings`, `harvest.openQuestions`, and `harvest.followUps` as source material, but write the synthesis in your own words with the depth your analysis produced. The harvest fields are often terse -- your synthesis should reflect the full depth of the multi-round analysis.
package/dist/client.d.ts CHANGED
@@ -2,22 +2,36 @@
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' | 'think' | 'problem_solve' | 'challenge' | 'meta';
6
- export interface ScopingQuestion {
7
- question: string;
8
- options: Array<{
9
- label: string;
10
- description: string;
11
- }>;
12
- default: string;
5
+ export type RvryTool = 'deepthink' | 'problem_solve';
6
+ export interface ConstraintView {
7
+ id: string;
8
+ type: 'FORWARD' | 'FORBIDDEN' | 'QUESTION';
9
+ text: string;
10
+ status: 'active' | 'resolved' | 'acknowledged' | 'deferred';
11
+ }
12
+ export interface DetectionView {
13
+ overallSeverity: 'low' | 'medium' | 'high' | null;
14
+ interventionHint: string | null;
15
+ }
16
+ export interface GateView {
17
+ verdict: 'PASS' | 'SOFT_FAIL' | 'HARD_FAIL' | null;
18
+ blocked: boolean;
19
+ reason: string | null;
20
+ }
21
+ export interface MilestoneView {
22
+ key: string;
23
+ status: 'missing' | 'satisfied';
13
24
  }
14
25
  export interface ThinkResponse {
15
26
  sessionId: string;
16
- status: 'scoping' | 'active' | 'complete';
27
+ status: 'active' | 'complete';
17
28
  round: number;
18
- prompt: string;
19
- instruction: string;
20
- scopingQuestions?: ScopingQuestion[];
29
+ question: string;
30
+ constraints: ConstraintView[];
31
+ detection: DetectionView;
32
+ gate: GateView;
33
+ milestones: MilestoneView[];
34
+ constraintBlock: string;
21
35
  usage?: {
22
36
  used: number;
23
37
  limit: number;
@@ -38,8 +52,4 @@ export interface ThinkResponse {
38
52
  * Call the RVRY engine /api/v1/think endpoint with a specific tool.
39
53
  * Start a new session by omitting sessionId, or continue by providing one.
40
54
  */
41
- export declare function callTool(tool: RvryTool, input: string, token: string, sessionId?: string, skipScoping?: boolean): Promise<ThinkResponse>;
42
- /**
43
- * @deprecated Use callTool('think', input, token, sessionId) instead.
44
- */
45
- export declare function callThink(input: string, token: string, sessionId?: string): Promise<ThinkResponse>;
55
+ export declare function callTool(tool: RvryTool, input: string, token: string, sessionId?: string): Promise<ThinkResponse>;
package/dist/client.js CHANGED
@@ -6,15 +6,12 @@ const DEFAULT_ENGINE_URL = 'https://engine.rvry.ai';
6
6
  * Call the RVRY engine /api/v1/think endpoint with a specific tool.
7
7
  * Start a new session by omitting sessionId, or continue by providing one.
8
8
  */
9
- export async function callTool(tool, input, token, sessionId, skipScoping) {
9
+ export async function callTool(tool, input, token, sessionId) {
10
10
  const baseUrl = process.env.RVRY_ENGINE_URL ?? DEFAULT_ENGINE_URL;
11
11
  const body = { input, tool };
12
12
  if (sessionId) {
13
13
  body.sessionId = sessionId;
14
14
  }
15
- if (skipScoping) {
16
- body.skipScoping = true;
17
- }
18
15
  const res = await fetch(`${baseUrl}/api/v1/think`, {
19
16
  method: 'POST',
20
17
  headers: {
@@ -28,9 +25,3 @@ export async function callTool(tool, input, token, sessionId, skipScoping) {
28
25
  }
29
26
  return res.json();
30
27
  }
31
- /**
32
- * @deprecated Use callTool('think', input, token, sessionId) instead.
33
- */
34
- export async function callThink(input, token, sessionId) {
35
- return callTool('think', input, token, sessionId);
36
- }
package/dist/index.js CHANGED
@@ -48,10 +48,6 @@ const TOOL_DEFS = [
48
48
  type: 'string',
49
49
  description: 'Session ID for continuing an existing session. Omit to start a new session.',
50
50
  },
51
- skipScoping: {
52
- type: 'boolean',
53
- description: 'Skip the scoping questions phase and begin analysis immediately.',
54
- },
55
51
  },
56
52
  required: ['input'],
57
53
  },
@@ -72,10 +68,6 @@ const TOOL_DEFS = [
72
68
  type: 'string',
73
69
  description: 'Session ID for continuing an existing session. Omit to start a new session.',
74
70
  },
75
- skipScoping: {
76
- type: 'boolean',
77
- description: 'Skip the scoping questions phase and begin analysis immediately.',
78
- },
79
71
  },
80
72
  required: ['input'],
81
73
  },
@@ -89,12 +81,12 @@ function stripResponse(result, question) {
89
81
  round: result.round,
90
82
  question,
91
83
  };
92
- if (result.status === 'scoping' && result.scopingQuestions) {
93
- stripped.scopingQuestions = result.scopingQuestions;
94
- }
95
84
  if (result.status === 'active') {
96
- stripped.prompt = result.prompt;
97
- stripped.instruction = result.instruction;
85
+ stripped.constraints = result.constraints;
86
+ stripped.detection = result.detection;
87
+ stripped.gate = result.gate;
88
+ stripped.milestones = result.milestones;
89
+ stripped.constraintBlock = result.constraintBlock;
98
90
  }
99
91
  if (result.status === 'complete' && result.harvest) {
100
92
  stripped.harvest = result.harvest;
@@ -142,7 +134,6 @@ async function main() {
142
134
  };
143
135
  }
144
136
  const sessionId = typeof typedArgs?.sessionId === 'string' ? typedArgs.sessionId : undefined;
145
- const skipScoping = typedArgs?.skipScoping === true;
146
137
  // Cache question on first call (no sessionId = new session)
147
138
  // On continuation calls, read from cache
148
139
  let question = input;
@@ -153,7 +144,7 @@ async function main() {
153
144
  question = questionCache.get(sessionId) ?? input;
154
145
  }
155
146
  try {
156
- const result = await callTool(rvryTool, input, token, sessionId, skipScoping || undefined);
147
+ const result = await callTool(rvryTool, input, token, sessionId);
157
148
  // Cache question on first call (now we have the sessionId)
158
149
  if (!sessionId) {
159
150
  questionCache.set(result.sessionId, input);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rvry/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "RVRY reasoning depth enforcement (RDE) engine client.",
5
5
  "type": "module",
6
6
  "bin": {