Skip to main content
Glama
youjunxiaji

gl-mcp-feedback

by youjunxiaji

gl-mcp-feedback

交互式反馈 MCP 服务器。AI 调用 interactive_feedback 把工作摘要发到浏览器页面,用户在页面里回复文字和图片,回复再回到 AI,把多次试错合并成一次有效沟通。

适用于支持 MCP 的 AI 编辑器,如 Cursor、Cline、Windsurf。

功能

  • 微信式对话流:AI 的摘要(Markdown 渲染,代码块带复制按钮)靠左,用户回复靠右,历史消息可回看。

  • 文字与图片回复:图片可选文件或 Ctrl/⌘+V 粘贴,Ctrl/⌘+Enter 发送。

  • 消息排队:AI 干活期间用户也能继续发消息,最多排 3 条,排队中可以编辑、撤回。装了 Cursor 钩子,AI 调用完任意一次工具就能读到;没装,或 AI 先一步再次提问,则随下一次 interactive_feedback 一并带回,不会因为 AI 再次提问而丢失。

  • 多对话分开:每个 Cursor 对话一个页面(/c/<对话 ID>/),回复和排队的消息不会串到别的对话;对话 ID 由 Cursor 钩子填入 conversation_id,没有钩子的调用共用一个页面。/ 列出所有对话。

  • 新提问提醒:新一轮提问到达时播放提示音,页面在后台时再弹桌面通知;页面没在被看时,标签页标题前会加 🟢、图标右上角会加绿点,开着好几个对话的页面也能一眼分出哪个有新消息,切回来自动消失。

  • 环境自动检测:识别 SSH Remote、WSL 等环境,无法打开浏览器时可通过端口转发访问。

Related MCP server: Copilot Leecher

工具与 Prompt

名称

说明

interactive_feedback

打开 Web UI 收集反馈。参数:project_directory、summary(Markdown,必填)、timeout(秒,默认 600,也是上限,更大的值按 600 处理)、conversation_id(可选,由 Cursor 钩子填入,AI 不要填)

get_system_info

返回平台、Python 版本、是否远程 / WSL 等环境信息

prompt chat

无参数,激活互动模式。在 Cursor 中输入 /user-gl-mcp-feedback/chat(前缀随 MCP 配置里的服务器名而定)

安装与配置

需要 Python ≥ 3.12 和 uv。在 MCP 配置里加入:

{
    "mcpServers": {
        "gl-mcp-feedback": {
            "command": "uvx",
            "args": ["gl-mcp-feedback@latest"],
            "timeout": 600,
            "autoApprove": ["interactive_feedback"]
        }
    }
}

从源码运行:

{
    "mcpServers": {
        "gl-mcp-feedback": {
            "command": "uv",
            "args": ["run", "--directory", "/path/to/gl-mcp-feedback", "gl-mcp-feedback"],
            "timeout": 600
        }
    }
}

配置里的 timeout 只有读它的客户端(比如 Cline)才用得上,Cursor 不读:Cursor 对每次 MCP 工具调用有 120 秒的空闲超时,调用期间每收到一条进度通知就重新计时。所以等用户回复期间,服务端每 30 秒发一条进度通知,一次提问最长能等 10 分钟(timeout 的上限)。

环境变量

在 MCP 配置的 env 里设置。

变量

用途

默认

MCP_WEB_HOST

Web UI 绑定地址

127.0.0.1

MCP_WEB_PORT

Web UI 端口,范围 1024-65535,0 表示系统自动分配

8765

MCP_DEBUG

调试日志(输出到 stderr),true / false

false

MCP_WEB_HOST 为 127.0.0.1 时只能本机访问;SSH 远程开发时可设为 0.0.0.0,再用 http://[远程主机 IP]:8765 访问。也可以保持默认,改用 SSH 端口转发把远程的 8765 转到本机。详见 SSH Remote 环境使用指南。

Cursor 钩子

