人机交互MCP工具

HITL MCP CLI是一款连接AI自主决策与人类判断的交互工具,通过标准化接口使AI代理在关键决策点请求人工输入。

  • by geehexx
  • Python
  • 本地部署
  • 5 星标
  • 更新于
在 GitHub 查看 geehexx/hitl-mcp-cli

使用说明

🤝 HITL MCP CLI

人在环MCP服务器 --弥合人工智能自主性和人类判断之间的差距

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

🎯 为什么人类在循环中?

人工智能代理正在改变我们的工作方式,但它们不应该孤立地运作。 HITL MCP CLI 使人工智能代理能够在关键决策点请求人类输入,将自动化的速度与人类判断的智慧相结合。

问题

AI代理面临需要人类指导的情况:

  • 🤔 歧义:要求并不总是很明确
  • ⚠️ 风险:有些操作过于敏感,不能盲目自动化
  • 🎨 偏好:存在多种有效方法,但人类有背景
  • ✅ 验证:继续之前需要确认假设

解决方案

HITL MCP CLI提供了一个 标准化、优雅的界面 AI代理可以在不破坏其工作流程的情况下请求人工输入。他们可以:

  • 提出澄清性问题 当需求不明确时
  • 请求批准 在破坏性或敏感操作之前
  • 展示选项 让人类选择最好的方法
  • 确认假设 确保与人类意图保持一致

现实世界场景

🤖 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..."

✨ 特性

  • 🎯 5互动工具:收集输入、提问、从选项中选择、确认操作和发送通知
  • 🖥️ 完整TUI:基于文本的终端UI,带有会话面板、队列历史记录和可折叠消息
  • 🚀 即时设置:与合作 uvx --无需安装
  • 🔌 MCP标准:与任何兼容MCP的AI代理无缝集成
  • ⚡ 迅速的:异步优先设计,开销最小
  • 🛡️ 类型安全:可靠性和IDE支持的完整类型提示
  • 📊 交互日志记录:记录到的所有工具调用 ~/.local/state/hitl-mcp/interactions.jsonl
  • 🔧 可定制的:自定义主机/端口、日志级别

⚠️ 关键配置

需要超时设置:HITL操作需要 无限超时 因为人类的反应时间是不可预测的。否则,工具调用将在60秒后失败。

集 "timeout": 0 在MCP客户端配置中(见下文)。


🚀 快速开始

安装

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

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

启动服务器

# 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

环境变量:

  • HITL_HOST:服务器主机(默认值:127.0.0.1)
  • HITL_PORT:服务器端口(默认值:5555)
  • HITL_LOG_LEVEL:日志记录级别-调试、信息、警告、错误(默认值:错误)
  • HITL_NO_BANNER:禁用启动横幅-true/false(默认值:false)

配置您的AI代理

添加到您的MCP客户端配置中(例如,Claude Desktop、Cline):

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

⚠️ 重要:设置 "timeout": 0 无限超时。人工输入是不可预测的——用户可能需要几秒钟或几分钟的时间才能做出回应。如果用户响应速度不够快,默认的60秒MCP超时将导致工具调用失败。

备注:服务器以无状态HTTP模式运行,这是MCP客户端所必需的 它们发出独立的HTTP请求(包括Kiro CLI和大多数MCP客户端)。

就是这样! 您的AI代理现在可以请求人工输入。


🛠️ 可用工具

1. hitl_collect --收集输入

从用户那里收集单个输入值。用于文本、文件路径或多行内容。

何时使用:

  • 收集名称、描述或自由形式的输入
  • 完成获取文件/目录路径
  • 请求多行内容(代码片段、描述)

示例:

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"
)

参数:

  • message (str):要显示的问题
  • input_type (文字[“文本”、“路径”、“多行”]):输入模式(默认:“文本”)
  • default (str,可选):预填值
  • validation_pattern (str,可选):用于验证的正则表达式模式
  • validation_message (str,可选):自定义验证错误消息
  • context (str,可选):提示上方显示的其他上下文
  • strip_whitespace (bool):从输入中删除前导/尾随空格(默认值:False)
  • required (bool):拒绝空输入(默认值:False)
  • path_type (Literal[“file”,“dir”,“any”],可选):在以下情况下验证路径类型 input_type="path"
  • agent_name (str,可选):调用代理标识符(显示在会话面板中)
  • project_id (str,可选):会话分组的项目标识符
  • step (int,可选):当前步骤号(显示为“步骤X/Y”)
  • total_steps (int,可选):工作流中的总步骤数
  • notes (str,可选):自由形式上下文在消息下方显示为灰色线条

