@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
|
-
###
|
|
134
|
+
### UI backend status
|
|
135
135
|
|
|
136
|
-
`interactive-mcp`
|
|
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.
|
|
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,
|
|
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
|
-
|
|
204
|
-
if (!
|
|
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
|
-
|
|
283
|
-
if (!
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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.
|
|
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"
|