钩子是可选的。它是一个 Python 脚本(仓库里的 hooks/gl-feedback.py,随包发布),管三件事:

  • 给每次 interactive_feedback 填上 Cursor 的对话 ID,让每个对话用自己的页面

  • AI 调用完任意一次工具时,把用户排队的消息取走,附在那次工具结果后面交给 AI;消息带图片时,图片存成本地文件,路径写在文字里,AI 用 Read 查看;对话的房间销毁时这些图片一并删除,没被删掉的(比如服务异常退出)24 小时后清理

  • 对话正常结束时(stop),通知服务销毁这个对话的房间,页面显示「对话已结束」,已有的记录留在页面上,由你自己关掉

没装钩子,所有对话共用一个页面,排队的消息要等 AI 下次调用 interactive_feedback 才送达。

安装

先确认 MCP 已经是新版:钩子会给 interactive_feedback 填 conversation_id,旧版服务端不认这个参数、会拒绝调用,所以先在 Cursor 里把这个 MCP 关掉再打开(uvx 会拉最新版)。然后执行一条命令:

uvx gl-mcp-feedback@latest hooks install

它依次做三件事:

  1. 把脚本复制到用户目录下的 .cursor/hooks/gl-feedback.py(macOS / Linux 是 ~/.cursor,Windows 是 %USERPROFILE%\.cursor)

  2. 用将要登记的命令试跑一次脚本,确认 uv 和 Python 都能用;试跑不通就停下,不改配置

  3. 把五项钩子合并登记进同一个目录的 hooks.json,别的钩子原样保留,改动前先把原文件备份成 hooks.json.bak

登记的命令是 uv run --quiet --no-project --script ./hooks/gl-feedback.py <模式>,脚本路径是相对的(用户级钩子从 .cursor 目录运行),每个人登记的内容都一样。重复执行不会重复登记;已经登记了 gl-feedback.py 的条目(比如你自己指向仓库脚本的)默认不动,加 --force 才改成新位置。升级之后再执行一次,脚本就更新到新版。从源码运行时,在仓库里执行 uv run gl-mcp-feedback hooks install。卸载:uvx gl-mcp-feedback@latest hooks uninstall。

脚本只依赖 uv(用 uvx 启动 MCP 的话已经有了),macOS、Linux 和 Windows 通用。

Windows 上同样用这条命令,不过作者没有 Windows 环境,没有在真机上验证过。Cursor 在 Windows 上通过 PowerShell 执行钩子命令,官方论坛确认过一个问题:Git Bash 在启动进程的祖先里时(比如从 Git Bash 里启动 Cursor),Cursor 会把 PowerShell 写的命令交给 bash,所有钩子都失败,interactive_feedback 也会被拦住(Hook blocked)。从开始菜单或 PowerShell 启动就没有这个问题。遇到这种情况或别的问题,执行 hooks uninstall 卸掉钩子,MCP 照常能用。

各项钩子做什么

pre 给所有项目的对话填对话 ID。Cursor 给 preToolUse 的输入里没有 MCP 服务器名,matcher 只能按工具名匹配,别的 MCP 服务器如果也有叫 interactive_feedback 的工具,它的调用同样会被改写。log 把会话事件的几个字段记进 ~/.cache/gl-mcp-feedback/hook-events.log。

stop 在 AI 的每个回合结束时触发:先记一条事件,再把回合的结束状态报告给这个对话的房间。状态是 completed(正常结束)时,房间 3 秒后销毁(它送达过的图片文件一并删除),页面收到「对话已结束」,输入框锁定,已有的记录留在页面上,页面不会自己关闭;这 3 秒里对话再提问,房间就留下。房间里还有排队中的消息时也留下,等对话下次提问或调用工具时送达。状态是 aborted(被中断)或 error(出错)时,房间只标成「已结束」,不销毁。不管有没有收到 stop,闲置超过 2 小时的房间都会销毁。

标记文件、登记文件、图片和事件日志都放在 GL_FEEDBACK_HOME(默认 ~/.cache/gl-mcp-feedback),服务端和钩子读同一个变量,一般不用改。

推荐的 AI 规则

为了让 AI 稳定地走「先确认 → 再动手 → 最后回收反馈」的流程,建议把下面这段放进 AI 助手的规则(Cursor 的 User Rules / Project Rules、Cline 的 Custom Instructions 等):

gl-mcp-feedback 交互规范:

1. 代码修改完成后,必须调用 interactive_feedback,在 summary 中说明已完成的修改,等待用户测试反馈。
2. 用户提出新需求时,先调用 interactive_feedback 阐述理解和实现思路,等用户确认后再写代码。
3. 工具调用被中断/取消时,立即调用 interactive_feedback 询问用户。
4. 收到「用户没有回复」的提示、或 MCP 调用超时时,立即重新调用等待反馈(timeout 传 600)。
5. summary 参数使用 Markdown 格式,按需使用标题、列表、文件路径等结构化信息。
6. summary 用 Markdown 时尽量保持简洁:减少代码块嵌套、长串双引号、复杂转义,能用纯文本叙述就用纯文本,能用列表就不要堆段落。代码块仅在贴具体代码/命令时使用。

第 1、2 条是核心:改代码前先确认、改代码后回收反馈。第 5、6 条与渲染有关:summary 会在 Web UI 里以 Markdown 展示,写得简洁可读性最好。

常见问题

页面没有收到新的反馈:多半是 WebSocket 断了,刷新浏览器页面即可。

对话进行到一半,页面显示「已断开」,并提示 MCP 服务已断开:MCP 进程被重启了,多半是 Cursor 自己重启的(按日志观察,它每次启动后会把 MCP 重启一次,多数在几秒内,偶尔晚到几分钟;在设置里手动重载 MCP 也一样)。房间和记录都在进程内存里,刷新页面恢复不了;AI 下次提问时会在新进程里新开一个页面,旧页面上的记录还留着,直接关掉即可。

AI 在我没回复时又发来一条很短的提问:用户在 10 分钟(timeout 的上限)内没有回复,这一轮提问就标为超时,页面上显示「该轮对话已超时,未收到回复」,AI 收到一条让它再次提问的提示,于是用一两句话重新发起;上一轮的完整内容还留在页面上。如果两三分钟就报 MCP error -32001: Request timed out,说明进度通知没起作用:先确认 MCP 是最新版本并且重启过(uvx 用 @latest,从源码运行的在 Cursor 设置里把 gl-mcp-feedback 关掉再打开)。

排队的消息要等 AI 下次提问才送达:钩子没生效。重新执行 uvx gl-mcp-feedback@latest hooks install,它会试跑脚本,哪里不通会直接告诉你;也可以确认 ~/.cursor/hooks.json 里登记了 post,以及 Cursor 的 PATH 里有 uv。

AI 等后台命令的时候发的消息,要等它等完才读到:钩子只在工具调用结束时送达。AI 用 AwaitShell 等后台命令期间,Cursor 每秒会触发几次内部轮询,这些触发送出去的内容会被丢弃,所以钩子跳过它们,消息在等待结束后的第一次工具调用结束时送达。

对话结束了,页面还开着:页面不会自己关闭,免得你不在时 AI 留下的消息跟着消失。对话正常结束后页面显示「对话已结束」、输入框锁定,已有的记录还在,看完手动关掉即可;刷新页面会跳回房间列表,记录就看不到了(房间在服务端已经销毁,记录只在页面里)。如果对话结束后页面一直没有显示「对话已结束」,确认 ~/.cursor/hooks.json 里 stop 登记的命令是 ... gl-feedback.py stop(不是 log)。

interactive_feedback 被拦住(提示 Hook blocked 或被拒绝):钩子脚本跑不起来时,Cursor 会拒绝 preToolUse 钩子管着的调用,比如 uv 出错,或 Windows 上被 Git Bash 搅乱。执行 uvx gl-mcp-feedback@latest hooks uninstall 卸掉钩子,MCP 照常能用,排除原因后再装。

AI 没有调用出 MCP:确认 MCP 工具状态为绿灯,反复开关一次 MCP,等几秒让它重新连接。

出现 Unexpected token 'D' 之类的解析错误:调试输出干扰了通信,设置 MCP_DEBUG=false 或去掉该变量。

Web UI 打不开:检查防火墙,或用 MCP_WEB_PORT 换一个端口。

开发

git clone https://github.com/youjunxiaji/gl-mcp-feedback.git
cd gl-mcp-feedback
uv sync