2. hitl_ask --问一个问题

别名为 hitl_collect。在代理的工作流程中,使用读起来更自然的名称。


3. hitl_choose --当前选择

显示选项列表供用户选择。支持单选或多选、长列表模糊搜索和丰富的选项描述。

何时使用:

  • 在实施方法之间进行选择
  • 选择部署环境
  • 选择要启用的功能

示例:

# 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
)

参数:

  • message (str):要显示的问题
  • choices (list[str],可选):简单选项字符串
  • options (list[dict],可选):具有值/标签/描述的丰富选项
  • multiple (bool):启用复选框模式(默认值:False)
  • default (str,可选):预选选项
  • fuzzy_search (bool,可选):强制打开/关闭模糊搜索(自动搜索>15个项目)
  • context (str,可选):提示上方显示的其他上下文
  • agent_name (str,可选):调用代理标识符(显示在会话面板中)
  • project_id (str,可选):会话分组的项目标识符
  • step (int,可选):当前步骤号(显示为“步骤X/Y”)
  • total_steps (int,可选):工作流中的总步骤数
  • notes (str,可选):自由形式上下文在消息下方显示为灰色线条

安全舱口:在多选模式下,如果用户选择所有选项或不选择任何选项,他们将获得一个自由的文本输入来解释他们的意图。


4. hitl_confirm --获取确认

要求用户确认或拒绝操作。对于破坏性操作,使用严重性=“高”。

何时使用:

  • 在执行破坏性操作(删除、覆盖)之前
  • 在昂贵的操作(API调用、部署)之前
  • 确认假设或解释

示例:

# 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")

参数:

  • message (str):是/否问题
  • default (bool):默认答案(默认值:False)
  • severity (文字[“低”、“中”、“高”]):确认强度(默认值:“中”)
  • context (str,可选):在提示上方的面板中显示其他上下文
  • timeout_seconds (int):等待秒数,0=无限(默认值:0)
  • agent_name (str,可选):调用代理标识符(显示在会话面板中)
  • project_id (str,可选):会话分组的项目标识符
  • step (int,可选):当前步骤号(显示为“步骤X/Y”)
  • total_steps (int,可选):工作流中的总步骤数
  • notes (str,可选):自由形式上下文在消息下方显示为灰色线条

退货: {"action": "accept"|"decline"|"cancel"}.何时 timeout_seconds > 0,还包括 "timed_out": bool.


5. hitl_notify --显示通知

向用户显示样式化通知。非阻塞——不等待输入。

何时使用:

  • 确认操作成功
  • 报告错误或警告
  • 提供进度更新

示例:

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"
)

参数:

  • message (str):详细消息(支持多行)
  • level (文字[“成功”、“信息”、“警告”、“错误”]):视觉样式(默认值:“信息”)
  • title (str,可选):通知标题
  • agent_name (str,可选):调用代理标识符(显示在会话面板中)
  • project_id (str,可选):会话分组的项目标识符
  • step (int,可选):当前步骤号(显示为“步骤X/Y”)
  • total_steps (int,可选):工作流中的总步骤数
  • notes (str,可选):自由形式上下文在通知下方显示为灰色线条

📖 使用模式

模式1:澄清

当需求不明确时,问具体问题:

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)"
)

模式2:审批门

在采取重大行动之前请求批准:

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"
    )

模式3:信息收集

通过多个提示收集结构化数据:

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"
)

模式4:渐进式披露

从高级选择开始,然后深入:

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()

🏗️ 建筑

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

看 docs/ARCHITECTURE.md 获取详细的架构文档。


🖥️ TUI功能

基于文本的TUI提供了一个丰富的终端界面:

  • 会议小组:显示代理名称和项目,按最近度进行颜色编码(活动<10min=亮,空闲=正常,非活动=暗)。切换至 ctrl+b 或 f3.
  • 队列面板:所有具有颜色编码状态(待处理/已完成/已取消)的请求的完整历史记录。单击任意行可还原待处理的请求或查看已答复请求的摘要。
  • 可折叠消息:默认情况下,长度超过200个字符的邮件会折叠--单击展开,或使用 ctrl+e 全部展开/折叠。
  • 台阶指示器:何时 step 和 total_steps 屏幕标题显示“步骤X/Y”。

