🤝 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提供了一个丰富的终端界面:
- 会议小组:显示代理名称和项目,按最近度进行颜色编码(活动\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工具。
解决方案:
- 验证服务器是否正在运行(
hitl-mcp应显示启动横幅) - 检查您的MCP客户端配置文件位置
- 配置更改后重新启动MCP客户端(例如Claude Desktop)
- 验证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,它会抑制这些消息。如果你看到他们:
- 检查是否
HITL_LOG_LEVEL环境变量设置为INFO或DEBUG - 访问日志仅在以下情况下显示
HITL_LOG_LEVEL=DEBUG - 要使服务器完全静音,请执行以下操作:
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连接错误或超时
问题:工具调用失败,出现连接错误或超时错误。
解决方案:
- 验证服务器是否正在运行:检查一下
hitl-mcp正在运行且可访问 - 检查网络连接:确保MCP客户端可以访问服务器URL
- 验证超时配置:确保
"timeout": 0在MCP客户端配置中设置 - 检查防火墙设置:确保端口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):尊重取消,不要重试
- 超时/连接:配置问题,通知用户,不要无限期重试
- 验证错误:用户输入不符合要求,工具将自动重新提示
- 意外错误:记录并向用户报告
______________________________________________________________________
🤝 贡献
欢迎投稿!拜托:
- 分叉存储库
- 创建要素分支(
git checkout -b feature/amazing-feature) - 添加新功能的测试
- 确保所有测试通过(
uv run pytest) - 提交您的更改(
git commit -m 'Add amazing feature') - 推到分支(
git push origin feature/amazing-feature) - 打开拉取请求
______________________________________________________________________
📄 许可证
Apache许可证2.0-请参阅 许可证 了解详情。
______________________________________________________________________
🙏 致谢
内置:
______________________________________________________________________
💬 支持
- 问题:
- 讨论:
- MCP社区: 模型上下文协议
______________________________________________________________________
⭐ 标记此回购 如果你觉得它有用的话!
制作❤️ 面向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 查看完整的迁移指南。