uv run gl-mcp-feedback test --web   # 启动一个测试用的 Web UI
uv run gl-mcp-feedback version      # 查看版本

uv run pytest                       # 测试
uv run ruff check .                 # lint
uv run pyright                      # 类型检查

致谢

授权

MIT,详见 LICENSE。

Available Tools

2 tools
get_system_infoA

获取系统环境信息

Returns: str: JSON 格式的系统信息

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses the return type (string in JSON format), and the verb 'get' implies a read-only operation. However, it does not explicitly state that it is non-destructive or describe any potential side effects, which would be helpful for a tool with no annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, consisting of two short lines. It front-loads the core purpose and immediately provides return format information, with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, parameterless tool with an output schema (indicated by the Returns section), the description is sufficiently complete. It tells the agent what the tool returns and in what format, which is all that is needed for this straightforward operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description does not need to explain parameters, and indeed mentions none, which is appropriate for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states '获取系统环境信息' (Get system environment information), which is a specific verb and resource. It unambiguously distinguishes from the sibling tool 'interactive_feedback', which is about user feedback rather than system data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It only states what the tool does without mentioning any exclusions, prerequisites, or comparisons to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

interactive_feedbackA

Open a Web UI to collect interactive feedback from the user.

This tool is the PRIMARY communication channel with the user. The full list of "when to call" scenarios lives in the project's gl-mcp-feedback user rules; this docstring only covers the runtime contract that the tool itself enforces.

Strict prohibitions: - While this tool is available, DO NOT invoke Cursor's built-in AskQuestion. Route every question through summary as a numbered list. - DO NOT end the turn with a plain-text reply when there is substantive content for the user to read. Put it in summary. - When the user skips without feedback, re-call this tool to ask why; only stop on explicit termination (结束 / 不用了 / stop / done). - Allowed parameters: project_directory, summary, timeout, plus conversation_id, which a Cursor hook fills in: never set it yourself. Names like question / choices / options belong to AskQuestion and will fail schema validation here.

