@rawwee/interactive-mcp 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -131,11 +131,10 @@ This section is primarily for developers looking to modify or contribute to the
131
131
  bun run start
132
132
  ```
133
133
 
134
- ### Terminal UI backend status
134
+ ### UI backend status
135
135
 
136
- `interactive-mcp` now uses OpenTUI (`@opentui/core`, `@opentui/react`) for terminal UI rendering.
137
-
138
- OpenTUI is the terminal UI renderer backend.
136
+ `interactive-mcp` currently runs with the OpenTUI terminal backend (`@opentui/core`, `@opentui/react`).
137
+ The VS Code extension and bridge runtime have been removed from the active feature set for now, and may be reconsidered in a future iteration.
139
138
 
140
139
  #### Command-Line Options
141
140
 
@@ -143,7 +142,7 @@ The `interactive-mcp` server accepts the following command-line options. These s
143
142
 
144
143
  | Option | Alias | Description |
145
144
  | ----------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
146
- | `--timeout` | `-t` | Sets the default timeout (in seconds) for user input prompts. Defaults to 30 seconds. |
145
+ | `--timeout` | `-t` | Sets the default timeout (in seconds) for user input prompts. |
147
146
  | `--disable-tools` | `-d` | Disables specific tools or groups (comma-separated list). Prevents the server from advertising or registering them. Options: `request_user_input`, `message_complete_notification`, `intensive_chat`. |
148
147
 
149
148
  **Example:** Setting multiple options in the client config `args` array:
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
4
4
  import notifier from 'node-notifier';
5
5
  import yargs from 'yargs';
6
6
  import { hideBin } from 'yargs/helpers';
7
+ import { askQuestionInSession, startIntensiveChatSession, stopIntensiveChatSession, } from './commands/intensive-chat/index.js';
7
8
  import { getCmdWindowInput } from './commands/input/index.js';
8
- import { startIntensiveChatSession, askQuestionInSession, stopIntensiveChatSession, } from './commands/intensive-chat/index.js';
9
9
  import { USER_INPUT_TIMEOUT_SECONDS, USER_INPUT_TIMEOUT_SENTINEL, } from './constants.js';
10
10
  import logger from './utils/logger.js';
11
11
  import { validateRepositoryBaseDirectory } from './utils/base-directory.js';
@@ -158,10 +158,11 @@ if (isToolEnabled('start_intensive_chat')) {
158
158
  const { sessionTitle, baseDirectory } = args;
159
159
  try {
160
160
  const validatedBaseDirectory = await validateRepositoryBaseDirectory(baseDirectory);
161
- // Start a new intensive chat session, passing global timeout
162
161
  const sessionId = await startIntensiveChatSession(sessionTitle, validatedBaseDirectory, globalTimeoutSeconds);
163
162
  // Track this session for the client
164
- activeChatSessions.set(sessionId, sessionTitle);
163
+ activeChatSessions.set(sessionId, {
164
+ title: sessionTitle,
165
+ });
165
166
  return {
166
167
  content: [
167
168
  {
@@ -200,8 +201,8 @@ if (isToolEnabled('ask_intensive_chat')) {
200
201
  async (args) => {
201
202
  // Use inferred args type
202
203
  const { sessionId, question, predefinedOptions, baseDirectory } = args;
203
- // Check if session exists
204
- if (!activeChatSessions.has(sessionId)) {
204
+ const activeSession = activeChatSessions.get(sessionId);
205
+ if (!activeSession) {
205
206
  return {
206
207
  content: [
207
208
  { type: 'text', text: 'Error: Invalid or expired session ID.' },
@@ -210,7 +211,6 @@ if (isToolEnabled('ask_intensive_chat')) {
210
211
  }
211
212
  try {
212
213
  const validatedBaseDirectory = await validateRepositoryBaseDirectory(baseDirectory);
213
- // Ask the question in the session
214
214
  const answer = await askQuestionInSession(sessionId, question, validatedBaseDirectory, predefinedOptions);
215
215
  // Check for the specific timeout indicator
216
216
  if (answer === USER_INPUT_TIMEOUT_SENTINEL) {
@@ -279,8 +279,8 @@ if (isToolEnabled('stop_intensive_chat')) {
279
279
  async (args) => {
280
280
  // Use inferred args type
281
281
  const { sessionId } = args;
282
- // Check if session exists
283
- if (!activeChatSessions.has(sessionId)) {
282
+ const activeSession = activeChatSessions.get(sessionId);
283
+ if (!activeSession) {
284
284
  return {
285
285
  content: [
286
286
  { type: 'text', text: 'Error: Invalid or expired session ID.' },
@@ -288,7 +288,6 @@ if (isToolEnabled('stop_intensive_chat')) {
288
288
  };
289
289
  }
290
290
  try {
291
- // Stop the session
292
291
  const success = await stopIntensiveChatSession(sessionId);
293
292
  // Remove session from map if successful
294
293
  if (success) {
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  // === Start Intensive Chat Definition ===
3
3
  const startCapability = {
4
- description: 'Start a persistent OpenTUI intensive chat session for gathering multiple answers quickly with markdown-friendly prompts.',
4
+ description: 'Start a persistent intensive chat session for gathering multiple answers quickly with markdown-friendly prompts.',
5
5
  parameters: {
6
6
  type: 'object',
7
7
  properties: {
@@ -18,17 +18,18 @@ const startCapability = {
18
18
  },
19
19
  };
20
20
  const startDescription = (globalTimeoutSeconds) => `<description>
