@achieveai/hitl-mcp-server 1.0.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2025 Human-in-the-Loop MCP Server Contributors
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+
19
+ For the full text of the GNU General Public License Version 3,
20
+ please visit: https://www.gnu.org/licenses/gpl-3.0.txt
package/README.md ADDED
@@ -0,0 +1,306 @@
1
+ # Human In The Loop MCP Server
2
+
3
+ A Model Context Protocol (MCP) server that enables LLM agents to request human input through interactive dialog boxes. This tool provides a seamless way for AI agents to ask for clarification, make decisions with human guidance, and handle ambiguous situations.
4
+
5
+ ## Features
6
+
7
+ - **Interactive Dialog UI**: Opens a browser-based dialog for user interaction
8
+ - **Multiple Choice Questions**: Support for both single and multiple selection
9
+ - **Custom Input**: "Other" field for free-text responses
10
+ - **Cross-Platform**: Works on Windows, macOS, and Linux
11
+ - **Timeout Support**: Configurable timeouts for time-sensitive decisions
12
+ - **STDIO Transport**: Easy integration with Claude Desktop and other MCP clients
13
+
14
+ ## Installation
15
+
16
+ ### Prerequisites
17
+
18
+ - Node.js 18+ and npm
19
+ - A browser (for displaying dialogs)
20
+
21
+ ### From Source
22
+
23
+ ```bash
24
+ # Clone the repository
25
+ git clone <repository-url>
26
+ cd hitl-mcp-server
27
+
28
+ # Install dependencies
29
+ npm install
30
+
31
+ # Build the TypeScript code
32
+ npm run build
33
+
34
+ # Test the installation
35
+ npm run dev
36
+ ```
37
+
38
+ ### Global Installation
39
+
40
+ ```bash
41
+ # Build first
42
+ npm run build
43
+
44
+ # Install globally
45
+ npm install -g .
46
+
47
+ # Now you can run it from anywhere
48
+ hitl-mcp-server
49
+ ```
50
+
51
+ ## Configuration
52
+
53
+ Pre-configured examples are available in the `config/` directory for different MCP clients.
54
+
55
+ ### Claude Desktop Configuration
56
+
57
+ Add the server to your Claude Desktop config file:
58
+
59
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
60
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
61
+ **Linux**: `~/.config/claude/claude_desktop_config.json`
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "human-in-the-loop": {
67
+ "command": "node",
68
+ "args": ["D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server\\dist\\index.js"],
69
+ "env": {
70
+ "NODE_ENV": "production"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### VS Code Configuration
78
+
79
+ Create `.vscode/mcp.json` in your workspace:
80
+
81
+ ```json
82
+ {
83
+ "mcpServers": {
84
+ "human-in-the-loop": {
85
+ "command": "npx",
86
+ "args": ["-y", "@hitl/mcp-server"],
87
+ "env": {
88
+ "NODE_ENV": "production"
89
+ }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### Cursor IDE Configuration
96
+
97
+ Add to your Cursor settings:
98
+
99
+ ```json
100
+ {
101
+ "mcpServers": {
102
+ "human-in-the-loop": {
103
+ "name": "Human In The Loop",
104
+ "command": "node",
105
+ "args": ["./dist/index.js"],
106
+ "cwd": "D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server",
107
+ "transport": "stdio",
108
+ "autoStart": false
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### NPM Global Installation
115
+
116
+ ```bash
117
+ # Install globally from npm (when published)
118
+ npm install -g @hitl/mcp-server
119
+
120
+ # Then use in any config:
121
+ {
122
+ "mcpServers": {
123
+ "human-in-the-loop": {
124
+ "command": "hitl-mcp-server"
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## Usage
131
+
132
+ Once configured, the AI agent can use the `ask_human` tool to request input:
133
+
134
+ ### Example: Single Choice
135
+
136
+ ```javascript
137
+ {
138
+ "question": "Which database should I use for this project?",
139
+ "options": [
140
+ {
141
+ "label": "PostgreSQL",
142
+ "value": "postgres",
143
+ "description": "Robust relational database with advanced features"
144
+ },
145
+ {
146
+ "label": "MongoDB",
147
+ "value": "mongo",
148
+ "description": "Flexible document database for unstructured data"
149
+ },
150
+ {
151
+ "label": "SQLite",
152
+ "value": "sqlite",
153
+ "description": "Lightweight embedded database"
154
+ }
155
+ ],
156
+ "allowMultiple": false,
157
+ "allowOther": true,
158
+ "context": "This is for a medium-scale web application with complex queries"
159
+ }
160
+ ```
161
+
162
+ ### Example: Multiple Choice
163
+
164
+ ```javascript
165
+ {
166
+ "question": "Which files should I include in the commit?",
167
+ "options": [
168
+ {
169
+ "label": "src/index.ts",
170
+ "value": "index"
171
+ },
172
+ {
173
+ "label": "src/utils.ts",
174
+ "value": "utils"
175
+ },
176
+ {
177
+ "label": "README.md",
178
+ "value": "readme"
179
+ }
180
+ ],
181
+ "allowMultiple": true,
182
+ "allowOther": false,
183
+ "context": "Several files have been modified"
184
+ }
185
+ ```
186
+
187
+ ### Example: With Timeout
188
+
189
+ ```javascript
190
+ {
191
+ "question": "Should I proceed with the deployment?",
192
+ "options": [
193
+ {
194
+ "label": "Yes, deploy now",
195
+ "value": "yes"
196
+ },
197
+ {
198
+ "label": "No, cancel",
199
+ "value": "no"
200
+ }
201
+ ],
202
+ "allowMultiple": false,
203
+ "allowOther": false,
204
+ "timeout": 30000 // 30 seconds
205
+ }
206
+ ```
207
+
208
+ ## Response Format
209
+
210
+ The tool returns a JSON response:
211
+
212
+ ```javascript
213
+ {
214
+ "success": true,
215
+ "timestamp": 1703001234567,
216
+ "response": "selected_value", // or array for multiple selection
217
+ "responseType": "selection" // or "custom" for other text, "none" if skipped
218
+ }
219
+ ```
220
+
221
+ ## Testing
222
+
223
+ ### Run Unit Tests
224
+
225
+ ```bash
226
+ npm test
227
+ ```
228
+
229
+ ### Test Dialog Manager
230
+
231
+ ```bash
232
+ npm run build
233
+ node dist/test-client.js
234
+ ```
235
+
236
+ This will open test dialogs to verify the UI is working correctly.
237
+
238
+ ### Manual Testing with MCP Inspector
239
+
240
+ You can use the MCP Inspector tool to test the server:
241
+
242
+ ```bash
243
+ npx @modelcontextprotocol/inspector node dist/index.js
244
+ ```
245
+
246
+ ## Development
247
+
248
+ ### Project Structure
249
+
250
+ ```
251
+ hitl-mcp-server/
252
+ ├── src/
253
+ │ ├── index.ts # Main MCP server implementation
254
+ │ ├── dialog-manager.ts # Dialog UI and HTTP server
255
+ │ └── test-client.ts # Test client for dialog manager
256
+ ├── dist/ # Compiled JavaScript (after build)
257
+ ├── package.json
258
+ ├── tsconfig.json
259
+ └── README.md
260
+ ```
261
+
262
+ ### Available Scripts
263
+
264
+ - `npm run build` - Compile TypeScript to JavaScript
265
+ - `npm run dev` - Run in development mode with auto-reload
266
+ - `npm test` - Run unit tests
267
+ - `npm run typecheck` - Check TypeScript types without building
268
+
269
+ ## Why Use This Tool?
270
+
271
+ LLM agents often encounter situations requiring human judgment:
272
+
273
+ 1. **Ambiguous Requirements**: When instructions are unclear or contradictory
274
+ 2. **Critical Decisions**: Before performing irreversible actions
275
+ 3. **Multiple Valid Approaches**: When several solutions are equally valid
276
+ 4. **Missing Context**: When additional information is needed
277
+ 5. **Subjective Choices**: Design decisions, naming conventions, etc.
278
+
279
+ This tool ensures AI agents can gracefully handle these situations by requesting human input rather than making assumptions or failing silently.
280
+
281
+ ## Troubleshooting
282
+
283
+ ### Dialog doesn't open
284
+
285
+ - Check if port 3000-5000 range is available
286
+ - Ensure your default browser is properly configured
287
+ - Check the server logs for error messages
288
+
289
+ ### Timeout errors
290
+
291
+ - Increase the timeout value in your request
292
+ - Ensure the dialog window has focus
293
+
294
+ ### Server won't start
295
+
296
+ - Check if another instance is already running
297
+ - Verify Node.js version is 18 or higher
298
+ - Run `npm install` to ensure all dependencies are installed
299
+
300
+ ## License
301
+
302
+ MIT
303
+
304
+ ## Contributing
305
+
306
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "human-in-the-loop": {
4
+ "command": "node",
5
+ "args": ["D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server\\dist\\index.js"],
6
+ "env": {
7
+ "NODE_ENV": "production"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "mcpServers": {
3
+ "human-in-the-loop": {
4
+ "name": "Human In The Loop",
5
+ "description": "Interactive dialog system for getting human feedback",
6
+ "command": "node",
7
+ "args": ["./dist/index.js"],
8
+ "cwd": "D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server",
9
+ "env": {
10
+ "NODE_ENV": "production"
11
+ },
12
+ "transport": "stdio",
13
+ "autoStart": false,
14
+ "restartOnFailure": true,
15
+ "maxRestarts": 3
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "mcpServers": {
3
+ "human-in-the-loop": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@hitl/mcp-server"
8
+ ],
9
+ "env": {
10
+ "NODE_ENV": "production"
11
+ },
12
+ "capabilities": {
13
+ "tools": true
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dialog-manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-manager.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dialog-manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ import { DialogManager } from '../dialog-manager.js';
2
+ import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
3
+ describe('DialogManager', () => {
4
+ let manager;
5
+ beforeEach(() => {
6
+ manager = new DialogManager();
7
+ });
8
+ afterEach(async () => {
9
+ await manager.close();
10
+ });
11
+ describe('initialization', () => {
12
+ it('should initialize the server on a random port', async () => {
13
+ const port = await manager.initialize();
14
+ expect(port).toBeGreaterThan(0);
15
+ expect(port).toBeLessThanOrEqual(65535);
16
+ });
17
+ it('should not reinitialize if already initialized', async () => {
18
+ const port1 = await manager.initialize();
19
+ const port2 = await manager.initialize();
20
+ expect(port1).toBe(port2);
21
+ });
22
+ });
23
+ describe('HTML generation', () => {
24
+ it('should escape HTML in user input', () => {
25
+ const manager = new DialogManager();
26
+ const html = manager.generateDialogHTML({
27
+ id: 'test',
28
+ question: '<script>alert("XSS")</script>',
29
+ options: [
30
+ {
31
+ label: '<b>Bold</b>',
32
+ value: 'test',
33
+ description: '"Quotes" & \'apostrophes\''
34
+ }
35
+ ],
36
+ allowMultiple: false,
37
+ allowOther: true
38
+ });
39
+ expect(html).not.toContain('<script>alert("XSS")</script>');
40
+ expect(html).toContain('&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;');
41
+ expect(html).not.toContain('<b>Bold</b>');
42
+ expect(html).toContain('&lt;b&gt;Bold&lt;/b&gt;');
43
+ });
44
+ it('should include context when provided', () => {
45
+ const manager = new DialogManager();
46
+ const html = manager.generateDialogHTML({
47
+ id: 'test',
48
+ question: 'Test question',
49
+ options: [{ label: 'Option 1', value: 'opt1' }],
50
+ allowMultiple: false,
51
+ allowOther: false,
52
+ context: 'Important context information'
53
+ });
54
+ expect(html).toContain('Important context information');
55
+ expect(html).toContain('Context:');
56
+ });
57
+ it('should not include context section when not provided', () => {
58
+ const manager = new DialogManager();
59
+ const html = manager.generateDialogHTML({
60
+ id: 'test',
61
+ question: 'Test question',
62
+ options: [{ label: 'Option 1', value: 'opt1' }],
63
+ allowMultiple: false,
64
+ allowOther: false
65
+ });
66
+ expect(html).not.toContain('Context:');
67
+ });
68
+ });
69
+ describe('dialog options', () => {
70
+ it('should render radio buttons for single choice', () => {
71
+ const manager = new DialogManager();
72
+ const html = manager.generateDialogHTML({
73
+ id: 'test',
74
+ question: 'Choose one',
75
+ options: [
76
+ { label: 'A', value: 'a' },
77
+ { label: 'B', value: 'b' }
78
+ ],
79
+ allowMultiple: false,
80
+ allowOther: false
81
+ });
82
+ expect(html).toContain('type="radio"');
83
+ expect(html).not.toContain('type="checkbox"');
84
+ });
85
+ it('should render checkboxes for multiple choice', () => {
86
+ const manager = new DialogManager();
87
+ const html = manager.generateDialogHTML({
88
+ id: 'test',
89
+ question: 'Choose many',
90
+ options: [
91
+ { label: 'A', value: 'a' },
92
+ { label: 'B', value: 'b' }
93
+ ],
94
+ allowMultiple: true,
95
+ allowOther: false
96
+ });
97
+ expect(html).toContain('type="checkbox"');
98
+ expect(html).not.toContain('type="radio"');
99
+ });
100
+ it('should include other field when allowed', () => {
101
+ const manager = new DialogManager();
102
+ const html = manager.generateDialogHTML({
103
+ id: 'test',
104
+ question: 'Choose',
105
+ options: [{ label: 'A', value: 'a' }],
106
+ allowMultiple: false,
107
+ allowOther: true
108
+ });
109
+ expect(html).toContain('other-input');
110
+ expect(html).toContain('Other (please specify)');
111
+ });
112
+ it('should not include other field when not allowed', () => {
113
+ const manager = new DialogManager();
114
+ const html = manager.generateDialogHTML({
115
+ id: 'test',
116
+ question: 'Choose',
117
+ options: [{ label: 'A', value: 'a' }],
118
+ allowMultiple: false,
119
+ allowOther: false
120
+ });
121
+ expect(html).not.toContain('other-input');
122
+ expect(html).not.toContain('Other (please specify)');
123
+ });
124
+ });
125
+ describe('timeout handling', () => {
126
+ it('should reject with timeout error after specified duration', async () => {
127
+ await manager.initialize();
128
+ const dialogPromise = manager.showDialog({
129
+ id: 'timeout-test',
130
+ question: 'This will timeout',
131
+ options: [{ label: 'Option', value: 'opt' }],
132
+ allowMultiple: false,
133
+ allowOther: false,
134
+ timeout: 100
135
+ });
136
+ await expect(dialogPromise).rejects.toThrow('Dialog timeout');
137
+ }, 10000);
138
+ });
139
+ });
140
+ //# sourceMappingURL=dialog-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/dialog-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { EventEmitter } from 'events';
2
+ export interface DialogOption {
3
+ label: string;
4
+ value: string;
5
+ description?: string;
6
+ }
7
+ export interface DialogRequest {
8
+ id: string;
9
+ question: string;
10
+ options: DialogOption[];
11
+ allowMultiple: boolean;
12
+ allowOther: boolean;
13
+ context?: string;
14
+ timeout?: number;
15
+ }
16
+ export interface DialogResponse {
17
+ id: string;
18
+ selectedValues: string[];
19
+ otherText?: string;
20
+ timestamp: number;
21
+ }
22
+ export declare class DialogManager extends EventEmitter {
23
+ private app;
24
+ private port;
25
+ private pendingDialogs;
26
+ private server;
27
+ private isInitialized;
28
+ constructor(port?: number);
29
+ private setupRoutes;
30
+ private generateDialogHTML;
31
+ private escapeHtml;
32
+ initialize(): Promise<number>;
33
+ showDialog(request: DialogRequest): Promise<DialogResponse>;
34
+ close(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=dialog-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-manager.d.ts","sourceRoot":"","sources":["../src/dialog-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,cAAc,CAKnB;IACH,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,aAAa,CAAkB;gBAE3B,IAAI,GAAE,MAAU;IAQ5B,OAAO,CAAC,WAAW;IAgDnB,OAAO,CAAC,kBAAkB;IAqW1B,OAAO,CAAC,UAAU;IAWZ,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAoB7B,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAkC3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}