返回市场
命中-MCP客户端

命中-MCP客户端

作者:geehexx2 星标更新:2025-11-16

项目介绍

🤝 HITL MCP CLI

Human-in-the-Loop MCP Server — 桥接人工智能自主性和人类判断之间的差距

License Python 3.11+ MCP

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

🎯 为什么需要Human-in-the-Loop?

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

面临的问题

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

  • 🤔 不确定性:需求并不总是明确的
  • ⚠️ 风险:某些操作过于敏感,不能盲目自动化
  • 🎨 偏好:存在多种有效的方法,但人类拥有上下文
  • ✅ 验证:假设需要确认后才能继续

解决方案

HITL MCP CLI 提供了一个标准化、优雅的接口,让AI代理可以在不中断工作流程的情况下请求人类输入。而不是让代理做出可能错误的假设或完全停止,它们可以:

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

实际场景

🤖 代理: "我找到了三种实现此功能的方法。您更喜欢哪种方法?"
👤 人类: [选择选项B:平衡性能和可维护性]
🤖 代理: "实施选项B..."

🤖 代理: "我即将删除150个废弃文件。是否继续?"
👤 人类: "是的,继续"
🤖 代理: "已删除150个文件。 ✅ 完成"

🤖 代理: "应该部署到测试环境还是生产环境?"
👤 人类: "先部署到测试环境"
🤖 代理: "正在部署到测试环境..."

✨ 特性

  • 🎯 5种交互工具:文本输入、选择、确认、路径输入和通知
  • 🎨 美观的终端UI:图标、渐变和流畅动画
  • 🚀 即时设置:与 uvx 一起使用——无需安装
  • 🔌 MCP标准:无缝集成任何兼容MCP的AI代理
  • ⚡ 雷霆般的速度:异步优先设计,最小开销
  • 🛡️ 类型安全:完整的类型提示,确保可靠性和IDE支持
  • 🌈 视觉反馈:加载指示器和状态消息
  • 🔧 自定义:禁用动画,自定义主机/端口

⚠️ 关键配置

超时设置必需:HITL操作需要无限超时,因为人类响应时间不可预测。没有这个设置,工具调用将在60秒后失败。

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


🚀 快速开始

安装

# 直接运行无需安装(推荐)
uvx hitl-mcp-cli

# 或全局安装
uv tool install hitl-mcp-cli

# 或使用pip
pip install hitl-mcp-cli

启动服务器

# 默认:localhost:5555
hitl-mcp

# 自定义主机/端口
hitl-mcp --host 0.0.0.0 --port 8080

# 禁用启动横幅
hitl-mcp --no-banner

# 使用环境变量
export HITL_HOST=0.0.0.0
export HITL_PORT=8080
export HITL_LOG_LEVEL=INFO
export HITL_NO_BANNER=true
hitl-mcp

环境变量

  • HITL_HOST:服务器主机(默认:127.0.0.1)
  • HITL_PORT:服务器端口(默认:5555)
  • HITL_LOG_LEVEL:日志级别 - DEBUG, INFO, WARNING, ERROR(默认:ERROR)
  • 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超时会导致工具调用失败,如果用户没有足够快地响应。

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


🛠️ 可用工具

1. request_text_input — 收集文本输入

从用户处获取文本,可选验证。

何时使用

  • 收集名称、描述或自由形式输入
  • 获取配置值
  • 请求API密钥或凭据(带验证)

示例

name = await request_text_input(
    prompt="我们应该给这个项目起什么名字?",
    default="my-project",
    validate_pattern=r"^[a-z0-9-]+$"  # 只允许小写字母、数字和连字符
)

参数

  • prompt (str):显示的问题
  • default (str, 可选):预填值
  • multiline (bool):启用多行输入以处理较长文本
  • validate_pattern (str, 可选):用于验证的正则表达式模式

2. request_selection — 展示选择

让用户从预定义选项中选择(单选或多选)。

何时使用

  • 在实现方法之间进行选择
  • 选择部署环境
  • 选择要启用的功能
  • 从已知集合中配置选项

示例

# 单选
env = await request_selection(
    prompt="我应该部署到哪个环境?",
    choices=["开发", "测试", "生产"],
    default="测试"
)

# 多选
features = await request_selection(
    prompt="我应该启用哪些功能?",
    choices=["认证", "缓存", "日志", "监控"],
    allow_multiple=True
)

参数

  • prompt (str):显示的问题
  • choices (list[str]):可用选项
  • default (str, 可选):预选选项
  • allow_multiple (bool):启用复选框模式以进行多选

3. request_confirmation — 获取是/否批准

在继续之前请求明确批准。

何时使用

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

示例

confirmed = await request_confirmation(
    prompt="我将删除50个未使用的依赖项。是否继续?",
    default=False  # 默认为安全选项
)

if confirmed:
    # 继续操作
    await delete_dependencies()
    await notify_completion(
        title="清理完成",
        message="已移除50个未使用的依赖项",
        notification_type="success"
    )

