mcpField
U
ui-ticket-mcp

ui-ticket-mcp

本地服务
github.com/0ics-srls开发工具94 周前更新

关于 ui-ticket-mcp

ui-ticket-mcp 将浏览器中的原型评审连接到 AI 编码 Agent,并记录元素级上下文,帮助 Agent 根据反馈处理代码。

主要功能

  1. 01浏览器评审面板
  2. 02点击与拖动标注
  3. 03捕获 DOM 和样式上下文
  4. 04支持线程和分类的评审评论
  5. 05通过 MCP 工具管理评审

适用场景

  1. 01标记具体界面元素的视觉问题
  2. 02为 Agent 提供代码修复上下文
  3. 03跟踪并解决页面评审

MCP 相关

向 Agent 提供 10 个 MCP 工具,用于列出、查看、创建和解决评审,以及查找源文件。本地 REST API 连接浏览器评审界面。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"0ics-srls-ui-ticket": {
"command": "uvx",
"args": [
"ui-ticket-mcp"
],
"env": {
"PROJECT_ROOT": "<PROJECT_ROOT>",
"REVIEW_PORT": "<REVIEW_PORT>"
}
}
}
}
启动命令uvx ui-ticket-mcp
需要配置的环境变量
PROJECT_ROOTRoot directory of the project being reviewed
REVIEW_PORTHTTP port for REST API (default: 3200)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiui-ticket-mcp1.6.1

工具

11

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

ui-ticket-mcp

连接人与 AI 的代码审查桥梁。 直接在浏览器中审查 UI 原型,然后让 AI Agent 读取你的反馈并自动修复代码。

你可以点击元素,撰写审查意见,例如“这个按钮应该是蓝色的”或“这里的间距不对”,然后你的 AI 编码 Agent(Claude Code、Codex、Cursor 等)会通过 MCP 获取这些意见并解决问题,同时获得你所指向元素的完整上下文,包括其 CSS、位置和周围的 DOM。

工作原理

journey
    title Using ui-ticket-mcp
    section Review
      Open your app in browser: 5: You
      Click on a broken element: 4: You
      Write what's wrong: 5: You
    section AI resolves
      Agent reads your feedback: 3: AI
      Agent finds the source file: 4: AI
      Agent fixes the code: 5: AI
      Review disappears: 5: You, AI

一个 Python 进程即可处理所有事务:为 Agent 提供 MCP 协议(stdio),为浏览器 UI 提供 REST API(HTTP)。审查记录存储在项目内的 SQLite 数据库中。


快速开始

1. 连接到你的 AI Agent

将以下内容添加到项目的 .mcp.json 中(Claude Code、Codex、Cursor 等):

{
  "mcpServers": {
    "ui-ticket-mcp": {
      "command": "uvx",
      "args": ["ui-ticket-mcp"],
      "env": {
        "PROJECT_ROOT": "/path/to/your/project",
        "REVIEW_PORT": "3200"
      }
    }
  }
}

重启 Agent。uvx 会自动下载并运行软件包,无需手动安装。

替代方案: 运行 pip install ui-ticket-mcp,然后使用 "command": "ui-ticket-mcp" 替代 uvx。

MCP 服务启动时,还会在 http://localhost:3200(或你自定义的 REVIEW_PORT)上启动 REST API,供浏览器 UI 使用。

重要: API 始终在本地(localhost)运行。网站 https://uiticket.0ics.ai/ 仅是落地页,不是 API 端点。请始终将 http://localhost:{PORT}/api 用作 api-url。

2. 将浏览器 UI 添加到你的应用
npm install ui-ticket-panel

在应用的入口文件中(例如 main.ts、index.tsx):

import { defineReviewPanel } from 'ui-ticket-panel';
defineReviewPanel();

然后在根模板中:

<review-panel api-url="http://localhost:3200/api"></review-panel>

就这么简单。它适用于任何框架,包括 Angular、React、Vue、Svelte 或纯 HTML。它是一个标准的 Web Component。对于 SSR 框架(Next.js、Nuxt、SvelteKit),请参阅框架示例部分——你需要在客户端进行动态导入。

没有打包工具?使用 CDN
<script type="module" src="https://unpkg.com/ui-ticket-panel/dist/bundle.js"></script>
<review-panel api-url="http://localhost:3200/api"></review-panel>

此软件包会自动注册 <review-panel> 元素。无需安装 npm,也无需构建。

3. 开始审查

在浏览器中打开你的应用。右下角会显示一个悬浮聊天按钮。点击它即可打开审查面板,或按 Alt+A 进入标注模式,然后直接点击元素。


浏览器 UI 功能

审查面板

