@rvry/mcp 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,18 +55,15 @@ Record the answers (or stated assumptions) as a brief context summary.
55
55
 
56
56
  ## Phase 1b: Start Engine Session
57
57
 
58
- Format the user's original question enriched with scoping context. Include the scoping answers (or assumptions) as additional context.
58
+ Format the user's original question enriched with scope context.
59
59
 
60
60
  Call `mcp__rvry-dev__deepthink` with:
61
61
  ```
62
62
  {
63
- "input": "<original question>\n\nScoping context: <brief summary of scoping answers, e.g. 'Focus: architectural trade-offs. Priority: risk analysis. No time constraint.'>",
64
- "skipScoping": true
63
+ "input": "<original question>\n\nContext: <brief summary of scope answers, e.g. 'Focus: architectural trade-offs. Priority: risk analysis. No time constraint.'>"
65
64
  }
66
65
  ```
67
66
 
68
- `skipScoping` is ALWAYS `true` -- scoping happened here, not in the engine.
69
-
70
67
  Proceed to Phase 2.
71
68
 
72
69
 
@@ -74,13 +71,21 @@ Proceed to Phase 2.
74
71
 
75
72
  Repeat until `status === "complete"`:
76
73
 
77
- 1. Read the engine's `prompt` and `instruction` these guide YOUR analysis. **Do not show either to the user.**
74
+ 1. The engine's response has two content blocks. The first is Base64-encoded JSON -- decode it to read the structured data. The second is a plain-text summary for the user. From the decoded JSON, 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.**
78
75
  2. Show the user a brief status line:
79
- - Format: `Round {round} {what you're doing this round}`
80
- - Example: `Round 3 stress-testing the current position`
81
- - Derive the description from the engine's phase indicator or your own summary of the round's focus. One line only.
82
- 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.
83
- 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:
84
89
  ```
85
90
  Constraint Updates
86
91
  RESOLVE: C1, C2
@@ -89,16 +94,15 @@ Repeat until `status === "complete"`:
89
94
  MILESTONE: <milestone> | <evidence>
90
95
  End Constraint Updates
91
96
  ```
92
- 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.**
93
98
 
94
99
  ### What NEVER appears in user-visible output:
95
- - The engine's `prompt` field content
96
- - Constraint tables (`C1 [ACTIVE] FORWARD: ...`)
97
- - Constraint update blocks (`RESOLVE: C1`, `MILESTONE: ...`)
100
+ - The engine's `question` field content
101
+ - Constraint views or constraint update blocks
98
102
  - Self-check questions or responses
99
- - Gate verdicts (`SOFT_FAIL`, `HARD_FAIL`, `PASS`)
103
+ - Gate verdicts or detection results
100
104
  - Milestone markers
101
- - Protocol surface elements (session awareness text, phase indicators from engine)
105
+ - The `constraintBlock` content
102
106
 
103
107
  ### What the user sees per round:
104
108
  - The one-line status (step 2 above)
@@ -108,7 +112,7 @@ Repeat until `status === "complete"`:
108
112
 
109
113
  When `status === "complete"`:
110
114
 
111
- 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.
112
116
 
113
117
  Present to the user:
114
118
  1. **Default Starting Point**: What the obvious answer was and why it was insufficient
@@ -116,4 +120,4 @@ Present to the user:
116
120
  3. **Open Questions**: What remains genuinely uncertain (if any)
117
121
  4. **Suggested Next Steps**: Concrete follow-up actions or investigations
118
122
 
119
- 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.
@@ -55,18 +55,15 @@ Record the answers (or stated assumptions) as a brief context summary.
55
55
 
56
56
  ## Phase 1b: Start Engine Session
57
57
 
58
- Format the user's original problem enriched with scoping context. Include the scoping answers (or assumptions) as additional context.
58
+ Format the user's original problem enriched with scope context.
59
59
 
60
60
  Call `mcp__rvry-dev__problem_solve` with:
61
61
  ```
62
62
  {
63
- "input": "<original problem>\n\nScoping context: <brief summary of scoping answers, e.g. 'Priority: risk minimization. Options: evaluate known ones. Single decision-maker.'>",
64
- "skipScoping": true
63
+ "input": "<original problem>\n\nContext: <brief summary of scope answers, e.g. 'Priority: risk minimization. Options: evaluate known ones. Single decision-maker.'>"
65
64
  }
66
65
  ```
67
66
 
68
- `skipScoping` is ALWAYS `true` -- scoping happened here, not in the engine.
69
-
70
67
  Proceed to Phase 2.
71
68
 
72
69
 
@@ -74,12 +71,12 @@ Proceed to Phase 2.
74
71
 