按键绑定

关键 行动
q 退出
ctrl+l 清除活动日志
ctrl+b 切换会话面板
f2 循环日志级别(调试/信息/警告/错误)
f3 切换会话面板(VS代码安全替代方案)
ctrl+e 展开/折叠所有可折叠邮件
escape 取消/关闭对话框


📋 日志

HITL MCP将每次工具交互记录到 ~/.local/state/hitl-mcp/interactions.jsonl 作为JSONL。每个条目都包括工具名称、持续时间、结果类型以及消息和结果的预览。日志自动以10MB的速度旋转。

logrotate配置示例见 控制/日志旋转:

sudo cp contrib/logrotate.conf /etc/logrotate.d/hitl-mcp

🧪 发展

设置

git clone https://github.com/geehexx/hitl-mcp-cli.git
cd hitl-mcp-cli
uv sync --all-extras

测试

# Run tests
uv run poe test

# With coverage
uv run pytest --cov --cov-report=html

# Lint and format
uv run poe lint
uv run poe format

# All checks
uv run poe check

看 docs/TEST.md 获取全面的测试指南。

手动测试

# Run example script
uv run python example.py

# Test with FastMCP dev server
fastmcp dev hitl_mcp_cli/server.py

# Test with MCP Inspector
npx @modelcontextprotocol/inspector hitl-mcp

📚 文档

♿ 无障碍

HITL MCP CLI设计为可访问:

  • ✅ 仅键盘导航:所有交互都可以在没有鼠标的情况下工作
  • ✅ 非彩色视觉提示:图标独立于颜色区分提示类型
  • ✅ 色盲支持:图标确保色觉缺陷的用户可以使用所有功能
  • ✅ 模糊搜索:长选择列表(>15个项目)自动启用搜索筛选
  • ✅ 终端兼容性:通过终端模拟器与屏幕阅读器配合使用

看 文档/可访问性.md 获取详细的可访问性信息、测试方法以及为有不同需求的用户提供的建议。


💻 VS代码终端

为了在VS Code的集成终端中获得最佳体验,请添加到您的 settings.json:

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

这确保了 Ctrl+\ (命令面板)和其他键绑定到达TUI。

备注: ctrl+b 和 ctrl+\ 可能被VS代码拦截。将这些添加到 commandsToSkipShell 在您的VS代码设置中,或使用 f2 (日志级别)和 f3 (切换会话)作为替代方案。


🔧 故障排除

60秒后工具调用超时

问题:当用户需要超过60秒的时间来响应时,工具会因“请求超时”错误而失败。

解决方案:设置 "timeout": 0 在MCP客户端配置中:

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

为什么:MCP协议有一个默认的60秒超时。人工输入是不可预测的——用户可能需要几分钟的时间来做出决定。将超时设置为0表示无限等待。

服务器无法启动

问题:端口已在使用中。

解决方案:使用端口5555停止其他进程,或在其他端口上启动服务器:

hitl-mcp --port 8080

不要忘记更新MCP客户端配置以匹配新端口。

代理中未显示工具

问题:特工看不到HITL工具。

解决方案:

  1. 验证服务器是否正在运行(hitl-mcp 应显示启动横幅)
  2. 检查您的MCP客户端配置文件位置
  3. 配置更改后重新启动MCP客户端(例如Claude Desktop)
  4. 验证URL是否匹配: http://127.0.0.1:5555/mcp

GET/mcp返回400个错误请求

问题:看到 "GET /mcp HTTP/1.1" 400 Bad Request 在日志中。

解决方案:这是 预期行为MCP端点仅接受带有JSON-RPC消息的POST请求。GET请求不是MCP协议的一部分,将返回400。这通常发生在以下情况下:

  • 浏览器尝试访问端点
  • 健康检查系统使用GET而不是POST
  • 代理错误地探测端点

如果你需要一个健康检查端点,这在docs/ROADMAP.md中会被跟踪,作为未来的考虑因素。

详细的服务器日志

问题:来自uvicorn的INFO日志太多(“已启动服务器进程”、“等待应用程序启动”等)

解决方案:默认日志级别为ERROR,它会抑制这些消息。如果你看到他们:

  1. 检查是否 HITL_LOG_LEVEL 环境变量设置为INFO或DEBUG
  2. 访问日志仅在以下情况下显示 HITL_LOG_LEVEL=DEBUG
  3. 要使服务器完全静音,请执行以下操作: HITL_LOG_LEVEL=ERROR hitl-mcp --no-banner

