AgentStack
MCP verified Apache-2.0 Self-run

Hitl Mcp Cli

mcp-geehexx-hitl-mcp-cli · by geehexx

A HITL (Human-In-The-Loop) MCP server that runs on CLI.

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add mcp-geehexx-hitl-mcp-cli

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Hitl Mcp Cli? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

🤝 HITL MCP CLI

Human-in-the-Loop MCP Server — Bridge the gap between AI autonomy and human judgment

[](https://opensource.org/licenses/Apache-2.0) [](https://www.python.org/downloads/) [](https://modelcontextprotocol.io)

██╗  ██╗██╗████████╗██╗         ███╗   ███╗ ██████╗██████╗
██║  ██║██║╚══██╔══╝██║         ████╗ ████║██╔════╝██╔══██╗
███████║██║   ██║   ██║         ██╔████╔██║██║     ██████╔╝
██╔══██║██║   ██║   ██║         ██║╚██╔╝██║██║     ██╔═══╝
██║  ██║██║   ██║   ███████╗    ██║ ╚═╝ ██║╚██████╗██║
╚═╝  ╚═╝╚═╝   ╚═╝   ╚══════╝    ╚═╝     ╚═╝ ╚═════╝╚═╝

🎯 Why Human-in-the-Loop?

AI agents are transforming how we work, but they shouldn't operate in isolation. HITL MCP CLI enables AI agents to request human input at critical decision points, combining the speed of automation with the wisdom of human judgment.

The Problem

AI agents face situations where they need human guidance:

  • 🤔 Ambiguity: Requirements aren't always clear-cut
  • ⚠️ Risk: Some operations are too sensitive to automate blindly
  • 🎨 Preference: Multiple valid approaches exist, but humans have context
  • ✅ Validation: Assumptions need confirmation before proceeding

The Solution

HITL MCP CLI provides a standardized, elegant interface for AI agents to request human input without breaking their workflow. Instead of agents making potentially wrong assumptions or halting entirely, they can:

  • Ask clarifying questions when requirements are ambiguous
  • Request approval before destructive or sensitive operations
  • Present options and let humans choose the best approach
  • Confirm assumptions to ensure alignment with human intent

Real-World Scenarios

🤖 Agent: "I found 3 ways to implement this feature. Which approach do you prefer?"
👤 Human: [Selects Option B: Balanced performance and maintainability]
🤖 Agent: "Implementing Option B..."

🤖 Agent: "I'm about to delete 150 deprecated files. Proceed?"
👤 Human: "Yes, proceed"
🤖 Agent: "Deleted 150 files. ✅ Complete"

🤖 Agent: "Should I deploy to staging or production?"
👤 Human: "Staging first"
🤖 Agent: "Deploying to staging environment..."

✨ Features

  • 🎯 5 Interactive Tools: Collect input, ask questions, choose from options, confirm actions, and send notifications
  • 🖥️ Full TUI: Textual-based terminal UI with sessions panel, queue history, and collapsible messages
  • 🚀 Instant Setup: Works with uvx — no installation required
  • 🔌 MCP Standard: Seamless integration with any MCP-compatible AI agent
  • ⚡ Lightning Fast: Async-first design with minimal overhead
  • 🛡️ Type-Safe: Full type hints for reliability and IDE support
  • 📊 Interaction Logging: All tool calls logged to ~/.local/state/hitl-mcp/interactions.jsonl
  • 🔧 Customizable: Customize host/port, log level

⚠️ Critical Configuration

Timeout Setting Required: HITL operations require infinite timeout because human response time is unpredictable. Without this, tool calls will fail after 60 seconds.

Set "timeout": 0 in your MCP client configuration (see below).


🚀 Quick Start

Installation

# Run directly without installation (recommended)
uvx hitl-mcp-cli

# Or install globally
uv tool install hitl-mcp-cli

Start the Server

# Default: TUI mode on localhost:5555
hitl-mcp

# Custom host/port
hitl-mcp --host 0.0.0.0 --port 8080

# Using environment variables
export HITL_HOST=0.0.0.0
export HITL_PORT=8080
export HITL_LOG_LEVEL=INFO
hitl-mcp

Environment Variables:

  • HITL_HOST: Server host (default: 127.0.0.1)
  • HITL_PORT: Server port (default: 5555)
  • HITL_LOG_LEVEL: Logging level - DEBUG, INFO, WARNING, ERROR (default: ERROR)
  • HITL_NO_BANNER: Disable startup banner - true/false (default: false)

Configure Your AI Agent

Add to your MCP client configuration (e.g., Claude Desktop, Cline):

{
  "mcpServers": {
    "hitl": {
      "url": "http://127.0.0.1:5555/mcp",
      "transport": "streamable-http",
      "timeout": 0
    }
  }
}

⚠️ Important: Set "timeout": 0 for infinite timeout. Human input is unpredictable - users may take seconds or minutes to respond. The default 60-second MCP timeout will cause tool calls to fail if users don't respond quickly enough.

> Note: The server runs in stateless HTTP mode, which is required for MCP clients > that make independent HTTP requests (including Kiro CLI and most MCP clients).

That's it! Your AI agent can now request human input.


🛠️ Available Tools

1. hitl_collect — Collect Input

Collect a single input value from the user. Use for text, file paths, or multiline content.

When to use:

  • Collecting names, descriptions, or free-form input
  • Getting file/directory paths with completion
  • Requesting multi-line content (code snippets, descriptions)

Example:

name = await hitl_collect(
    message="What should we name this project?",
    default="my-project",
    validation_pattern=r"^[a-z0-9-]+$"
)

# Path input
config = await hitl_collect(
    message="Select configuration file:",
    input_type="path"
)

# Multiline input
description = await hitl_collect(
    message="Enter project description:",
    input_type="multiline"
)

Parameters:

  • message (str): Question to display
  • input_type (Literal["text", "path", "multiline"]): Input mode (default: "text")
  • default (str, optional): Pre-filled value
  • validation_pattern (str, optional): Regex pattern for validation
  • validation_message (str, optional): Custom validation error message
  • context (str, optional): Additional context displayed above the prompt
  • strip_whitespace (bool): Strip leading/trailing whitespace from input (default: False)
  • required (bool): Reject empty input (default: False)
  • path_type (Literal["file", "dir", "any"], optional): Validate path type when input_type="path"
  • agent_name (str, optional): Calling agent identifier (shown in Sessions panel)
  • project_id (str, optional): Project identifier for session grouping
  • step (int, optional): Current step number (shown as "Step X/Y")
  • total_steps (int, optional): Total steps in workflow
  • notes (str, optional): Freeform context displayed as a dimmed line below the message

2. hitl_ask — Ask a Question

Alias for hitl_collect. Use whichever name reads more naturally in your agent's workflow.


3. hitl_choose — Present Choices

Present a list of options for the user to select from. Supports single or multiple selection, fuzzy search for long lists, and rich option descriptions.

When to use:

  • Choosing between implementation approaches
  • Selecting deployment environments
  • Picking features to enable

Example:

# Simple choices
env = await hitl_choose(
    message="Which environment should I deploy to?",
    choices=["Development", "Staging", "Production"],
    default="Staging"
)

# Rich options with descriptions
approach = await hitl_choose(
    message="Select implementation approach:",
    options=[
        {"value": "fast", "label": "Fast", "description": "Quick but uses more memory"},
        {"value": "safe", "label": "Safe", "description": "Slower but reliable"},
    ]
)

# Multiple selections
features = await hitl_choose(
    message="Which features should I enable?",
    choices=["Authentication", "Caching", "Logging", "Monitoring"],
    multiple=True
)

Parameters:

  • message (str): Question to display
  • choices (list[str], optional): Simple option strings
  • options (list[dict], optional): Rich options with value/label/description
  • multiple (bool): Enable checkbox mode (default: False)
  • default (str, optional): Pre-selected option
  • fuzzy_search (bool, optional): Force fuzzy search on/off (auto for >15 items)
  • context (str, optional): Additional context displayed above the prompt
  • agent_name (str, optional): Calling agent identifier (shown in Sessions panel)
  • project_id (str, optional): Project identifier for session grouping
  • step (int, optional): Current step number (shown as "Step X/Y")
  • total_steps (int, optional): Total steps in workflow
  • notes (str, optional): Freeform context displayed as a dimmed line below the message

> Escape hatch: In multiple-selection mode, if the user selects all or none of the options, they are offered a free-text input to explain their intent.


4. hitl_confirm — Get Confirmation

Ask the user to confirm or reject an action. Use severity='high' for destructive operations.

When to use:

  • Before destructive operations (delete, overwrite)
  • Before expensive operations (API calls, deployments)
  • Confirming assumptions or interpretations

Example:

# Standard confirmation
result = await hitl_confirm(
    message="I will delete 50 unused dependencies. Proceed?",
    default=False
)
if result["action"] == "accept":
    ...

# High severity — requires typed "yes"
result = await hitl_confirm(
    message="Delete production database?",
    severity="high",
    context="This will affect 10,000 active users.\nDowntime: ~30 seconds."
)

# Timed confirmation
result = await hitl_confirm(
    message="Deploy to production?",
    severity="high",
    timeout_seconds=300
)
if result.get("timed_out"):
    print("Approval timed out")

Parameters:

  • message (str): Yes/no question
  • default (bool): Default answer (default: False)
  • severity (Literal["low", "medium", "high"]): Confirmation intensity (default: "medium")
  • context (str, optional): Additional context displayed in a panel above the prompt
  • timeout_seconds (int): Seconds to wait, 0 = infinite (default: 0)
  • agent_name (str, optional): Calling agent identifier (shown in Sessions panel)
  • project_id (str, optional): Project identifier for session grouping
  • step (int, optional): Current step number (shown as "Step X/Y")
  • total_steps (int, optional): Total steps in workflow
  • notes (str, optional): Freeform context displayed as a dimmed line below the message

Returns: {"action": "accept"|"decline"|"cancel"}. When timeout_seconds > 0, also includes "timed_out": bool.


5. hitl_notify — Display Notifications

Display a styled notification to the user. Non-blocking — does not wait for input.

When to use:

  • Confirming successful operations
  • Reporting errors or warnings
  • Providing progress updates

Example:

await hitl_notify(
    message="Successfully deployed v2.1.0 to production\n\nURL: https://app.example.com",
    level="success",
    title="Deployment Complete"
)

await hitl_notify(
    message="The old API will be removed in v3.0",
    level="warning",
    title="Deprecation Warning"
)

Parameters:

  • message (str): Detailed message (supports multi-line)
  • level (Literal["success", "info", "warning", "error"]): Visual style (default: "info")
  • title (str, optional): Notification title
  • agent_name (str, optional): Calling agent identifier (shown in Sessions panel)
  • project_id (str, optional): Project identifier for session grouping
  • step (int, optional): Current step number (shown as "Step X/Y")
  • total_steps (int, optional): Total steps in workflow
  • notes (str, optional): Freeform context displayed as a dimmed line below the notification

📖 Usage Patterns

Pattern 1: Clarification

When requirements are ambiguous, ask specific questions:

approach = await hitl_choose(
    message="I can implement this feature in two ways. Which do you prefer?",
    choices=[
        "Option A: Fast implementation, higher memory usage",
        "Option B: Slower but more memory efficient",
        "Option C: Balanced approach (recommended)"
    ],
    default="Option C: Balanced approach (recommended)"
)

Pattern 2: Approval Gate

Request approval before significant actions:

files_to_delete = find_unused_files()
result = await hitl_confirm(
    message=f"I found {len(files_to_delete)} unused files. Delete them?",
    default=False
)

if result["action"] == "accept":
    delete_files(files_to_delete)
    await hitl_notify(
        message=f"Deleted {len(files_to_delete)} unused files",
        level="success",
        title="Cleanup Complete"
    )
else:
    await hitl_notify(
        message="No files were deleted",
        level="info",
        title="Cancelled"
    )

Pattern 3: Information Gathering

Collect structured data through multiple prompts:

project_name = await hitl_collect(
    message="Project name:",
    validation_pattern=r"^[a-z0-9-]+$"
)

language = await hitl_choose(
    message="Programming language:",
    choices=["Python", "TypeScript", "Go", "Rust"]
)

features = await hitl_choose(
    message="Select features to include:",
    choices=["Testing", "Linting", "CI/CD", "Documentation"],
    multiple=True
)

output_dir = await hitl_collect(
    message="Output directory:",
    input_type="path"
)

Pattern 4: Progressive Disclosure

Start with high-level choices, then drill down:

action = await hitl_choose(
    message="What would you like to do?",
    choices=["Deploy", "Rollback", "View Logs", "Run Tests"]
)

if action == "Deploy":
    env = await hitl_choose(
        message="Deploy to which environment?",
        choices=["Staging", "Production"]
    )

    if env == "Production":
        result = await hitl_confirm(
            message="Deploy to PRODUCTION?",
            context="This will affect live users.",
            severity="high"
        )
        if result["action"] == "accept":
            await deploy_to_production()

🏗️ Architecture

AI Agent (Claude, GPT, etc.)
         ↓ HTTP (MCP Protocol)
    FastMCP Server
         ↓ Async Calls
      TUI Layer (Textual)
         ↓ Terminal I/O
        User

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed architecture documentation.


🖥️ TUI Features

The Textual-based TUI provides a rich terminal interface:

  • Sessions panel: Shows agent names and projects, color-coded by recency (active 15 items) automatically enable search filtering
  • ✅ Terminal compatibility: Works with screen readers through terminal emulators

See [docs/ACCESSIBILITY.md](docs/ACCESSIBILITY.md) for detailed accessibility information, testing methodology, and recommendations for users with diverse needs.


💻 VS Code Terminal

For the best experience in VS Code's integrated terminal, add to your settings.json:

{
  "terminal.integrated.allowChords": false,
  "terminal.integrated.sendKeybindingsToShell": true
}

This ensures Ctrl+\ (command palette) and other key bindings reach the TUI.

> Note: ctrl+b and ctrl+\ may be intercepted by VS Code. Add these to commandsToSkipShell in your VS Code settings, or use f2 (log level) and f3 (toggle sessions) as alternatives.


🔧 Troubleshooting

Tool Calls Timeout After 60 Seconds

Problem: Tools fail with "Request timed out" error when user takes longer than 60 seconds to respond.

Solution: Set "timeout": 0 in your MCP client configuration:

{
  "mcpServers": {
    "hitl": {
      "url": "http://127.0.0.1:5555/mcp",
      "transport": "streamable-http",
      "timeout": 0
    }
  }
}

Why: The MCP protocol has a default 60-second timeout. Human input is unpredictable - users may need minutes to make decisions. Setting timeout to 0 means infinite wait.

Server Won't Start

Problem: Port already in use.

Solution: Either stop the other process using port 5555, or start the server on a different port:

hitl-mcp --port 8080

Don't forget to update your MCP client configuration to match the new port.

Tools Not Appearing in Agent

Problem: Agent doesn't see the HITL tools.

Solution:

  1. Verify the server is running (hitl-mcp should show startup banner)
  2. Check you

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.