@rawwee/interactive-mcp 1.4.3 → 1.5.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.
package/README.md
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@rawwee/interactive-mcp) [](https://www.npmjs.com/package/@rawwee/interactive-mcp) [](https://github.com/josippapez/interactive-mcp-server/blob/main/LICENSE) [](https://github.com/prettier/prettier) [](https://github.com/josippapez/interactive-mcp-server) [](https://github.com/josippapez/interactive-mcp-server/commits/main)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Repository
|
|
6
|
+
|
|
7
|
+
- GitHub: https://github.com/josippapez/interactive-mcp-server
|
|
8
|
+
|
|
9
|
+

|
|
6
10
|
|
|
7
11
|
A MCP Server implemented in Node.js/TypeScript, facilitating interactive communication between LLMs and users. **Note:** This server is designed to run locally alongside the MCP client (e.g., Claude Desktop, VS Code), as it needs direct access to the user's operating system to display notifications and command-line prompts.
|
|
8
12
|
|
|
@@ -19,7 +23,7 @@ This server exposes the following tools via the Model Context Protocol (MCP):
|
|
|
19
23
|
- `stop_intensive_chat`: Closes an active intensive chat session.
|
|
20
24
|
|
|
21
25
|
Prompt UIs support markdown-friendly question text (including multiline prompts, fenced code blocks, and diff snippets). When useful, you can also include VS Code-style file links in prompt text (for example, `vscode://file/<absolute-path>:<line>:<column>`).
|
|
22
|
-
In TUI input mode, `Cmd/Ctrl+V` supports clipboard text plus file/image includes from pasted paths, copied file objects, and copied images (platform support varies). Files are sent as path references rather than full contents to optimize token usage—the AI can then read files directly using its available tools.
|
|
26
|
+
In TUI input mode, `Cmd/Ctrl+C` copies current input, `Cmd/Ctrl+V` supports clipboard text plus file/image includes from pasted paths, copied file objects, and copied images (platform support varies), and `Cmd/Ctrl+Z` / `Cmd/Ctrl+Shift+Z` provide undo/redo. Files are sent as path references rather than full contents to optimize token usage—the AI can then read files directly using its available tools.
|
|
23
27
|
|
|
24
28
|
## Usage Scenarios
|
|
25
29
|
|
|
@@ -278,7 +278,7 @@ const App = ({ sessionId, title, outputDir, searchRoot, timeoutSeconds, onCloseS
|
|
|
278
278
|
: 0;
|
|
279
279
|
return (_jsxs("box", { flexDirection: "column", width: "100%", height: "100%", backgroundColor: "black", paddingLeft: isNarrow ? 0 : 1, paddingRight: isNarrow ? 0 : 1, children: [_jsxs("box", { marginBottom: 1, flexDirection: "column", width: "100%", paddingLeft: 1, paddingRight: 1, gap: 0, children: [_jsx("text", { fg: "magenta", children: _jsx("strong", { children: title }) }), _jsxs("text", { fg: "gray", wrapMode: "word", children: ["Session ", sessionId] }), !isNarrow && _jsx("text", { fg: "gray", children: "Waiting for prompts\u2026" })] }), _jsx("scrollbox", { ref: scrollRef, flexGrow: 1, width: "100%", scrollY: true, stickyScroll: followInput, stickyStart: followInput ? 'bottom' : undefined, viewportCulling: false, scrollbarOptions: {
|
|
280
280
|
showArrows: false,
|
|
281
|
-
}, children: _jsxs("box", { flexDirection: "column", width: "100%", paddingBottom: 1, children: [_jsx("box", { flexDirection: "column", width: "100%", gap: 2, children: chatHistory.map((msg, i) => (_jsxs("box", { flexDirection: "column", width: "100%", paddingLeft: 1, paddingRight: 1, gap: 1, children: [msg.isQuestion ? (_jsxs("box", { flexDirection: "column", width: "100%", gap: 0, children: [_jsx("text", { fg: "cyan", children: _jsx("strong", { children: "QUESTION" }) }), _jsx("box", { paddingLeft: isNarrow ? 1 : 2, children: _jsx(MarkdownText, { content: msg.text, showCodeCopyControls: true }) })] })) : null, msg.answer ? (_jsxs("box", { flexDirection: "column", width: "100%", marginTop: 0, children: [_jsx("text", { fg: "green", children: _jsx("strong", { children: "ANSWER" }) }), _jsx("box", { paddingLeft: isNarrow ? 1 : 2, children: _jsx(MarkdownText, { content: msg.answer, showCodeCopyControls: true }) })] })) : null] }, `msg-${i}`))) }), currentQuestionId && (_jsx("box", { flexDirection: "column", marginTop: 1, paddingLeft: 1, paddingRight: 1, gap: 1, children: _jsx(InteractiveInput, { question: chatHistory
|
|
281
|
+
}, children: _jsxs("box", { flexDirection: "column", width: "100%", paddingBottom: 1, children: [_jsx("box", { flexDirection: "column", width: "100%", gap: 2, children: chatHistory.map((msg, i) => (_jsxs("box", { flexDirection: "column", width: "100%", paddingLeft: 1, paddingRight: 1, gap: 1, children: [msg.isQuestion ? (_jsxs("box", { flexDirection: "column", width: "100%", gap: 0, children: [_jsx("text", { fg: "cyan", children: _jsx("strong", { children: "QUESTION" }) }), _jsx("box", { paddingLeft: isNarrow ? 1 : 2, children: _jsx(MarkdownText, { content: msg.text, showContentCopyControl: true, contentCopyLabel: "Copy question", showCodeCopyControls: true }) })] })) : null, msg.answer ? (_jsxs("box", { flexDirection: "column", width: "100%", marginTop: 0, children: [_jsx("text", { fg: "green", children: _jsx("strong", { children: "ANSWER" }) }), _jsx("box", { paddingLeft: isNarrow ? 1 : 2, children: _jsx(MarkdownText, { content: msg.answer, showContentCopyControl: true, contentCopyLabel: "Copy answer", showCodeCopyControls: true }) })] })) : null] }, `msg-${i}`))) }), currentQuestionId && (_jsx("box", { flexDirection: "column", marginTop: 1, paddingLeft: 1, paddingRight: 1, gap: 1, children: _jsx(InteractiveInput, { question: chatHistory
|
|
282
282
|
.slice()
|
|
283
283
|
.reverse()
|
|
284
284
|
.find((m) => m.isQuestion && !m.answer)
|
|
@@ -233,14 +233,40 @@ export function MarkdownText({ content, streaming = false, showContentCopyContro
|
|
|
233
233
|
const segments = useMemo(() => splitMarkdownSegments(content), [content]);
|
|
234
234
|
const [clipboardHint, setClipboardHint] = useState(null);
|
|
235
235
|
const [copiedSnippetIndex, setCopiedSnippetIndex] = useState(null);
|
|
236
|
+
const clipboardHintTimeoutRef = useRef(null);
|
|
236
237
|
const copiedSnippetTimeoutRef = useRef(null);
|
|
237
238
|
useEffect(() => {
|
|
238
239
|
return () => {
|
|
240
|
+
if (clipboardHintTimeoutRef.current) {
|
|
241
|
+
clearTimeout(clipboardHintTimeoutRef.current);
|
|
242
|
+
}
|
|
239
243
|
if (copiedSnippetTimeoutRef.current) {
|
|
240
244
|
clearTimeout(copiedSnippetTimeoutRef.current);
|
|
241
245
|
}
|
|
242
246
|
};
|
|
243
247
|
}, []);
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
if (!clipboardHint) {
|
|
250
|
+
if (clipboardHintTimeoutRef.current) {
|
|
251
|
+
clearTimeout(clipboardHintTimeoutRef.current);
|
|
252
|
+
clipboardHintTimeoutRef.current = null;
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (clipboardHintTimeoutRef.current) {
|
|
257
|
+
clearTimeout(clipboardHintTimeoutRef.current);
|
|
258
|
+
}
|
|
259
|
+
clipboardHintTimeoutRef.current = setTimeout(() => {
|
|
260
|
+
setClipboardHint(null);
|
|
261
|
+
clipboardHintTimeoutRef.current = null;
|
|
262
|
+
}, 2000);
|
|
263
|
+
return () => {
|
|
264
|
+
if (clipboardHintTimeoutRef.current) {
|
|
265
|
+
clearTimeout(clipboardHintTimeoutRef.current);
|
|
266
|
+
clipboardHintTimeoutRef.current = null;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}, [clipboardHint]);
|
|
244
270
|
const copyWithHint = useCallback(async (value, successMessage) => {
|
|
245
271
|
if (!value) {
|
|
246
272
|
setClipboardHint('Nothing to copy.');
|
|
@@ -23,7 +23,7 @@ export const isControlKeyShortcut = (key, letter) => {
|
|
|
23
23
|
};
|
|
24
24
|
export const isSubmitShortcut = (key) => isControlKeyShortcut(key, 's');
|
|
25
25
|
export const isCopyShortcut = (key) => isControlKeyShortcut(key, 'c') ||
|
|
26
|
-
(key.ctrl && key.shift && key.name.toLowerCase() === 'c');
|
|
26
|
+
((key.ctrl || key.meta) && key.shift && key.name.toLowerCase() === 'c');
|
|
27
27
|
export const isPasteShortcut = (key) => isControlKeyShortcut(key, 'v') ||
|
|
28
28
|
(key.ctrl && key.shift && key.name.toLowerCase() === 'v');
|
|
29
29
|
export const isReverseTabShortcut = (key) => key.name === 'backtab' ||
|
|
@@ -64,5 +64,12 @@ export const textareaKeyBindings = [
|
|
|
64
64
|
{ name: 'a', ctrl: true, action: 'select-all' },
|
|
65
65
|
{ name: 'a', meta: true, action: 'select-all' },
|
|
66
66
|
{ name: 'a', super: true, action: 'select-all' },
|
|
67
|
+
{ name: 'z', ctrl: true, action: 'undo' },
|
|
68
|
+
{ name: 'z', meta: true, action: 'undo' },
|
|
69
|
+
{ name: 'z', super: true, action: 'undo' },
|
|
70
|
+
{ name: 'z', ctrl: true, shift: true, action: 'redo' },
|
|
71
|
+
{ name: 'z', meta: true, shift: true, action: 'redo' },
|
|
72
|
+
{ name: 'z', super: true, shift: true, action: 'redo' },
|
|
73
|
+
{ name: 'y', ctrl: true, action: 'redo' },
|
|
67
74
|
{ name: 'j', ctrl: true, action: 'newline' },
|
|
68
75
|
];
|
|
@@ -10,7 +10,7 @@ export const OptionList = ({ mode, options, selectedIndex, onSelectOption, onAct
|
|
|
10
10
|
onActivateOptionMode();
|
|
11
11
|
}, children: _jsxs("text", { wrapMode: "char", fg: index === selectedIndex && mode === 'option' ? 'cyan' : 'gray', children: [index === selectedIndex && mode === 'option' ? '› ' : ' ', opt] }) }, `${opt}-${index}`))) })] }));
|
|
12
12
|
};
|
|
13
|
-
export const InputEditor = ({ questionId, textareaRenderVersion, textareaRef, textareaContainerHeight, textareaRows, hasSuggestions, keyBindings, onFocusRequest, onContentSync, onSubmitFromTextarea, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0, width: "100%", children: [_jsx("text", { fg: "gray", children: "Input" }), _jsx("box", { border: true, borderStyle: "single", borderColor: hasSuggestions ? 'cyan' : 'gray', backgroundColor: "#1f1f1f",
|
|
13
|
+
export const InputEditor = ({ questionId, textareaRenderVersion, textareaRef, textareaContainerHeight, textareaRows, hasSuggestions, keyBindings, onFocusRequest, onContentSync, onSubmitFromTextarea, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0, width: "100%", children: [_jsx("text", { fg: "gray", children: "Input" }), _jsx("box", { border: true, borderStyle: "single", borderColor: hasSuggestions ? 'cyan' : 'gray', backgroundColor: "#1f1f1f", height: textareaContainerHeight, paddingLeft: 1, paddingRight: 1, onClick: onFocusRequest, children: _jsx("textarea", { ref: textareaRef, focused: true, height: textareaRows, wrapMode: "word", backgroundColor: "#1f1f1f", focusedBackgroundColor: "#1f1f1f", textColor: "white", focusedTextColor: "white", placeholderColor: "gray", placeholder: "Type your answer...", keyBindings: keyBindings, onContentChange: onContentSync, onCursorChange: onContentSync, onSubmit: onSubmitFromTextarea }, `textarea-${questionId}-${textareaRenderVersion}`) })] }));
|
|
14
14
|
export const SuggestionsPanel = ({ hasOptions, isIndexingFiles, fileSuggestions, selectedSuggestionIndex, selectedSuggestionVscodeLink, hasSearchRoot, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0, width: "100%", gap: 0, children: [_jsx("text", { fg: "gray", children: hasOptions
|
|
15
15
|
? 'File suggestions • ↑/↓ or Ctrl+N/P navigate • Enter apply'
|
|
16
16
|
: 'File suggestions • ↑/↓ or Ctrl+N/P navigate • Enter/Tab apply' }), isIndexingFiles ? (_jsx("text", { fg: "gray", children: "Indexing files..." })) : fileSuggestions.length > 0 ? (_jsxs("box", { flexDirection: "column", width: "100%", children: [fileSuggestions.map((suggestion, index) => (_jsx("box", { paddingLeft: 0, paddingRight: 1, gap: 0, children: _jsxs("text", { fg: index === selectedSuggestionIndex ? 'cyan' : 'gray', wrapMode: "char", children: [index === selectedSuggestionIndex ? '› ' : ' ', suggestion] }) }, suggestion))), selectedSuggestionVscodeLink && (_jsxs("box", { flexDirection: "column", width: "100%", children: [_jsx("text", { fg: "gray", wrapMode: "word", children: "open file with:" }), _jsx("text", { fg: "cyan", wrapMode: "word", onMouseUp: () => {
|
|
@@ -20,7 +20,7 @@ export const SuggestionsPanel = ({ hasOptions, isIndexingFiles, fileSuggestions,
|
|
|
20
20
|
}, children: "\u2022 VS Code Insiders" })] }))] })) : (_jsx("text", { fg: "gray", children: hasSearchRoot
|
|
21
21
|
? '#search: no matches'
|
|
22
22
|
: '#search: no search root configured' }))] }));
|
|
23
|
-
export const QuestionBox = ({ question, MarkdownTextComponent, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0,
|
|
23
|
+
export const QuestionBox = ({ question, MarkdownTextComponent, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0, gap: 0, border: true, borderStyle: "single", borderColor: "cyan", backgroundColor: "#121212", paddingLeft: 1, paddingRight: 1, paddingTop: 1, paddingBottom: 1, children: [_jsx("text", { fg: "cyan", children: _jsx("strong", { children: "PROMPT" }) }), _jsx(MarkdownTextComponent, { content: question, showContentCopyControl: true, showCodeCopyControls: true })] }));
|
|
24
24
|
export const SearchStatus = ({ isIndexingFiles, repositoryFiles, searchRoot, hasSearchRoot, }) => (_jsxs("box", { flexDirection: "column", marginBottom: 0, width: "100%", children: [_jsx("text", { fg: "gray", wrapMode: "char", children: hasSearchRoot
|
|
25
25
|
? `#search root: ${searchRoot}`
|
|
26
26
|
: '#search root: no search root' }), _jsx("text", { fg: "gray", children: isIndexingFiles
|
|
@@ -33,5 +33,5 @@ export const ClipboardStatus = ({ status }) => (_jsx("text", { fg: status.starts
|
|
|
33
33
|
export const AttachmentsDisplay = ({ queuedAttachments, }) => (_jsxs("box", { flexDirection: "column", width: "100%", gap: 0, children: [_jsxs("text", { fg: "yellow", children: [_jsx("strong", { children: "QUEUED ATTACHMENTS" }), " (Delete placeholder text to remove)"] }), queuedAttachments.map((attachment, index) => (_jsxs("text", { fg: "gray", wrapMode: "word", children: ["[File ", index + 1, "] ", attachment.label] }, attachment.id)))] }));
|
|
34
34
|
export const SendButton = () => (_jsx("box", { backgroundColor: "cyan", paddingLeft: 1, paddingRight: 1, alignSelf: "flex-start", marginBottom: 0, children: _jsxs("text", { fg: "black", children: [_jsx("strong", { children: "Send" }), " \u2303S"] }) }));
|
|
35
35
|
export const HelpText = ({ hasOptions }) => (_jsx("text", { fg: "gray", wrapMode: "word", children: hasOptions
|
|
36
|
-
? 'Enter/Ctrl+J newline (or #search apply) • #search nav: ↑/↓ or Ctrl+N/P • Tab mode switch • #path for repo file autocomplete • Cmd/Ctrl+C copy • Cmd/Ctrl+V paste/attach'
|
|
37
|
-
: 'Enter/Ctrl+J newline • #search nav: ↑/↓ or Ctrl+N/P • Enter/Tab #search apply • #path for repo file autocomplete • Cmd/Ctrl+C copy • Cmd/Ctrl+V paste/attach' }));
|
|
36
|
+
? 'Enter/Ctrl+J newline (or #search apply) • #search nav: ↑/↓ or Ctrl+N/P • Tab mode switch • #path for repo file autocomplete • Cmd/Ctrl+C copy input • Cmd/Ctrl+V paste/attach • Cmd/Ctrl+Z undo • Cmd/Ctrl+Shift+Z redo'
|
|
37
|
+
: 'Enter/Ctrl+J newline • #search nav: ↑/↓ or Ctrl+N/P • Enter/Tab #search apply • #path for repo file autocomplete • Cmd/Ctrl+C copy input • Cmd/Ctrl+V paste/attach • Cmd/Ctrl+Z undo • Cmd/Ctrl+Shift+Z redo' }));
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
3
|
import notifier from 'node-notifier';
|
|
@@ -86,12 +85,13 @@ const server = new McpServer({
|
|
|
86
85
|
// Conditionally register tools based on command-line arguments
|
|
87
86
|
if (isToolEnabled('request_user_input')) {
|
|
88
87
|
// Use properties from the imported tool object
|
|
89
|
-
server.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
server.registerTool('request_user_input', {
|
|
89
|
+
// Need to handle description potentially being a function
|
|
90
|
+
description: typeof requestUserInputTool.description === 'function'
|
|
91
|
+
? requestUserInputTool.description(globalTimeoutSeconds)
|
|
92
|
+
: requestUserInputTool.description,
|
|
93
|
+
inputSchema: requestUserInputTool.schema, // Use schema property
|
|
94
|
+
}, async (args) => {
|
|
95
95
|
// Use inferred args type
|
|
96
96
|
const { projectName, message, predefinedOptions, baseDirectory } = args;
|
|
97
97
|
try {
|
|
@@ -126,12 +126,13 @@ if (isToolEnabled('request_user_input')) {
|
|
|
126
126
|
}
|
|
127
127
|
if (isToolEnabled('message_complete_notification')) {
|
|
128
128
|
// Use properties from the imported tool object
|
|
129
|
-
server.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
server.registerTool('message_complete_notification', {
|
|
130
|
+
// Description is a string here, but handle consistently
|
|
131
|
+
description: typeof messageCompleteNotificationTool.description === 'function'
|
|
132
|
+
? messageCompleteNotificationTool.description(globalTimeoutSeconds) // Should not happen based on definition, but safe
|
|
133
|
+
: messageCompleteNotificationTool.description,
|
|
134
|
+
inputSchema: messageCompleteNotificationTool.schema, // Use schema property
|
|
135
|
+
}, (args) => {
|
|
135
136
|
// Use inferred args type
|
|
136
137
|
const { projectName, message } = args;
|
|
137
138
|
notifier.notify({ title: projectName, message });
|
|
@@ -149,12 +150,13 @@ if (isToolEnabled('message_complete_notification')) {
|
|
|
149
150
|
// Each tool must be checked individually based on filtered capabilities
|
|
150
151
|
if (isToolEnabled('start_intensive_chat')) {
|
|
151
152
|
// Use properties from the imported intensiveChatTools object
|
|
152
|
-
server.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
server.registerTool('start_intensive_chat', {
|
|
154
|
+
// Description is a function here
|
|
155
|
+
description: typeof intensiveChatTools.start.description === 'function'
|
|
156
|
+
? intensiveChatTools.start.description(globalTimeoutSeconds)
|
|
157
|
+
: intensiveChatTools.start.description,
|
|
158
|
+
inputSchema: intensiveChatTools.start.schema, // Use schema property
|
|
159
|
+
}, async (args) => {
|
|
158
160
|
// Use inferred args type
|
|
159
161
|
const { sessionTitle, baseDirectory } = args;
|
|
160
162
|
try {
|
|
@@ -194,12 +196,13 @@ if (isToolEnabled('start_intensive_chat')) {
|
|
|
194
196
|
}
|
|
195
197
|
if (isToolEnabled('ask_intensive_chat')) {
|
|
196
198
|
// Use properties from the imported intensiveChatTools object
|
|
197
|
-
server.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
server.registerTool('ask_intensive_chat', {
|
|
200
|
+
// Description is a string here
|
|
201
|
+
description: typeof intensiveChatTools.ask.description === 'function'
|
|
202
|
+
? intensiveChatTools.ask.description(globalTimeoutSeconds) // Should not happen, but safe
|
|
203
|
+
: intensiveChatTools.ask.description,
|
|
204
|
+
inputSchema: intensiveChatTools.ask.schema, // Use schema property
|
|
205
|
+
}, async (args) => {
|
|
203
206
|
// Use inferred args type
|
|
204
207
|
const { sessionId, question, predefinedOptions, baseDirectory } = args;
|
|
205
208
|
const activeSession = activeChatSessions.get(sessionId);
|
|
@@ -272,12 +275,13 @@ if (isToolEnabled('ask_intensive_chat')) {
|
|
|
272
275
|
}
|
|
273
276
|
if (isToolEnabled('stop_intensive_chat')) {
|
|
274
277
|
// Use properties from the imported intensiveChatTools object
|
|
275
|
-
server.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
server.registerTool('stop_intensive_chat', {
|
|
279
|
+
// Description is a string here
|
|
280
|
+
description: typeof intensiveChatTools.stop.description === 'function'
|
|
281
|
+
? intensiveChatTools.stop.description(globalTimeoutSeconds) // Should not happen, but safe
|
|
282
|
+
: intensiveChatTools.stop.description,
|
|
283
|
+
inputSchema: intensiveChatTools.stop.schema, // Use schema property
|
|
284
|
+
}, async (args) => {
|
|
281
285
|
// Use inferred args type
|
|
282
286
|
const { sessionId } = args;
|
|
283
287
|
const activeSession = activeChatSessions.get(sessionId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rawwee/interactive-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,6 +30,14 @@
|
|
|
30
30
|
"author": "",
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"description": "",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/josippapez/interactive-mcp-server.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/josippapez/interactive-mcp-server#readme",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/josippapez/interactive-mcp-server/issues"
|
|
40
|
+
},
|
|
33
41
|
"devDependencies": {
|
|
34
42
|
"@eslint/js": "^10.0.1",
|
|
35
43
|
"@semantic-release/commit-analyzer": "^13.0.1",
|