悬浮面板可用于浏览、筛选和管理所有审查记录:

  • 筛选标签页 - 在未解决、已解决和全部审查记录之间切换
  • 搜索 - 对所有审查评论进行全文搜索
  • 标签筛选 - 按类别筛选:一般、错误、建议、问题
  • 单条审查操作 - 解决、重新打开、删除、回复、高亮元素
  • 串联回复 - 回复审查意见,进行来回讨论
  • 手动审查表单 - 无需标注即可撰写审查意见(按 Ctrl+Enter 提交)
  • 徽标计数器 - 悬浮按钮显示未解决审查的数量
标注系统

标注系统让你可以指向特定元素并为其添加评审:

  • 点击进行标注 - 按 Alt+A(或目标按钮),然后点击任意元素
  • 拖动多选 - 点击并拖动,选择包含多个元素的区域
  • 悬停预览 - 移动鼠标时实时查看元素识别信息
  • 智能弹窗 - 根据可用空间显示在元素上方或下方

标注元素时,系统会捕获丰富的元数据,帮助 AI Agent 准确理解你指向的内容:

捕获的数据示例
元素名称Button 'Save'、Input[email] 'Your email'、Heading 2 'Features'
CSS 选择器#main-header、div.card > button.primary:nth-of-type(2)
边界框以像素为单位的位置和尺寸
附近文本自身文本 + 上一个/下一个同级元素的文本,用于提供上下文
选中文本如果你在标注前高亮了文本
CSS 类已过滤(排除框架生成的哈希值)
计算样式颜色、背景、字体、边框、内边距(根据元素类型智能选择)
完整 DOM 路径body > div#app > section.content > div.card > button
无障碍信息ARIA 角色、标签、tabindex、是否可聚焦
同级元素上下文父级标签、子元素数量、相邻同级标签
标记徽章

带有标注的评审会在页面上、标注元素旁显示编号徽章:

  • 单条评审 - 圆形徽章,显示评审 ID;未解决时为红色,已解决时为绿色
  • 堆叠评审(同一元素上有 3 条或更多)- 药丸形徽章,显示数量,并用渐变色表示未解决与已解决的比例
  • 点击徽章 - 在面板中打开评审
  • 删除徽章 - 悬停时点击 X 按钮即可移除
  • 工具提示 - 悬停可查看作者、元素名称和评论预览
标签

每条评审都可以标记一个类别:

标签颜色用途
general靛蓝色一般反馈(默认)
bug红色某项功能无法正常使用
suggestion绿色改进建议
question琥珀色需要澄清
键盘快捷键
快捷键操作
Alt+A切换标注模式
Ctrl+Enter提交评审或回复
Escape关闭弹窗 / 退出标注模式

架构

graph LR
    Agent[AI Agent]
    Browser[Reviewer - Browser]
    Server[ui-ticket-mcp]
    DB[(SQLite)]

    Agent <-->|stdio MCP| Server
    Browser <-->|HTTP REST :3200| Server
    Server --- DB
  • MCP(stdio)- 你的 Agent 框架会自动启动它。提供 10 个工具,供 AI Agent 读取、解决和管理评审。
  • REST API(HTTP :3200)- 在后台启动,为浏览器评审界面提供服务。已启用对所有来源的 CORS。
  • SQLite(WAL 模式)- 支持并发读取 + 1 个写入者,忙碌超时为 5 秒。数据库位于项目中的 .reviews/reviews.db。

MCP 工具

AI Agent 可使用 10 个工具:

get_review_summary()

概览所有页面的评审数量。

Page         | Open | Resolved | Total
------------ | ---- | -------- | -----
user-profile |    3 |        1 |     4
dashboard    |    0 |        2 |     2
get_reviews(page_id?: str)

列出评审评论。可按页面筛选。显示状态、标签、元素上下文和回复链。