summary writing rules: - Markdown: headings (##), lists, tables, code fences, bold for key decisions. Include modified file paths and explicit questions when applicable. - NEVER pass an empty string or the placeholder phrase 我已完成了您请求的任务。 — runtime validation rejects them and you must re-call with a real summary.

Queued messages: While you work between two calls, the user can keep typing in the Web UI; those messages are queued (at most 3) and reach you in one of two ways, both under a header starting with (你工作期间,用户追加了 N 条消息:

- After any tool call, a Cursor hook appends the queue to that
  tool's result. Images are saved as local files whose paths are
  listed in the block: open them with ``Read``.
- On your next call to this tool, the queue is returned
  immediately, without waiting for a new reply.

Either way they are NOT an answer to the ``summary`` you just
passed: treat them as new instructions in the given order, act on
them, then call this tool again.

Args: project_directory: Absolute or relative project path. Defaults to cwd. summary: Required Markdown summary. No empty string, no placeholder. timeout: Seconds to wait for user feedback. Values above 600 are capped, so always pass 600. conversation_id: Filled in by a Cursor hook. Never set it yourself.

Returns: ToolResult: TextContent with the user's text feedback plus MCPImage objects for any uploaded images. An empty result means the user skipped — re-call to ask why. A result starting with [interactive_feedback TIMEOUT] means the user has not replied within the wait limit — re-call to keep waiting.

NameRequiredDescriptionDefault
summaryNoMarkdown summary of the AI's current work / plan / question, rendered in the Web UI. MUST be filled in with substantive content; empty strings and placeholder phrases (e.g. "我已完成了您请求的任务。") are rejected at runtime.
timeoutNoSeconds to wait for user feedback. Values above 600 are capped, so always pass 600.
conversation_idNoFilled in automatically by a Cursor hook to identify the conversation. NEVER set this yourself; always leave it empty.
project_directoryNoProject directory path..

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so richly: it discloses runtime validation that rejects empty/placeholder summaries, the 600s timeout cap, that conversation_id is hook-injected, and the queued-message behaviour (max 3, delivered via hook result or next call). It also documents the exact return shapes — empty result = skipped, '[interactive_feedback TIMEOUT]' prefix = no reply — which is precisely the behavioural context an agent needs to drive the retry loop.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded — purpose first, then prohibitions, then summary rules, then queue semantics, then Args/Returns. The one deduction is redundancy: the timeout cap and the summary-validation rule are each stated twice, and the Args section duplicates schema descriptions word for word, costing length without new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no annotations, this covers everything: how to write the argument, what the return value looks like in all three outcomes (feedback, skip, timeout), and how out-of-band user messages arrive mid-loop. Nothing an agent needs to invoke it correctly and react to results is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so a 3 would be the floor, but the description adds genuine value beyond the schema: it warns that names like question/choices/options will fail schema validation here, which prevents a likely mis-call from prior AskQuestion habit. The Args block otherwise restates the schema descriptions almost verbatim (cwd default, timeout cap).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Open a Web UI to collect interactive feedback from the user') and immediately stakes out the role as the PRIMARY user-communication channel. It explicitly distinguishes itself from a near-alternative ('DO NOT invoke Cursor's built-in AskQuestion'), so an agent knows exactly what this tool is and is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives unusually concrete routing rules: use this instead of AskQuestion, never end the turn with plain text when there is substantive content, re-call after a skip, re-call after a TIMEOUT. The residual gap is that the full 'when to call' scenario list is deferred to external gl-mcp-feedback user rules, so the positive trigger conditions are not fully self-contained.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev3.0.2
    • Changedinteractive_feedback1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Seconds to wait for user feedback. Keep >= 600."New value: +"Seconds to wait for user feedback. Values above 600 are capped, so always pass 600."
  2. 1 tool updatev3.0.1
    • Changedinteractive_feedback2 fields changed
      • addedInput schema / properties / conversation_id
        Added value: +{
        +  "default": "",
        +  "description": "Filled in automatically by a Cursor hook to identify the conversation. NEVER set this yourself; always leave it empty.",
        +  "type": "string"
        +}
      • removedInput schema / properties / title
        Removed value: -{
        -  "default": "",
        -  "description": "Optional short headline (max ~30 chars) for this feedback round, displayed in the browser tab and at the top of the AI summary panel. Should be concise (e.g. \"需要你提供更多信息\", \"修复完成,请验证\"). Leave empty when there's no good headline.",
        -  "type": "string"
        -}
  3. 2 tool updatesv2.2.3
    • First observedget_system_info
    • First observedinteractive_feedback

TDQS

A3.8/5.0

Scored across 2 tools

Disambiguation4/5

The two tools have clearly different runtime behaviors: interactive_feedback drives user dialogue, while get_system_info reads environment data. There is no direct overlap, but get_system_info appears unrelated to the feedback domain, which weakens the overall set coherence.

Naming Consistency3/5

Both names use snake_case, so they are readable and mechanically consistent. However, interactive_feedback is a noun/adjective phrase while get_system_info follows a verb_noun pattern, so the naming convention is mixed rather than predictable.

Tool Count3/5

Two tools is borderline thin for a server whose core purpose is interactive feedback, especially when one tool carries almost all the domain behavior. The second tool is a small unrelated utility rather than a complementary feedback operation.

Completeness3/5

interactive_feedback is richly specified and covers many runtime states such as timeout, queued messages, images, and termination handling. However, there are no explicit session-management or history tools, and get_system_info is isolated from the feedback workflow.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    MCP server that enables human-in-the-loop workflow in AI-assisted development tools by allowing users to provide direct feedback to AI agents without consuming additional premium requests.
    1
    1
    -
  • F
    license
    A
    quality
    Not graded
    maintenance
    An MCP server that enables users to review and refine AI outputs through a local web UI, returning feedback as free tool call results to save on GitHub Copilot premium requests. It allows for multiple rounds of iterative improvements within a single request session.
    1
    30
    -
  • A
    license
    A
    quality
    C
    maintenance
    An interactive feedback MCP server with a web UI, enabling AI-driven development workflows where AI can prompt users for feedback before taking actions, supporting platforms like Cursor, Cline, and Windsurf.
    2
    MIT