About Human Loop
Human Loop is an MCP server in the Browser category: browser-based human-in-the-loop MCP server — ask your AI agent to ask you via polished browser dialogs.
Install
claude mcp add human-loop -- npx -y @dzulfiikar/human-loop-mcpnpx -y @dzulfiikar/human-loop-mcpThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Tools (7)
get_human_loop_promptReturns guidance text on when to use the tools
Parameters not published.
get_multiline_inputLarge text area with autocomplete and file attachments
Parameters not published.
get_user_choiceSingle or multi-select from a list of choices
Parameters not published.
get_user_inputSingle-line text, password, integer, or float input
Parameters not published.
health_checkReturns server health status and available tools
Parameters not published.
show_confirmation_dialogBinary confirm/cancel dialog
Parameters not published.
show_info_messageInformational message with acknowledgement
Parameters not published.
Ask AI
Ask AI about Human Loop
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
What Is This?
An MCP (Model Context Protocol) server that gives AI agents a way to ask the human operator questions through the browser.
- A lightweight localhost HTTP server spins up
- Your default browser opens a dialog page
- You fill in the form (optionally attaching files) and submit
- The response flows back to the agent through MCP
No Python, no Tkinter, no Electron — just a Node.js process, a browser tab, and clean HTML.
Why?
GUI-based human-in-the-loop tools often break on macOS (Accessibility permissions, focus stealing, Python framework builds). This project sidesteps all of that by using the browser as the UI layer — it works everywhere Node.js runs.
Features
| 7 MCP tools | Text input, multiline, choice, confirmation, info, health check, and usage guidance |
| File attachments | Drag-and-drop, paste, or click-to-upload files in the multiline dialog. Files are base64-encoded and returned alongside the text response (5 MB per-file limit) |
| Autocomplete | @ files, # GitHub issues/PRs, / slash commands, ? keyboard shortcuts |
| Dark/light mode | Follows system preference automatically |
| Keyboard-first | Cmd+Enter submit, Esc cancel, arrow-key navigation in dropdowns |
| Command-palette UI | Linear/Raycast-inspired design with purple accents, monospace labels, noise texture background |
| Zero bloat | Only two runtime dependencies: @modelcontextprotocol/sdk and zod |
| Single-file HTML | No static assets, no bundler — fully server-rendered |
Install
npm (recommended)
npm install -g human-loop-mcp
Or run directly without installing:
npx human-loop-mcp
From source
git clone https://github.com/dzulfiikar/human-loop-mcp.git
cd human-loop-mcp
npm install
npm run build
Quick Start
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"human-loop": {
"command": "npx",
"args": ["-y", "human-loop-mcp"]
}
}
}
Cursor / Windsurf
Add to .cursor/mcp.json or equivalent:
{
"mcpServers": {
"human-loop": {
"command": "npx",
"args": ["-y", "human-loop-mcp"]
}
}
}
GitHub Copilot CLI
[mcp_servers.human-loop]
command = "npx"
args = ["-y", "human-loop-mcp"]
From source (development)
[mcp_servers.human-loop-dev]
command = "npx"
args = ["tsx", "/path/to/human-loop-mcp/src/index.ts"]
Tools
| Tool | Description |
|---|---|
get_user_input |
Single-line text, password, integer, or float input |
get_user_choice |
Single or multi-select from a list of choices |
get_multiline_input |
Large text area with autocomplete and file attachments |
show_confirmation_dialog |
Binary confirm/cancel dialog |
show_info_message |
Informational message with acknowledgement |
get_human_loop_prompt |
Returns guidance text on when to use the tools |
health_check |
Returns server health status and available tools |
Example: Text Input
{
"title": "API Key",
"prompt": "Enter your OpenAI API key:",
"input_type": "password"
}
Example: Choice
{
"title": "Database",
"prompt": "Which database should I use?",
"choices": ["PostgreSQL", "MySQL", "SQLite"],
"allow_multiple": false
}
Example: Confirmation
{
"title": "Deploy",
"message": "Deploy v2.1.0 to production?",
"confirm_label": "Deploy",
"cancel_label": "Abort"
}
File Attachments
The get_multiline_input dialog supports file attachments through three methods:
| Method | How |
|---|---|
| Drag and drop | Drag files onto the textarea — a drop overlay appears |
| Paste | Cmd+V / Ctrl+V with an image or file in the clipboard |
| Upload button | Click the paperclip "Attach" button below the textarea |
Attachment behavior
- Any file type is accepted
- 5 MB per-file limit — oversized files are rejected with an inline error
- Files are base64-encoded and returned in the tool result alongside the text value
- Image previews are shown as thumbnails in the attachment chips
- Each chip shows the file name, size, and a remove button
- When no files are attached, the result is identical to the previous format (fully backward-compatible)
Result format
When attachments are present, the get_multiline_input tool returns:
{
"action": "submit",
"value": "Here is the screenshot",
"attachments": [
{
"name": "screenshot.png",
"type": "image/png",
"size": 48210,
"data": "iVBORw0KGgo..."
}
]
}
When no attachments are provided, the attachments field is omitted entirely.
Configuration
Environment variables
| Variable | Default | Description |
|---|---|---|
HITL_HOST |
127.0.0.1 |
HTTP server bind address |
HITL_PORT |
(ephemeral) | Fixed HTTP port. If unset, the OS assigns a random port |
HITL_NO_LAUNCH |
(unset) | Set to 1 to print dialog URLs to stderr instead of auto-opening the browser |
Programmatic usage
import { BrowserDialogServer } from "human-loop-mcp/browser/browser-dialog-server";
const server = new BrowserDialogServer({
port: 8080,
launchUrl: async (url) => {
console.log(`Open: ${url}`);
},
});
Architecture
┌──────────────────────────────────────────┐
│ MCP Client (AI Agent) │
│ Claude / Cursor / Copilot CLI │
└──────────────┬───────────────────────────┘
│ stdio (JSON-RPC)
┌──────────────▼───────────────────────────┐
│ index.ts Tool registration │
│ service.ts Business logic │
│ browser-dialog-server.ts HTTP + APIs │
│ dialog-session-manager.ts Sessions │
│ html.ts HTML/CSS/JS renderer │
└──────────────┬───────────────────────────┘
│ HTTP (localhost)
┌──────────────▼───────────────────────────┐
│ Browser Dialog UI │
│ Forms · Autocomplete · Attachments │
│ Dark/light · Keyboard shortcuts │
└──────────────────────────────────────────┘
Data flow
- MCP client calls a tool (e.g.
get_multiline_input) via stdio JSON-RPC index.tsroutes the call toHumanLoopServiceservice.tstransforms args and callsBrowserDialogServer.openDialog()browser-dialog-server.tscreates a session, starts HTTP if needed, opens the browserhtml.tsrenders a self-contained HTML page with the dialog form- User submits (with optional file attachments) — the POST handler validates and resolves the session promise
- Response flows back through MCP to the AI agent, including any base64-encoded attachments
Development
npm install # Install dependencies
npm run dev # Run from source (tsx, hot-reload)
npm run build # Compile to dist/
npm test # Run tests (Vitest)
npm run typecheck # Type-check without emitting
Project structure
src/
├── index.ts MCP server entry point & tool registration
├── service.ts Tool handler business logic
└── browser/
├── browser-dialog-server.ts HTTP server, browser launcher, API endpoints
├── dialog-session-manager.ts Session lifecycle, validation & attachment types
└── html.ts Dialog page renderer (forms, autocomplete, attachments)
tests/
├── service.test.ts
├── dialog-session-manager.test.ts
└── browser-dialog-server.test.ts
Contributing
See CONTRIBUTING.md for development setup, code style, and PR guidelines.
License
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.