参数

  • prompt (str):是/否问题
  • default (bool):默认答案(对于破坏性操作使用 False

4. request_path_input — 获取文件/目录路径

收集文件或目录路径并进行验证。

何时使用

  • 选择配置文件
  • 选择输出目录
  • 查找输入数据
  • 指定日志文件位置

示例

config_path = await request_path_input(
    prompt="选择配置文件:",
    path_type="file",
    must_exist=True,
    default="./config.yaml"
)

output_dir = await request_path_input(
    prompt="应将输出保存在哪里?",
    path_type="directory",
    must_exist=False,  # 如果需要,将创建该目录
    default="./output"
)

参数

  • prompt (str):显示的问题
  • path_type (Literal["file", "directory", "any"]):预期路径类型
  • must_exist (bool):验证路径是否存在
  • default (str, 可选):预填路径

5. notify_completion — 显示状态通知

为重要事件显示样式化的通知。

何时使用

  • 确认成功操作
  • 报告错误或警告
  • 提供进度更新
  • 强调重要信息

示例

# 成功通知
await notify_completion(
    title="部署完成",
    message="成功部署v2.1.0到生产环境\n\nURL: https://app.example.com",
    notification_type="success"
)

# 警告通知
await notify_completion(
    title="弃用警告",
    message="旧API将在v3.0中被移除",
    notification_type="warning"
)

# 错误通知
await notify_completion(
    title="构建失败",
    message="发现TypeScript编译错误\n\n运行'npm run type-check'以获取详细信息",
    notification_type="error"
)

参数

  • title (str):通知标题
  • message (str):详细消息(支持多行)
  • notification_type (Literal["success", "info", "warning", "error"]):视觉风格

📖 使用模式

模式1:澄清

当需求不确定时,提出具体问题:

# 代理遇到不确定的需求
approach = await request_selection(
    prompt="我可以以两种方式实现此功能。您更喜欢哪一种?",
    choices=[
        "选项A:快速实现,更高内存使用",
        "选项B:较慢但更节省内存",
        "选项C:平衡方法(推荐)"
    ],
    default="选项C:平衡方法(推荐)"
)

# 继续执行选定的方法
if "选项A" in approach:
    await implement_fast_version()
elif "选项B" in approach:
    await implement_efficient_version()
else:
    await implement_balanced_version()

模式2:审批门

在重大行动前请求批准:

# 解释将发生什么
files_to_delete = find_unused_files()
confirmed = await request_confirmation(
    prompt=f"我发现了{len(files_to_delete)}个未使用的文件。删除它们吗?",
    default=False
)

if confirmed:
    delete_files(files_to_delete)
    await notify_completion(
        title="清理完成",
        message=f"已删除{len(files_to_delete)}个未使用的文件",
        notification_type="success"
    )
else:
    await notify_completion(
        title="取消",
        message="没有删除任何文件",
        notification_type="info"
    )

模式3:信息收集

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

# 收集项目配置
project_name = await request_text_input(
    prompt="项目名称:",
    validate_pattern=r"^[a-z0-9-]+$"
)

language = await request_selection(
    prompt="编程语言:",
    choices=["Python", "TypeScript", "Go", "Rust"]
)

features = await request_selection(
    prompt="选择要包含的功能:",
    choices=["测试", "代码检查", "持续集成/持续部署", "文档"],
    allow_multiple=True
)

output_dir = await request_path_input(
    prompt="输出目录:",
    path_type="directory",
    must_exist=False
)

# 使用收集的信息生成项目
await generate_project(project_name, language, features, output_dir)

模式4:逐步披露

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

# 高层次选择
action = await request_selection(
    prompt="您想做什么?",
    choices=["部署", "回滚", "查看日志", "运行测试"]
)

if action == "部署":
    # 深入部署
    env = await request_selection(
        prompt="部署到哪个环境?",
        choices=["测试", "生产"]
    )

    if env == "生产":
        # 生产环境额外确认
        confirmed = await request_confirmation(
            prompt="部署到生产环境?这将影响实时用户。",
            default=False
        )
        if confirmed:
            await deploy_to_production()

🏗️ 架构

AI代理(Claude, GPT等)
         ↓ HTTP(MCP协议)
    FastMCP服务器
         ↓ 异步调用
      UI层(InquirerPy + Rich)
         ↓ 终端I/O
        用户

参见 docs/ARCHITECTURE.md 了解详细的架构文档。


🧪 开发

设置

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

测试

# 运行所有测试
uv run pytest

# 带覆盖率
uv run pytest --cov --cov-report=html

# 类型检查
uv run mypy hitl_mcp_cli/

# 代码检查
uv run ruff check .
uv run black --check .

参见 docs/TESTING.md 了解全面的测试指南。

手动测试

# 运行示例脚本
uv run python example.py

# 使用FastMCP开发服务器测试
fastmcp dev hitl_mcp_cli/server.py

# 使用MCP Inspector测试
npx @modelcontextprotocol/inspector hitl-mcp

📚 文档

♿ 无障碍

HITL MCP CLI 设计为无障碍:

  • ✅ 仅键盘导航:所有交互无需鼠标即可完成
  • ✅ 非颜色视觉提示:图标独立于颜色区分提示类型
  • ✅ 色盲支持:图标确保色觉缺陷用户也能使用所有功能
  • ✅ 模糊搜索:长选项列表(>15项)自动启用搜索过滤
  • ✅ 终端兼容性:通过终端模拟器与屏幕阅读器兼容

参见 docs/ACCESSIBILITY.md 了解详细的无障碍信息、测试方法以及针对不同需求用户的建议。

🔌 插件框架

HITL MCP CLI 将通过 MCP插件服务器 框架获得插件支持。这将实现:

  • 基于插件的扩展架构
  • 社区贡献插件以增加新功能
  • 包装模式以增强HITL的新功能

参见 MCP插件服务器仓库 了解插件框架架构和开发详情。


🔧 故障排除

工具调用在60秒后超时

问题:当用户响应时间超过60秒时,工具调用会因“请求超时”而失败。

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

{
  "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客户端(