21
- Start an intensive chat session (OpenTUI terminal UI) for gathering multiple answers quickly from the user.
21
+ Start an intensive chat session for gathering multiple answers quickly from the user.
22
22
  **Highly recommended** for scenarios requiring a sequence of related inputs or confirmations.
23
23
  Very useful for gathering multiple answers from the user in a short period of time.
24
24
  Especially useful for brainstorming ideas or discussing complex topics with the user.
25
25
  </description>
26
26
 
27
27
  <importantNotes>
28
- - (!important!) Opens a persistent console window that stays open for multiple questions.
28
+ - (!important!) Opens a persistent interaction session that stays active for multiple questions.
29
29
  - (!important!) Returns a session ID that **must** be used for subsequent questions via 'ask_intensive_chat'.
30
30
  - (!important!) **Must** be closed with 'stop_intensive_chat' when finished gathering all inputs.
31
31
  - (!important!) After starting a session, **immediately** continue asking all necessary questions using 'ask_intensive_chat' within the **same response message**. Do not end the response until the chat is closed with 'stop_intensive_chat'. This creates a seamless conversational flow for the user.
32
+ - (!important!) Continue the prompt loop until the user explicitly says one of: "Stop prompting", "End session", or "Don't ask anymore".
32
33
  </importantNotes>
33
34
 
34
35
  <whenToUseThisTool>
@@ -41,7 +42,7 @@ Especially useful for brainstorming ideas or discussing complex topics with the
41
42
  </whenToUseThisTool>
42
43
 
43
44
  <features>
44
- - Opens a persistent OpenTUI window for continuous interaction
45
+ - Opens a persistent interactive prompt surface for continuous interaction
45
46
  - Renders markdown prompts, including code/diff snippets, for richer question context
46
47
  - Preserves markdown links, including VS Code file links (for example: "vscode://file/<abs-path>:<line>:<column>") in prompt content
47
48
  - Supports option mode + free-text mode while asking follow-up questions
@@ -49,6 +50,7 @@ Especially useful for brainstorming ideas or discussing complex topics with the
49
50
  - Returns a session ID for subsequent interactions
50
51
  - Keeps full chat history visible to the user
51
52
  - Maintains state between questions
53
+ - Backend-agnostic contract: start/ask/stop behavior is consistent across available UI backends
52
54
  - Requires baseDirectory and pins autocomplete/search scope to the repository root
53
55
  </features>
54
56
 
@@ -85,7 +87,7 @@ const startToolDefinition = {
85
87
  };
86
88
  // === Ask Intensive Chat Definition ===
