DSH Plugins Marketplace

DSH Plugins

Apps

/

Integrations

/

qq-bridge

q

qq-bridge

Identified★ 294

Bridge 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.mux event stream; this protocol generation was introduced in DSH 0.1.2-alpha.1 and is incompatible with the earlier dotted-endpoint protocol — for DSH 0.1.1-rc.2 or earlier, use tag v0.1.0 instead.

The default branch main is this version; a plain git clone gets 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-chat agent 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 上操控 DSH
    • reserved(一代仿真):仿真群友,观望/活跃/试探/退场状态机,选择性参与、按空格分句发送、主动收尾
    • reserved2(二代仿真,运行 setup-dsh.mjs 后 DSH 默认):文本不自动转发,AI 通过 qq_get_unread_messages / qq_send_message 等工具自主看消息、发言、等待、设置唤醒/潜水;DSH 端使用 qq-chat-v2 preset
  • 交互增强:
    • 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 数组)

Prerequisites

  1. A running DeepSeek Harness Web instance (default http://127.0.0.1:3080)
  2. 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 in accessToken if configured)
  3. 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.json and state/ will not be committed to the public repository; the repository only provides a desensitized config.example.json template.

FieldDescription
dsh.baseUrlDSH Web address, default http://127.0.0.1:3080
dsh.provider / dsh.model / dsh.reasoningEffortModel/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.authTokenDSH 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.authPrefixReserved fields; current new DSH pipeline uses Cookie exchange and no longer sends this authentication header directly
snowluma.wsUrlSnowLuma OneBot WebSocket address (e.g., ws://127.0.0.1:3001)
snowluma.httpUrlOneBot 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.accessTokenOneBot accessToken, leave empty if not configured
snowluma.launcherPath / homeDirSnowLuma launcher script and installation directory (for agent to auto start/stop)
agentPresetDSH agent preset used by QQ sessions, default qq-chat (see below for changing personality)
socialV2.agentPresetDSH agent preset used by reserved2 mode, default qq-chat-v2
workspaceTitleGrouping name for QQ sessions in DSH interface, default "QQ Chat"
allow.private / allow.groupsWhitelist (QQ number/group ID array); if empty and allowAllWhenEmpty: true, allow all
deny.*Blacklist, takes priority over whitelist
ackMessageImmediate reply after message delivery, empty string disables it
sendDelayMsInterval between consecutive QQ sends, prevents triggering rate limits
consolePortLocal console port, default 3100
consoleTokenConsole access token; if empty, auto-generated at startup and saved to state/console-token

⚠️ allowAllWhenEmpty: true means "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 local state/mode.json as a fallback. This ensures that when the AI uses tools like qq_send_message to send and receive messages, DSH automatically uses the qq-chat-v2 mode. If an existing old state/mode.json or 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 (default http://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):

  1. DSH(已运行,无需操作) 确认 http://127.0.0.1:3080 能打开即可。

  2. 装桥接并复制配置

    git clone https://github.com/Derpyu520/qq-bridge.git
    cd qq-bridge
    npm install
    

    Windows CMD 用 copy config.example.json config.json,其他平台用 cp config.example.json config.json。 示例模板里 allow.private / allow.groups 是空数组——空白名单 + allowAllWhenEmpty: false 时桥接不响应任何消息(这是刻意的 fail-closed 默认值)。白名单在第 5 步填。

  3. 装 DSH 端(preset + MCP),然后重启 DSH

    node scripts/setup-dsh.mjs
    

    装完必须重启 DSH——preset 与 MCP 只在 DSH 启动时加载。 跳过这步桥接不会崩,但群聊会话拿不到 qq-chat preset,桥接会拒绝建会话(有意的安全设计:绝不回退到带 bash/文件工具的默认 preset),表现同样是 QQ 上没反应。

  4. 下载并解压 SnowLuma

  5. 首次引导(WebUI)+ 填写桥接配置

    • 打开启动日志里的 WebUI 地址(README 写的是 http://localhost:5099,以你启动日志里实际打印的为准)

    • 用启动日志中的初始密码登录,按引导:同意条款 → 设置密码 → 接入 QQ 进程(扫码登录)

    • 在 WebUI 里配置 OneBot 连接:开启 WebSocket 服务端 和 HTTP API,分别记下端口(默认 WS 3001、HTTP 3000)和 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)。

  6. 启动桥接

    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.json take 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

DeepSeek-Reasonix

by esengine

DeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.

Integrations

★ 35.8k

MIT

Go

Oct 11, 2026

Index only — not installable

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.

Integrations

★ 8.1k

Go

Oct 8, 2026

Index only — not installable

by loopx-project

Long-horizon agent control plane for durable, governed work across Codex, Claude Code, and other harnesses.

Integrations

★ 6.2k

Apache-2.0

Python

Oct 11, 2026

Index only — not installable

by huangruiteng

Long-horizon agent control plane for durable, governed work across Codex, Claude Code, and other harnesses.

Integrations

★ 5.9k

Apache-2.0

Python

Sep 19, 2026

Index only — not installable

by AdamPlatin123

DSH Plugin Radar — 开源可自部署的 DSH 插件生态雷达:自动发现 15900+ 候选、k8s 运行级实测管线;自动索引可用Plugin List

Integrations

★ 1.5k

MIT

Python

Oct 11, 2026

Index only — not installable

by inclusionAI

Distributed agent coordination platform where agents live, connect, coordinate, execute, and evolve together.

Integrations

★ 571

Apache-2.0

Python

Oct 3, 2026

Index only — not installable