[#1] [OPEN] [bug] user-profile - alice: The header spacing is off
  → Element: Heading 2 'User Profile' | Selector: h2.page-title
[#2] [RESOLVED] user-profile - bob: Button color should be blue
get_annotated_reviews(page_id?: str)

仅返回带有元素标注元数据的评审。包含元素名称、CSS 选择器、完整 DOM 路径、选中文本、无障碍信息等 Agent 定位并理解标注元素所需的全部信息。

get_pending_work()

按页面分组列出所有未解决的评审,即 Agent 的“待办清单”。

## user-profile (2 open)
  - #1 [bug] (alice): The header spacing is off
  - #3 [suggestion] (alice): Add hover state to buttons

## dashboard (1 open)
  - #4 (bob): Chart labels are truncated
add_review(page_id, author, text, tag?, metadata?, parent_id?)

创建新的评审。支持标签、标注元数据(JSON),以及通过 parent_id 创建线程。

resolve_review(review_id, resolved_by?)

将评审标记为已解决。设置 resolved_at 时间戳和 resolved_by(默认为 "agent")。

reopen_review(review_id)

重新打开之前已解决的评审。清除解决信息。

batch_resolve(page_id, resolved_by?)

一次性解决某个页面上的所有未解决评审。返回 Resolved 3 review(s) on user-profile.

find_source_file_tool(page_id)

在 PROJECT_ROOT 中查找与页面 ID 匹配的源文件。按 kebab-case、CamelCase 和 glob 模式搜索。跳过 node_modules、dist、.git。

Found 3 file(s) for 'user-profile':
  - src/app/user-profile/user-profile.component.ts
  - src/app/user-profile/user-profile.component.html
  - src/app/shared/UserProfile.ts
get_setup_guide()

返回完整的设置指南(MCP 配置、REST API、浏览器 UI)。当 Agent 需要在新项目中协助设置评审系统时,此指南很有用。

典型 Agent 工作流
graph TD
    A["get_pending_work()"] -->|See what needs attention| B["get_annotated_reviews(page)"]
    B -->|Get element metadata for context| C["find_source_file_tool(page)"]
    C -->|Locate the source files| D["Read & edit the code"]
    D --> E{Resolve}
    E -->|Single| F["resolve_review(id)"]
    E -->|All on page| G["batch_resolve(page)"]

REST API

所有端点均位于 /api 下。已为所有来源启用 CORS。

评审
方法端点描述
GET/api/reviews/summary按页面提供摘要,包含未解决和已解决的数量
GET/api/reviews所有评审(按时间从新到旧排序)
GET/api/reviews/{page_id}某个页面的评审。查询参数:?status=open|resolved、?tag=bug|suggestion|...
POST/api/reviews/{page_id}创建评审
PATCH/api/review/{id}更新评审(状态、文本、标签、元数据)
DELETE/api/review/{id}永久删除评审
回复
方法端点描述
GET/api/review/{id}/replies获取评审的所有回复(按时间顺序)
POST/api/reviews/{page_id}创建回复(在请求正文中包含 parent_id)
POST 正文
字段类型默认值描述
textstring-评审评论(必填)
authorstring"anonymous"评审者姓名
tagstring"general""general"、"bug"、"suggestion" 或 "question"
metadataobject-标注上下文(元素、选择器、样式等)
parent_idinteger-线程回复对应的父评审 ID
PATCH 正文
字段类型描述
status"open" | "resolved"标记为已解决时会自动设置 resolved_at 和 resolved_by
textstring更新后的评论文本
tagstring更新后的标签
resolved_bystring解决此问题的人(通过 API 时默认为 "user",通过 MCP 时默认为 "agent")
metadataobject更新后的标注元数据

数据库

评审存储在项目中的 SQLite 数据库 {PROJECT_ROOT}/.reviews/reviews.db 内。首次运行时会自动创建数据库。

.reviews/ 目录包含:

文件用途
reviews.dbSQLite 数据库(提交到 git 即可与团队共享评审)
.gitkeep确保目录被纳入版本控制
.gitignore忽略 WAL 临时文件(*.db-wal、*.db-shm)

路径解析:

  1. REVIEW_DB_PATH 环境变量(显式覆盖)
  2. PROJECT_ROOT/.reviews/reviews.db(默认)
  3. ./reviews.db(备用)
架构
reviews (
  id          INTEGER PRIMARY KEY,
  page_id     TEXT NOT NULL,
  author      TEXT DEFAULT 'anonymous',
  text        TEXT NOT NULL,
  status      TEXT DEFAULT 'open',       -- 'open' | 'resolved'
  created_at  TEXT NOT NULL,             -- ISO 8601
  resolved_at TEXT,
  resolved_by TEXT,
  metadata    TEXT,                       -- JSON: annotation context
  tag         TEXT DEFAULT 'general',    -- 'general' | 'bug' | 'suggestion' | 'question'
  parent_id   INTEGER REFERENCES reviews(id)  -- threaded replies
)
标注元数据(JSON)

通过标注创建评审时,metadata 字段包含:

{
  "element": "Button 'Save'",
  "selector": "button.btn-primary",
  "boundingBox": { "x": 100, "y": 200, "width": 80, "height": 40 },
  "selectedText": "Click to save",
  "cssClasses": "btn btn-primary active",
  "nearbyText": "Save your work | [after:] Cancel",
  "nearbyElements": "Parent: form.editor (5 children) | Siblings: input, button.secondary",
  "computedStyles": "color: #fff, background: #3b82f6, border-radius: 4px",
  "fullPath": "body > div#app > div.modal > form > button",
  "accessibility": "role=\"button\", tabindex=\"0\", focusable",
  "isMultiSelect": false,
  "url": "http://localhost:4200/user-profile"
}

这些元数据为 AI Agent 提供关于标注内容的精确上下文——包括标注的是哪个元素、元素所在位置、外观,以及如何在 DOM 中找到它。


Web Component 属性

属性必填描述
api-url是REST API 基础 URL(例如 http://localhost:3200/api)
page-id否用于筛选评审的显式页面标识符。若省略,则使用自动检测(推荐)
页面识别

面板需要知道用户当前所在的页面,以便显示并提交该页面的评审。有两种模式:

自动检测(推荐)

未设置 page-id 属性时,面板会根据 URL 路径名推导页面标识符:

URL页面 ID
/home
/analyticsanalytics
/settingssettings
/user/profileuser/profile

面板还会监听 SPA 导航事件(pushState、replaceState、popstate),并在路由变更时自动重新加载评审。这意味着它开箱即用,可与 React Router、Vue Router、Angular Router、Next.js 等客户端路由配合使用。


<review-panel api-url="http://localhost:3200/api"></review-panel>
显式页面 ID

如果需要自行控制页面 ID(例如,页面与 URL 路径无法一一对应),请设置 page-id 属性:

<review-panel api-url="http://localhost:3200/api" page-id="dashboard"></review-panel>

**重要提示:**这两种模式互斥。设置 page-id 后,将完全禁用自动检测,面板不会响应路由变化。请勿同时使用这两种模式。

编程 API
const panel = document.querySelector('review-panel');

// Change page without reloading
panel.setPageId('dashboard');

软件包

软件包注册表描述
ui-ticket-mcpPyPIPython MCP 服务 + REST API
ui-ticket-panelnpm<review-panel> Web 组件
ui-ticket-corenpm与框架无关的核心:类型、API 客户端、响应式存储、标注引擎

环境变量

变量默认值描述
PROJECT_ROOT-被审查项目的根目录。数据库会自动创建在 {PROJECT_ROOT}/.reviews/
REVIEW_DB_PATH(auto)显式覆盖数据库路径。优先级高于 PROJECT_ROOT
REVIEW_PORT3200REST API 服务端口

框架示例

使用打包工具

在入口文件中(例如 main.ts、main.js):

import { defineReviewPanel } from 'ui-ticket-panel';
defineReviewPanel();

然后在 HTML 中:

<review-panel api-url="http://localhost:3200/api"></review-panel>
纯 HTML(无打包工具 / CDN)
<script type="module" src="https://unpkg.com/ui-ticket-panel/dist/bundle.js"></script>
<review-panel api-url="http://localhost:3200/api"></review-panel>
React
import { defineReviewPanel } from 'ui-ticket-panel';
defineReviewPanel();

function App() {
  return <review-panel api-url="http://localhost:3200/api" />;
}
Vue
<template>
  <review-panel api-url="http://localhost:3200/api"></review-panel>
</template>

<script setup>
import { defineReviewPanel } from 'ui-ticket-panel';
defineReviewPanel();
</script>
Angular
// app.config.ts
import { defineReviewPanel } from 'ui-ticket-panel';
defineReviewPanel();

// component - add CUSTOM_ELEMENTS_SCHEMA
@Component({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `<review-panel api-url="http://localhost:3200/api"></review-panel>`
})
Svelte
<script>
  import { defineReviewPanel } from 'ui-ticket-panel';
  defineReviewPanel();
</script>

<review-panel api-url="http://localhost:3200/api"></review-panel>
Next.js(SSR)

Web 组件使用 window 和 HTMLElement,而这两者在服务器端渲染期间不存在。你必须在客户端动态加载面板:

// components/ReviewPanel.tsx
'use client';
import { useEffect } from 'react';

export default function ReviewPanel() {
  useEffect(() => {
    import('ui-ticket-panel').then(m => m.defineReviewPanel());
  }, []);
  return <review-panel api-url="http://localhost:3200/api" />;
}

然后在根布局中使用:

// app/layout.tsx
import ReviewPanel from './components/ReviewPanel';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <ReviewPanel />
      </body>
    </html>
  );
}
Nuxt(SSR)
<template>
  <ClientOnly>
    <review-panel api-url="http://localhost:3200/api"></review-panel>
  </ClientOnly>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(async () => {
  const { defineReviewPanel } = await import('ui-ticket-panel');
  defineReviewPanel();
});
</script>
SvelteKit(SSR)
<script>
  import { onMount } from 'svelte';

  onMount(async () => {
    const { defineReviewPanel } = await import('ui-ticket-panel');
    defineReviewPanel();
  });
</script>

<review-panel api-url="http://localhost:3200/api"></review-panel>

问题与反馈

发现 Bug 或有功能需求?请在此代码仓库中提交问题。


许可证

CC BY-NC 4.0 — 可免费用于学习、研究和非商业用途。详情请参阅 LICENSE。


由 Šimon Cmar、Ladislav Sopko 和 Lorenzo Leoni 构建

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。