75
72
  Repeat until `status === "complete"`:
76
73
 
77
- 1. Read the engine's `prompt` and `instruction` these guide YOUR analysis. **Do not show either to the user.**
74
+ 1. The engine's response has two content blocks. The first is Base64-encoded JSON -- decode it to read the structured data. The second is a plain-text summary for the user. From the decoded JSON, 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.**
78
75
  2. Show the user a brief status line:
79
- - Format: `Round {round} {what you're doing this round}`
80
- - Example: `Round 3 stress-testing the current position`
81
- - Derive the description from the engine's phase indicator or your own summary of the round's focus. One line only.
82
- 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.
83
80
  4. In your internal reasoning, end your analysis with the constraint update block the engine expects:
84
81
  ```
85
82
  Constraint Updates
@@ -92,13 +89,12 @@ Repeat until `status === "complete"`:
92
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.**
93
90
 
94
91
  ### What NEVER appears in user-visible output:
95
- - The engine's `prompt` field content
96
- - Constraint tables (`C1 [ACTIVE] FORWARD: ...`)
97
- - Constraint update blocks (`RESOLVE: C1`, `MILESTONE: ...`)
92
+ - The engine's `question` field content
93
+ - Constraint views or constraint update blocks
98
94
  - Self-check questions or responses
99
- - Gate verdicts (`SOFT_FAIL`, `HARD_FAIL`, `PASS`)
95
+ - Gate verdicts or detection results
100
96
  - Milestone markers
101
- - Protocol surface elements (session awareness text, phase indicators from engine)
97
+ - The `constraintBlock` content
102
98
 
103
99
  ### What the user sees per round:
104
100
  - The one-line status (step 2 above)
@@ -108,7 +104,7 @@ Repeat until `status === "complete"`:
108
104
 
109
105
  When `status === "complete"`:
110
106
 
111
- 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.
112
108
 
113
109
  Present to the user:
114
110
  1. **Default Starting Point**: What the obvious answer was and why it was insufficient
@@ -116,4 +112,4 @@ Present to the user:
116
112
  3. **Open Questions**: What remains genuinely uncertain (if any)
117
113
  4. **Suggested Next Steps**: Concrete follow-up actions or investigations
118
114
 
119
- 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,42 @@
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;
13
20
  }
21
+ export interface MilestoneView {
22
+ key: string;
23
+ status: 'missing' | 'satisfied';
24
+ }
25
+ /**
26
+ * Decoded response from the RVRY engine /api/v1/think endpoint.
27
+ *
28
+ * In MCP transport, the raw tool response contains this data as a
29
+ * Base64-encoded JSON string (first content block). Decode before parsing.
30
+ */
14
31
  export interface ThinkResponse {
15
32
  sessionId: string;
16
- status: 'scoping' | 'active' | 'complete';
33
+ status: 'active' | 'complete';
17
34
  round: number;
18
- prompt: string;
19
- instruction: string;
20
- scopingQuestions?: ScopingQuestion[];
35
+ question: string;
36
+ constraints: ConstraintView[];
37
+ detection: DetectionView;
38
+ gate: GateView;
39
+ milestones: MilestoneView[];
40
+ constraintBlock: string;
21
41
  usage?: {
22
42
  used: number;
23
43
  limit: number;
@@ -38,8 +58,4 @@ export interface ThinkResponse {
38
58
  * Call the RVRY engine /api/v1/think endpoint with a specific tool.
39
59
  * Start a new session by omitting sessionId, or continue by providing one.
40
60
  */
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>;
61
+ 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);
@@ -176,8 +167,22 @@ async function main() {
176
167
  }).catch(() => { });
177
168
  }
178
169
  const stripped = stripResponse(result, question);
170
+ const userSummary = result.status === 'complete'
171
+ ? 'Session complete -- harvest ready'
172
+ : `Round ${result.round} -- ${result.constraints?.filter((c) => c.status === 'active').length ?? 0} constraints active, gate: ${result.gate?.verdict ?? 'starting'}`;
179
173
  return {
180
- content: [{ type: 'text', text: JSON.stringify(stripped) }],
174
+ content: [
175
+ {
176
+ type: 'text',
177
+ text: Buffer.from(JSON.stringify(stripped)).toString('base64'),
178
+ annotations: { audience: ['assistant'], priority: 1.0 },
179
+ },
180
+ {
181
+ type: 'text',
182
+ text: userSummary,
183
+ annotations: { audience: ['user'], priority: 0.7 },
184
+ },
185
+ ],
181
186
  };
182
187
  }
183
188
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rvry/mcp",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "RVRY reasoning depth enforcement (RDE) engine client.",
5
5
  "type": "module",
6
6
  "bin": {