多行文本输入清除终端

问题:使用Esc+Enter键提交多行文本后,终端屏幕会清除。

解决方案:此问题已在v0.4.0中修复。多行输入现在通过以下方式保留屏幕内容:

  • 对Esc+Enter使用显式键绑定
  • 在输入后添加换行符以防止终端清除

如果您仍然遇到此问题,请确保您运行的是最新版本:

uvx hitl-mcp-cli@latest
# or
uv tool upgrade hitl-mcp-cli

连接错误或超时

问题:工具调用失败,出现连接错误或超时错误。

解决方案:

  1. 验证服务器是否正在运行:检查一下 hitl-mcp 正在运行且可访问
  2. 检查网络连接:确保MCP客户端可以访问服务器URL
  3. 验证超时配置:确保 "timeout": 0 在MCP客户端配置中设置
  4. 检查防火墙设置:确保端口5555(或您的自定义端口)未被阻止

对于AI代理:如果遇到超时或连接错误:

  • 该错误表示配置或网络问题,而不是用户取消
  • 检查上面的故障排除部分
  • 通知用户错误并建议检查服务器状态
  • 不要无限期重试-在2-3次失败后,向用户报告问题

错误处理最佳实践

面向AI代理开发人员:

集成HITL MCP工具时,适当处理错误:

try:
    result = await hitl_collect(message="Enter value:")
except Exception as e:
    if "User cancelled" in str(e):
        # User pressed Ctrl+C - respect their decision
        print("Operation cancelled by user")
        return
    elif "timed out" in str(e).lower() or "connection" in str(e).lower():
        # Configuration or network issue
        print("Error: Cannot connect to HITL server")
        print("Please check that hitl-mcp is running and timeout is configured")
        return
    else:
        # Unexpected error
        print(f"Unexpected error: {e}")
        raise

备注: hitl_collect 和 hitl_confirm 返回 {"action": "cancel"} 在Ctrl+C上,而不是提高,因此请先检查返回值。

错误类别:

  • 用户取消 (Ctrl+C):尊重取消,不要重试
  • 超时/连接:配置问题,通知用户,不要无限期重试
  • 验证错误:用户输入不符合要求,工具将自动重新提示
  • 意外错误:记录并向用户报告

🤝 贡献

欢迎投稿!拜托:

  1. 分叉存储库
  2. 创建要素分支(git checkout -b feature/amazing-feature)
  3. 添加新功能的测试
  4. 确保所有测试通过(uv run pytest)
  5. 提交您的更改(git commit -m 'Add amazing feature')
  6. 推到分支(git push origin feature/amazing-feature)
  7. 打开拉取请求

📄 许可证

Apache许可证2.0-请参阅 许可证 了解详情。


🙏 致谢

内置:

  • FastMCP -快速、Pythonic MCP服务器框架
  • 文本的 -Python的现代TUI框架

💬 支持


⭐ 标记此回购 如果你觉得它有用的话!

制作❤️ 面向AI代理社区

v1.0.0rc1-MCP三个原始习语

从v1.0.0rc1开始,服务器根据 MCP规范习惯用法:

原始 表面 你得到了什么
工具 (5) hitl_collect / hitl_ask / hitl_choose / hitl_confirm / hitl_notify 模型控制动作;阻止用户响应。签名与v0.9.0相同。
资源 (4) queue://pending, queue://history, session://activity, session://last-user-action-age 实时HITL状态的只读JSON快照。由客户投票(CC已关闭订阅 not_planned).
提示 (4) hitl_architectural_fork, hitl_destructive_action, hitl_scope_clarification, hitl_panel_vote_summary 用户控制的可重用模板,用于常见的HITL决策形状。通过MCP主机中的斜线命令调用。

v1.0中没有什么

v1.0版本仅提供基础重构。后续发布的土地如下:

  • v1.1 --MCP启发(根据CC v2.1.76+的表单/URL模式)、超时然后轮询状态机、可配置的等待时间设置。
  • v1.2 --auq-mcp服务器功能奇偶校验(本地操作系统通知、问题拒绝、代理技能支持)、A2A v1.0端点+AgentCard、短语作者内容质量集成。

看 docs/ROADMAP.md 和 CHANGELOG.md 查看完整的迁移指南。