87
89
  const askCapability = {
88
- description: 'Ask a markdown-friendly question in an active OpenTUI intensive chat session.',
90
+ description: 'Ask a markdown-friendly question in an active intensive chat session.',
89
91
  parameters: {
90
92
  type: 'object',
91
93
  properties: {
@@ -120,6 +122,8 @@ Ask a new question in an active intensive chat session previously started with '
120
122
  - (!important!) Supports predefined options for quick selection.
121
123
  - (!important!) Returns the user's answer or indicates if they didn't respond.
122
124
  - (!important!) **Use this repeatedly within the same response message** after 'start_intensive_chat' until all questions are asked.
125
+ - (!important!) If response is empty or times out for required input, re-prompt and do not proceed with assumptions.
126
+ - (!important!) Keep the loop active until the user explicitly says one of: "Stop prompting", "End session", or "Don't ask anymore".
123
127
  </importantNotes>
124
128
 
125
129
  <whenToUseThisTool>
@@ -193,9 +197,10 @@ const stopDescription = `<description>
193
197
  </description>
194
198
 
195
199
  <importantNotes>
196
- - (!important!) Closes the console window for the intensive chat.
200
+ - (!important!) Closes the active intensive chat session.
197
201
  - (!important!) Frees up system resources.
198
202
  - (!important!) **Should always be called** as the final step when finished with an intensive chat session, typically at the end of the response message where 'start_intensive_chat' was called.
203
+ - (!important!) Only stop the session when the user explicitly wants to end prompting, such as with "Stop prompting", "End session", or "Don't ask anymore".
199
204
  </importantNotes>
200
205
 
201
206
  <whenToUseThisTool>
@@ -207,7 +212,7 @@ const stopDescription = `<description>
207
212
  </whenToUseThisTool>
208
213
 
209
214
  <features>
210
- - Gracefully closes the console window
215
+ - Gracefully closes the active session in the current backend
211
216
  - Cleans up system resources
212
217
  - Marks the session as complete
213
218
  </features>
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  // Define capability conforming to ToolCapabilityInfo
3
3
  const capabilityInfo = {
4
- description: 'Ask the user a question in an OpenTUI terminal prompt with markdown-friendly rendering and await their reply.',
4
+ description: 'Ask the user a question in an interactive prompt surface and await their reply.',
5
5
  parameters: {
6
6
  type: 'object',
7
7
  properties: {
@@ -29,7 +29,7 @@ const capabilityInfo = {
29
29
  };
30
30
  // Define description conforming to ToolRegistrationDescription
31
31
  const registrationDescription = (globalTimeoutSeconds) => `<description>
32
- Send a question to the user via the OpenTUI terminal prompt. **Crucial for clarifying requirements, confirming plans, or resolving ambiguity.**
32
+ Send a question to the user via an interactive prompt surface. **Crucial for clarifying requirements, confirming plans, or resolving ambiguity.**
33
33
  You should call this tool whenever it has **any** uncertainty or needs clarification or confirmation, even for trivial or silly questions.
34
34
  Feel free to ask anything! **Proactive questioning is preferred over making assumptions.**
35
35
  </description>
@@ -39,9 +39,15 @@ Feel free to ask anything! **Proactive questioning is preferred over making assu
39
39
  - (!important!) Continue to generate existing messages after user answers.
40
40
  - (!important!) Provide predefined options for quick selection if applicable.
41
41
  - (!important!) **Essential for validating assumptions before proceeding with significant actions (e.g., code edits, running commands).**
42
+ - (!important!) **Do not exit the prompt loop** until the user explicitly says one of: "Stop prompting", "End session", or "Don't ask anymore".
43
+ - (!important!) Immediately before final/closing handoff, ask exactly: "Are you satisfied with this result, or would you like any changes?"
44
+ - (!important!) If a required prompt times out or response is empty, re-prompt indefinitely and do not proceed with assumptions.
45
+ - (!important!) If the user skips a requested command/script, ask why it was skipped and whether to continue with alternatives or stop.
42
46
  </importantNotes>
43
47
 
44
48
  <whenToUseThisTool>
49
+ - Before starting any task, even if requirements appear clear
50
+ - After completing any task, to run the mandatory satisfaction check
45
51
  - When you need clarification on user requirements or preferences
46
52
  - When multiple implementation approaches are possible and user input is needed
47
53
  - **Before making potentially impactful changes (code edits, file operations, complex commands)**
@@ -51,14 +57,19 @@ Feel free to ask anything! **Proactive questioning is preferred over making assu
51
57
  - When facing ambiguous instructions that require clarification
52
58
  - When seeking feedback on generated code or solutions
53
59
  - When needing permission to modify critical files or functionality
60
+ - When user instructions are conflicting or unclear
61
+ - When the user asks to be prompted, asks a direct question, or asks a reply question
62
+ - When the user skips a command you requested
63
+ - Immediately before any final/closing handoff
54
64
  - **Whenever you feel even slightly unsure about the user's intent or the correct next step.**
55
65
  </whenToUseThisTool>
56
66
 
57
67
  <features>
58
- - OpenTUI prompt with markdown rendering (including code/diff blocks)
68
+ - Interactive prompt UI with markdown rendering (including code/diff blocks)
59
69
  - Preserves markdown links, including VS Code file links (for example: "vscode://file/<abs-path>:<line>:<column>") when provided in the prompt text
60
70
  - Supports option mode + free-text input mode when predefinedOptions are provided
61
71
  - Returns user response or timeout notification (timeout defaults to ${globalTimeoutSeconds} seconds)
72
+ - Backend-agnostic contract: same request/response behavior regardless of the active UI backend
62
73
  - Maintains context across user interactions
63
74
  - Handles empty responses gracefully
64
75
  - Shows project context in the prompt header/title
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "name": "@rawwee/interactive-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "interactive-mcp": "dist/index.js"
8
8
  },
9
9
  "files": [
10
- "dist",
10
+ "dist/constants.js",
11
+ "dist/index.js",
12
+ "dist/commands/input",
13
+ "dist/commands/intensive-chat",
14
+ "dist/components",
15
+ "dist/tool-definitions",
16
+ "dist/utils",
11
17
  "README.md",
12
18
  "LICENSE",
13
19
  "package.json"