Skip to main content
Glama
README.md
# quark-mcp

夸克 MCP Server — 通过夸克浏览器内置的 AI 对话页(`quark.cn/chat`,千问)提供**零 API 成本**的视觉、问答与文生图能力。

基于 CDP + Playwright 接管独立 profile 的夸克浏览器,在对话页上传图片提问、抓取回复返回,不需要 API Key。

## 能力

| 工具 | 说明 |
|------|------|
| `ask_quark` | 纯文本问答(复用会话,支持多轮上下文;`new_chat=true` 开新会话) |
| `vision_analyze` | 图片识别/分析(上传图片到对话页提问并取回复) |
| `image_generate` | 文生图(自然语言触发,一次约 4 张,存本地并返回路径) |
| `video_analyze` | 视频分析(下载/本地 → 抽帧烧时间戳 → 拼图分块 → 识别,可选本地转写) |
| `daemon_start` | 启动夸克 daemon(独立 profile,端口 9224,幂等) |
| `daemon_status` | 检查 daemon 运行状态与登录态 |
| `daemon_stop` | 关闭夸克 daemon |

## 工作原理

```
Claude Code ──MCP stdio──> server.py ──> quark_mcp/quark_ai.py ──CDP──> 夸克浏览器(独立 profile)
                                         quark_mcp/video_analyze.py         │
                                                                  quark.cn/chat(网页版千问)
```

- 夸克以 `--remote-debugging-port=9224` 启动独立 profile,登录态持久化
- 图片走 DataTransfer 注入(`JS_DROP_IMAGE`)而非 filechooser,等附件列表出现后再发送
- 回复完成判据:AI 回复轮 `[data-chat-answers-wrap]` 的卡片 class 出现 `completed`

## 环境要求

- Python 3.10+
- 夸克浏览器(自动探测 `QUARK_PATH` 环境变量或常见安装路径)
- `video_analyze` 需要 `ffmpeg`/`ffprobe`(抽帧)+ `pillow`(烧时间戳、拼图)
- 可选:`yt-dlp`(在线视频下载)、`faster-whisper`(`transcribe=True` 音频转写)

## 安装

```bash
pip install fastmcp playwright websocket-client
# 可选功能依赖
pip install pillow           # 视频帧时间戳烧录 + 拼图(video_analyze 必需)
pip install yt-dlp           # 在线视频下载(video_analyze 传 URL 时)
pip install faster-whisper   # 音频转写(transcribe=True)
```

pip 装的 `yt-dlp.exe` 常落在 `Scripts/` 而不在 PATH 上,代码里已做回退:
找不到 `yt-dlp` 命令时自动改用 `python -m yt_dlp`,所以不配 PATH 也能用。

## 使用

### 1. 作为 MCP server(Claude Code 等)

```json
{
  "mcpServers": {
    "quark-mcp": {
      "command": "python",
      "args": ["/path/to/quark-mcp/server.py"]
    }
  }
}
```

### 2. HTTP 模式(调试)

```bash
python server.py --port 8080
```

### 3. 直接 CLI 调用(不含 MCP)

```bash
# 启动 daemon(首次需手动登录一次,登录态持久化)
python quark_mcp/quark_ai.py --start
python quark_mcp/quark_ai.py --status

# 纯文本问答
python quark_mcp/quark_ai.py --ask "帮我解释一下 CDP 是什么"

# 图片识别
python quark_mcp/quark_ai.py --image photo.jpg --question "请描述这张图片"

# 文生图(默认存 ~/.claude/quark-images)
python quark_mcp/quark_ai.py --gen "一只橘猫坐在窗台看夕阳,插画风格"
python quark_mcp/quark_ai.py --gen "复古黄铜怀表" --outdir ./imgs --max-images 2

# 视频分析(本地文件或 URL)
python quark_mcp/video_analyze.py --video demo.mp4
python quark_mcp/video_analyze.py --video demo.mp4 --transcribe
```

## 生图说明

- **模型**:跟随夸克对话页默认(千问),不可指定
- **触发**:没有独立的「图像生成」技能开关,靠自然语言触发(prompt 里写清要画什么)
- **比例**:网页版无比例选择器,需在 prompt 里用文字描述(如「16:9 横构图」)
- **产出**:一次约 4 张,实测 960×1280 左右
- **下载**:CDN URL 带 `auth_key` 签名,必须走浏览器上下文(`page.request`)取图,裸 urllib 会 403

```python
# 返回结构
{"ok": True,
 "images": ["C:/Users/.../.claude/quark-images/quark_20260823-103519_1.png", ...],
 "text": "已生成 2 张图片, 保存至 ...",
 "meta": {"found": 4, "details": [{"path": ..., "bytes": ..., "width": 960, "height": 1280}],
          "model": "千问(夸克对话页默认)"}}
```

## 配置

- **夸克路径**:设置环境变量 `QUARK_PATH` 指定可执行文件
- **CDP 端口**:默认 `9224`,见 `quark_ai.py` 中的 `CDP_PORT`(与 doubao-mcp 的 9223 错开,可共存)
- **登录态**:独立 profile 位于 `~/.claude/quark-ai-profile`,首次 `daemon_start` 后手动登录一次即可
- **出图目录**:默认 `~/.claude/quark-images`,可用 `outdir` 覆盖

## 常见问题

- **退出码 1(CDP 不可达 / 未找到夸克)**:daemon 未启动,先 `daemon_start`;或设 `QUARK_PATH`
- **退出码 2(未登录)**:打开对话页手动登录一次
- **退出码 3(图片问题)**:路径不存在或上传失败
- **退出码 4(交互失败)**:输入框/发送按钮没找到,通常是页面改版
- **退出码 5(超时)**:生成较慢,增大 `timeout`(生图默认 300s)
- **退出码 6(结果为空)**:回复为空或未产出图片,可能是风控或内容被过滤

### 页面结构依赖

纯网页操作意味着夸克改版就可能失效。当前实测依赖(`quark_ai.py` 的 `SEL`,基于夸克 7.1.2.956 / Chromium 144 + 网页版 4.0.0):

| 用途 | 选择器 |
|------|--------|
| 输入框 | `textarea`(普通 textarea,非 contenteditable) |
| 发送 | `.submit-button` |
| AI 回复轮 | `[data-chat-answers-wrap]` |
| 用户提问轮 | `[data-chat-question-wrap]` |
| 完成标记 | `[class*="answer-common-card"]` 的 class 里出现 `completed` |
| 附件 | `[class*="upload-file-list"]`(附件挂载后才出现) |

两个坑:

1. 完成标记是回复卡片上的 `completed`,**不是** `.qk-markdown` 上的 `qk-markdown-complete`——后者是客户端面板的写法,网页版没有,照抄会永远判定「未完成」。
2. 生图要等「签名图 URL 集合稳定」,不能只看 `completed`——文字先 completed,成品图还要再约 45s 才把占位动画换掉。文字 completed 后再等 `IMAGE_GRACE`(120s)仍无图,才判定这轮不产图。

## License

MIT