qq-bridge
Identified★ 294Bridge between QQ (SnowLuma OneBot v11) and DeepSeek Harness agents: social simulation, safe MCP tools, slang learning and more.
QQ ↔ DeepSeek Harness Bridge
English: README.en.md | 中文: README.md
📘 See docs/PROJECT_GUIDE.md for the detailed outer/inner kernel manual (architecture, data flow, full configuration reference, debugging and improvement guide).
🔒 See RULES.md for the permission boundaries and security commitments of QQ sessions.
Wire QQ messages into the DSH agent: messages sent by QQ friends/groups become user messages in the DSH session, and agent replies (including questions and tool approvals) are sent back to QQ.
⚠️ Current version
v0.1.5, targeting DSH 0.1.5-rc.1 (verified item by item on that version). Uses Cookie authentication, slash RPC, and the/api/remote.muxevent stream; this protocol generation was introduced in DSH0.1.2-alpha.1and is incompatible with the earlier dotted-endpoint protocol — for DSH0.1.1-rc.2or earlier, use tagv0.1.0instead.The default branch
mainis this version; a plaingit clonegets you there with no branch switching required.
QQ 消息 ──► SnowLuma(OneBot v11 WS)──► 本桥接进程 ──► DSH Web API (127.0.0.1:3080/api)
▲ │
└── agent 回复/提问/审批 ┘
Project Showcase
📽️ AI Simulated Group Member - Project Intro Video (~11 MB)
The video is now hosted as a Release asset instead of in the repo — installing the bridge no longer requires downloading this 11 MB (it previously made up 88% of the total repo size).
Architecture
- QQ 侧:
@snowluma/sdk的SnowLumaWebSocketClient(OneBot v11 WebSocket 客户端,自动重连) - DSH 侧:适配 DSH 0.1.2 起、0.1.5 复核通过的协议——launch token 换 Cookie 鉴权、
/api/<namespace>/<method>斜杠 RPC、/api/remote.mux+session/follow事件流;复用AbstractApiClient传输层但不再依赖旧版 zod value schema。会话模型由桥接按config.json的dsh.model逐会话session.selectModel固定(默认deepseek-flash= DeepSeek-V41-Flash,多模态) - agent 自主收发 QQ:DSH 的 MCP 客户端(
~/.dsh/profiles/web/cordis.patch.yml配置)接入三个 MCP server:snowluma(桥接自带src/mcp-snowluma-safe.js):QQ 动作安全子集(查状态/查群/查消息/发消息,发送强制白名单;发送工具支持可选replyToMessageId引用回复)snowluma-host(桥接自带src/mcp-host-server.js):snowluma_status(默认只读探活);start_snowluma/stop_snowluma需显式开启snowluma.allowProcessControl: true且仅在closed-agent模式可用web-search-safe(桥接自带src/mcp-web-search-safe.js):只读web_search/web_fetch(带 SSRF 防护),供 agent 查网络用语/资料
- 会话模型:每个 QQ 会话(私聊/群)对应一个独立的 DSH 会话,统一归组到「QQ 聊天」工作区(不再散落未分组);映射持久化在
state/sessions.json - 性格定制:QQ 会话默认使用
qq-chatagent preset(~/.dsh/.agent-presets/qq-chat/agent.cordis.yml),reserved2使用qq-chat-v2(~/.dsh/.agent-presets/qq-chat-v2/agent.cordis.yml);人格与默认 DSH 一致(coding agent),仅附加 QQ 场景规则;角色扮演是可选机制——由控制台或管理端设置state/current-role.json注入(群友无法更改) - 本地控制台:桥接自带 Web 控制台
http://127.0.0.1:3100——切换运行模式(chat / closed-agent / reserved / reserved2)、设置角色、静默开关、查看活动日志、修改管理员/控制台令牌,全部即时生效;访问需要令牌(config.json的consoleToken,未配置时自动生成并打印在启动日志;控制台内可手动修改或重新生成) - 运行模式:
chat:白名单群 + 白名单私聊 → qq-chat 安全聊天closed-agent:仅私聊 owner(config.json 的 ownerQQ,可在控制台设置)→ 完整工具(默认用 DSH 自己声明的默认 preset,即standard;可在控制台「closed-agent preset」下拉改为任意 DSH preset),可在 QQ 上操控 DSHreserved(一代仿真):仿真群友,观望/活跃/试探/退场状态机,选择性参与、按空格分句发送、主动收尾reserved2(二代仿真,运行setup-dsh.mjs后 DSH 默认):文本不自动转发,AI 通过qq_get_unread_messages/qq_send_message等工具自主看消息、发言、等待、设置唤醒/潜水;DSH 端使用qq-chat-v2preset
- 交互增强:
- agent 通过
ask_user_question提问时,问题会转发到 QQ,回复即自动应答 - agent 请求工具审批时,转发到 QQ,回复「通过」/「拒绝」即可决策
- 支持 DSH 斜杠命令(如
/model)与/reset(重置会话上下文) - 群聊引用/回复会解析成「被引用人 + 原文」注入 DSH(如
[引用 Derp:El Psy Kongroo是啥]机关的走狗),让 AI 判断这句话是对谁说的,不会把群友之间引用第三方的对话误当成指向自己;引用机器人自己时会被视为必回 - MCP 发送工具支持可选
replyToMessageId,并新增专用qq_reply工具:AI 可以先用qq_get_group_history拿到真实消息 id,再引用/回复某条消息(是否允许 AI 主动使用由人格/策略决定;桥接会检测发送类工具调用并自动跳过该回合的重复自动转发) - 一代仿真模式(
reserved)下,AI 可以只输出[SILENT]表示“潜水/不接话”,桥接会静默不发送 - 一代仿真模式(
reserved)按空格分句:AI 用空格表示拆成多条消息;中英文/数字之间的空格也会被当成分条信号,不想分条就不要加空格(reserved2不适用,分条请用qq_send_message数组)
- agent 通过
Prerequisites
- A running DeepSeek Harness Web instance (default
http://127.0.0.1:3080) - A running SnowLuma instance with OneBot WebSocket and HTTP API configured (default
ws://127.0.0.1:3001/http://127.0.0.1:3000, fill inaccessTokenif configured) - Node.js ≥ 22.13
Install & Configure
npm install # 安装依赖(postinstall 会自动修补 @snowluma/sdk 的 ESM 打包 bug)
Copy config.example.json to config.json and then edit it:
Windows CMD users please use:
copy config.example.json config.json
⚠️ Real
config.jsonandstate/will not be committed to the public repository; the repository only provides a desensitizedconfig.example.jsontemplate.
| Field | Description |
|---|---|
dsh.baseUrl | DSH Web address, default http://127.0.0.1:3080 |
dsh.provider / dsh.model / dsh.reasoningEffort | Model/reasoning effort used by DSH sessions; if your DSH doesn't have the model shown in the example, change it to an available model in the DSH settings page (selection failure only logs, does not block startup) |
dsh.authToken | DSH launch token (process startup token used by new DSH to exchange for Cookie). If left empty, the bridge will automatically discover it from ~/.dsh/guard/logs/server-*.out.log; if encountering 401 after DSH restarts, it will automatically rediscover and exchange for Cookie |
dsh.authHeader / dsh.authPrefix | Reserved fields; current new DSH pipeline uses Cookie exchange and no longer sends this authentication header directly |
snowluma.wsUrl | SnowLuma OneBot WebSocket address (e.g., ws://127.0.0.1:3001) |
snowluma.httpUrl | OneBot HTTP API address (e.g., http://127.0.0.1:3000); do not fill in the WebSocket port, otherwise it will report HTTP 426 |
snowluma.accessToken | OneBot accessToken, leave empty if not configured |
snowluma.launcherPath / homeDir | SnowLuma launcher script and installation directory (for agent to auto start/stop) |
agentPreset | DSH agent preset used by QQ sessions, default qq-chat (see below for changing personality) |
socialV2.agentPreset | DSH agent preset used by reserved2 mode, default qq-chat-v2 |
workspaceTitle | Grouping name for QQ sessions in DSH interface, default "QQ Chat" |
allow.private / allow.groups | Whitelist (QQ number/group ID array); if empty and allowAllWhenEmpty: true, allow all |
deny.* | Blacklist, takes priority over whitelist |
ackMessage | Immediate reply after message delivery, empty string disables it |
sendDelayMs | Interval between consecutive QQ sends, prevents triggering rate limits |
consolePort | Local console port, default 3100 |
consoleToken | Console access token; if empty, auto-generated at startup and saved to state/console-token |
⚠️
allowAllWhenEmpty: truemeans "allow all if whitelist is empty"—connecting an agent to QQ is equivalent to handing account control to the model; it is recommended to fill in the whitelist first.
DSH-side Installation (Mandatory: install presets + mount MCP)
It is not enough for the bridge and console to run; the DSH side also requires installing two chat presets (qq-chat / qq-chat-v2) and mounting the MCP. This step is mandatory for new single-machine installations as well (it is not just for 'other devices'). After installation, you must restart DSH:
node scripts/setup-dsh.mjs
In a fresh environment, the script sets the DSH default mode to
reserved2(second-generation simulation) and creates a localstate/mode.jsonas a fallback. This ensures that when the AI uses tools likeqq_send_messageto send and receive messages, DSH automatically uses theqq-chat-v2mode. If an existing oldstate/mode.jsonor DSH setting value is present on the local machine, the script preserves it and does not overwrite it. Afterwards, you can switch modes via the button at the top of the bridge console (defaulthttp://127.0.0.1:3100); the console will write to both the DSH settings and the local fallback file.
For detailed steps, see docs/DSH_SETUP.md.
Complete Startup Process (From Scratch)
6 steps in total. DSH is installed and running; what's missing is the SnowLuma core itself + the DSH-side installation on the bridge (steps 2 and 3 are the easiest to skip, and if you do, QQ will show no response at all):
-
DSH(已运行,无需操作) 确认
http://127.0.0.1:3080能打开即可。 -
装桥接并复制配置
git clone https://github.com/Derpyu520/qq-bridge.git cd qq-bridge npm installWindows CMD 用
copy config.example.json config.json,其他平台用cp config.example.json config.json。 示例模板里allow.private/allow.groups是空数组——空白名单 +allowAllWhenEmpty: false时桥接不响应任何消息(这是刻意的 fail-closed 默认值)。白名单在第 5 步填。 -
装 DSH 端(preset + MCP),然后重启 DSH
node scripts/setup-dsh.mjs装完必须重启 DSH——preset 与 MCP 只在 DSH 启动时加载。 跳过这步桥接不会崩,但群聊会话拿不到
qq-chatpreset,桥接会拒绝建会话(有意的安全设计:绝不回退到带 bash/文件工具的默认 preset),表现同样是 QQ 上没反应。 -
下载并解压 SnowLuma
- 下载:https://github.com/SnowLuma/SnowLuma/releases/latest 选
SnowLuma-v<版本>-win-x64.zip(完整版,自带 Node 运行时;Lite 版需本机 Node 22.13+) - 解压到任意目录(例如
C:\SnowLuma),双击launcher.bat
- 下载:https://github.com/SnowLuma/SnowLuma/releases/latest 选
-
首次引导(WebUI)+ 填写桥接配置
-
打开启动日志里的 WebUI 地址(README 写的是
http://localhost:5099,以你启动日志里实际打印的为准) -
用启动日志中的初始密码登录,按引导:同意条款 → 设置密码 → 接入 QQ 进程(扫码登录)
-
在 WebUI 里配置 OneBot 连接:开启 WebSocket 服务端 和 HTTP API,分别记下端口(默认 WS
3001、HTTP3000)和 accessToken(若配置了) -
回到
config.json填好snowluma段,并把allow.private/allow.groups换成你自己的 QQ 号 / 群号:"snowluma": { "wsUrl": "ws://127.0.0.1:3001", "httpUrl": "http://127.0.0.1:3000", "accessToken": "你在 WebUI 里配置的 token(没配置就留空)" }
wsUrl是 OneBot WebSocket 端口,httpUrl是 OneBot HTTP API 端口(不要填成同一个 WS 端口,否则 MCP 工具会报 HTTP 426)。 -
-
启动桥接
npm start # 前台运行(崩溃不自动重启)看到
SnowLuma 已连接即成功;然后 QQ 上给机器人账号发条消息测试。 Windows 想要「崩溃自动重启」请改用start.bat(见下节)。
Running & Operations
npm start # 或双击 start.bat(守护模式:崩溃自动重启,关闭窗口即停止)
⚠️ Important:
- Only one instance of the bridge can run (a single-instance lock is used; duplicate startup attempts are rejected with a prompt that "an instance is already running")
- Launch via start.bat (in daemon mode); do not close the window — if the bridge crashes, it will automatically restart after 5 seconds
- If the bridge is unresponsive to exceptions or messages: double-click
restart.bat(automatically kills the old instance → clears the lock → restarts the daemon) - Restarting DSH usually does not require touching the bridge: the bridge pings DSH every 5 seconds. QQ messages received while DSH is unavailable are queued in the bridge process memory (up to 50 per session; the oldest items are discarded when full). Pending messages are attempted to be delivered after recovery. Exiting the bridge process clears the in-memory queue; no guarantee is made for resending replies that already ended during a disconnection.
- Changes to
config.json/roles//state/current-role.jsontake effect after restarting the bridge; changes to~/.dsh/.agent-presets/qq-chat*/or MCP configuration take effect after restarting DSH
Log example:
12:00:01 [bridge] SnowLuma 已连接:ws://127.0.0.1:3001
12:00:02 [bridge] 新会话 private:12345678 -> sess_xxxx
12:00:02 [bridge] 已投递 private:12345678: 你好
12:00:20 [bridge] agent 回复 (private:12345678) 42 字
Self-test (No SnowLuma / QQ required)
Offline regression tests (using a temp dir and mock services; no real config read, no QQ messages sent):
npm run test:audit
Details of this round of review and fixes are in docs/AUDIT_REPORT_2026-09-18.md. After upgrading, QQ sessions without permission metadata will be rebuilt once for legacy mappings. Mode or preset changes also trigger an automatic rebuild to avoid retaining old permissions. Old history remains in DSH.
Verify the DSH-side chain is connected (creates an isolated test session, existing sessions unaffected):
npm run self-test
Expected output: Connection successful → Test session created → Prompt accepted → Agent reply printed.
Directory Layout
qq-bridge/
config.example.json # 配置模板(脱敏占位符;真实 config.json 不入库)
docs/
PROJECT_GUIDE.md # 公开版项目说明书
dsh/agent-presets/ # qq-chat / qq-chat-v2 的 DSH agent preset 模板
plugins/qq-mode-console # DSH 插件:注册 qq-mode 设置命名空间(仅 host 半,UI 卡片未实现)
src/
bridge.js # 主程序
dsh-client.js # Node 版 DSH API 客户端(WS 下行)
md-to-plain.js # Markdown → QQ 纯文本
self-test.js # DSH 侧自测
scripts/ # 测试/运维脚本(含 postinstall 的 patch-snowluma-sdk.mjs)
patch-snowluma-sdk.mjs # 修补 SDK 的 ESM 打包 bug(postinstall 自动执行)
state/ # 运行时数据(不入库)
Known Limitations
- agent 回复在回合结束时一次性发送(不做流式逐字转发);回复超过 4000 字自动分段
- 图片及部分表情可以通过安全下载接入多模态模型;语音/视频以及无法取得图片字节的消息仍使用占位文本
- agent 的 Markdown 回复会转成纯文本(链接保留
文字 (url)形式) @snowluma/sdk的 npm 发布版存在 ESM 扩展名 bug,本仓库通过 postinstall 补丁修复(见scripts/patch-snowluma-sdk.mjs)
Compliance Notice
SnowLuma is an independent third-party project, unaffiliated with Tencent/QQ, and is provided for learning and technical research only; please read its EULA and the QQ User Agreement before use.
Comments
Loading…
From the same category
by esengine
DeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.
★ 35.8k
MIT
Go
Oct 11, 2026
by YaoApp
✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.
★ 8.1k
Go
Oct 8, 2026
by loopx-project
Long-horizon agent control plane for durable, governed work across Codex, Claude Code, and other harnesses.
★ 6.2k
Apache-2.0
Python
Oct 11, 2026
by huangruiteng
Long-horizon agent control plane for durable, governed work across Codex, Claude Code, and other harnesses.
★ 5.9k
Apache-2.0
Python
Sep 19, 2026
by AdamPlatin123
DSH Plugin Radar — 开源可自部署的 DSH 插件生态雷达:自动发现 15900+ 候选、k8s 运行级实测管线;自动索引可用Plugin List
★ 1.5k
MIT
Python
Oct 11, 2026
by inclusionAI
Distributed agent coordination platform where agents live, connect, coordinate, execute, and evolve together.
★ 571
Apache-2.0
Python
Oct 3, 2026