Introduction¶
If you have implemented agents in DSH, you will likely encounter the same need: the model chats well in the panel, can it connect to QQ so users can send messages directly? The common approach is to pull a NapCat or go-cqhttp client yourself, install the login state, and write a set of message receiving/sending services—the installation and deployment costs for this step are often higher than writing the business logic.
The plugin introduced below, luchengfj/qq-bot (panel plugin name @local/qq-bot), targets this pain point. It belongs to the “Everything is a Plugin” philosophy within the DeepSeek Harness ecosystem, maintained by luchengfj, aiming to turn Harness into a QQ bot channel: receiving text and image messages, invoking the model to generate answers, and sending the answers back. Its design approach differs significantly from the above types of solutions—the plugin itself is pure Node implementation, zero npm dependencies, doesn’t download, doesn’t install, doesn’t start any QQ client, and no longer downloads NapCat automatically; to interface with real QQ, it reuses an already installed and running OneBot v11 implementation endpoint.
What is this¶
One-sentence positioning: A DSH panel plugin providing a channel for QQ bot message sending and receiving, with direct chat verification available in the panel by default; connecting to real QQ is an optional capability.
The repository is https://github.com/luchengfj/qq-bot, license MIT, version declared as 1.0.0 in package.json, and engines.dsh requires >=0.1.7-rc.1. The current repository has 0 stars, indicating no large-scale user feedback yet; functionality is based on the README.
The plugin is based on the OneBot v11 protocol, adapted for NapCatQQ, Lagrange.Core, LLOneBot, go-cqhttp, and other already installed implementation endpoints.
Core Features¶
Below, the verified capabilities listed in the README are explained item by item.
1. Panel Direct Chat Test (Default path, zero download)
In the sidebar “QQ Bot” panel, the “① Direct Chat Test” block allows sending text or images without installing anything, following the complete BotLogic pipeline: receive image → memory / context → model answer → chunked reply. This means you can immediately verify that the plugin’s complete link works without connecting to any QQ endpoint.
2. Default Follow Harness Model, No API Key
Default llm.mode='harness', follows the current model selected in Harness, no API key needed. Image messages go through the attachment service. You can also switch to external, using the OpenAI-compatible /chat/completions endpoint, at which point an apiKey is required. The external endpoint can be switched to OpenAI, DeepSeek, local Ollama / vLLM, or any other compatible service.
3. Auto-detect + Auto-connect Local OneBot Port
On plugin startup, it automatically scans common ports on the local machine (default 3001, 3000, 5700, 8080, 6099, 3333), tries the / and /onebot paths for each port, sends a OneBot get_version probe (receiving a meta_event / lifecycle push also counts as a hit), and auto-connects when a usable service is found. It rescans every 20 seconds by default. The plugin’s own 6700 port is always excluded from the scan. Manually entered addresses are never overwritten—auto-detection is only enabled when no forward WS address has been configured or connected.
4. Four Ways to Interface with Existing OneBot Implementations
Besides auto-detection, the other three manual ways:
- Forward WebSocket (Plugin initiates connection): Fill in a running OneBot v11 forward WS address, or write to the
forward:block incordis.patch.yml. - Reverse WebSocket (Implementation connects back to plugin): Point any OneBot implementation’s reverse WS client address to
ws://127.0.0.1:6700/onebot. - HTTP POST Reporting: The same
/onebotpath also accepts OneBot HTTP POST reporting, wheresecretcan be used for HMAC-SHA1 signature; this unidirectional connection for sending replies requireshttpApiBasepointing to the OneBot HTTP API, and the first two methods are generally recommended.
5. Long-term Memory & Dialogue Context
The bot automatically remembers key facts stated by users (e.g., “My name is Xiao Ming”, “I live in Hangzhou”), completely isolating private and group chats, with no accumulation of overlapping topics; it automatically forgets if no speech is made for over memory.ttlDays (default 30 days). The dialogue context is a separate mechanism: it keeps the last few rounds of real Q&A and injects them into the model; it automatically clears after silence exceeds historyTtlMinutes, and /new can clear it immediately without affecting long-term memory.
6. Built-in Commands & Reply Cleaning
You can use /help, /status, /new, /memory, /forget in chat, all with Chinese aliases (/帮助, /状态, /换话题, /我的记忆, /忘记我); commands only take effect at the start of a message. After the model returns, the plugin performs local cleaning (lib/reply.js, no extra model calls): stripping intros and folding empty lines; when exceeding llm.maxReplyChars (default 600), it splits by paragraphs → sentences → spaces into multiple parts marked (1/4), rather than truncating directly.
Install & Enable¶
The installation method given in the README is mounting a directory; it does not write commands like dsh plugin add, so just execute the original text:
- Mount the plugin directory to Harness’s plugin directory;
- Or use the
insertline incordis.patch.ymlto point to this directory:
insert:
- { id: qq-bot, name: '@local/qq-bot' }
Then enable @local/qq-bot in DSH “Plugins”.
Note on loading rules: You must disable → re-enable after changing configuration or code for it to reload; local linked installed plugins will not auto hot-reload files.
Typical Usage¶
First do a zero-download verification, then connect to real QQ.
Step 1: Panel Direct Chat
1. Enable @local/qq-bot
2. Open the sidebar "QQ Bot" panel
3. Send a sentence (or paste an image) in the "① Direct Chat Test" input box
This step does not require a QQ client, does not require a token, and does not require an API key; it defaults to using the Harness native model. /help, /status, and other commands are also available in panel direct chat.
Step 2: Connect Real QQ
The README explicitly states the premise: QQ official has no “client-free” HTTP bot API, so to truly send and receive QQ messages, you still need a already installed and running OneBot v11 implementation endpoint; the plugin just no longer downloads it for you. The most hassle-free way is to configure nothing and let the auto-detect find it; you can also configure it manually. The entry point for modifying configuration is cordis.patch.yml:
host: 0.0.0.0
port: 6700
path: /onebot
The plugin defaults to listening on 0.0.0.0:6700, path /onebot. If using only locally, change host to 127.0.0.1.
Step 3: Run a Self-Check
The panel’s “③ Run Self-Check” checks 6 items one by one: OneBot listening, model backend, reverse WS connection, forward WS connection, panel direct chat availability, memory function, and includes model connectivity test, statistics zeroing, and real-time logs. After the self-check passes, you can send test messages via the panel’s send interface, reducing blind debugging time.
Panel & Interface Overview¶
The panel auto-refreshes every few seconds, organized into 5 grouped blocks (responsive two-column, single-column on narrow screens):
| Block | Content |
|---|---|
| ① Direct Chat Test | Verify receive image, answer, memory, and chunked reply without installing anything; Clear current session (chat-clear) |
| ② Connect Real QQ (Optional) | Auto-detect card (“Scan Now”, switch, candidate list), configure / disconnect forward WS address, reverse WS entry address, send test message |
| ③ Run Self-Check | 6 checks, model connectivity test, statistics zeroing, real-time logs |
| ④ Memory & Context | View / delete memory, change topic to clear context, write to disk immediately, view recent dialogue |
| ⑤ Config & Logs | Current configuration (read-only), full log ring, clear logs |
The panel registers 19 /api/qq-bot/* routes, all registered via ctx.webServer, only allowing same-origin local access: sec-fetch-site: cross-site, Origin and Host mismatch, non-loopback Host or remote address will be rejected (403). This means the panel is by default a local debugging interface; do not expect to expose it to the public network as an operations backend. Configuration in the panel is read-only by default, with the exception of forward WS, which can be changed in the panel and written to ~/.dsh/qq-bot-forward.json; other configurations should be edited in cordis.patch.yml then disable → enable.
Configuration Highlights¶
For the full list of configuration items, refer to cordis.patch.yml in the repository; here only a few items that are easy to trip over are listed:
llm:
mode: harness # harness: Follow current Harness model, no key needed (default)
# external: OpenAI compatible endpoint, requires apiKey
temperature: 0.4
maxReplyChars: 600
maxReplyParts: 4
allowPrivateImages: false # Default reject downloading intranet / local images, prevent SSRF
memory:
enabled: true
maxFacts: 60
ttlDays: 30
file: # Empty = in-memory only, invalid after restart; fill path to write to disk
detect:
enabled: true
ports: [3001, 3000, 5700, 8080, 6099, 3333]
intervalMs: 20000
excludePorts: [] # Plugin own port 6700 is always automatically excluded
trigger:
privateAlways: true # Whether to respond to all private messages
groupRequiresAt: true # Whether group messages require @bot or prefix
prefix: ""
allow:
groups: [] # Whitelist, empty = no restriction
users: []
denyUsers: []
A few worth noting default values: llm.allowPrivateImages defaults to false, so intranet or local image addresses will not be downloaded by default; trigger.groupRequiresAt defaults to true, so group messages require @ bot or a command prefix to trigger; the single image download limit is maxImageBytes: 8388608 (8MB).
Suitable Scenarios & Notes¶
Who is it for:
- People who have already installed OneBot v11 implementations like NapCatQQ, Lagrange.Core, LLOneBot, go-cqhttp, etc., and want to connect QQ to the Harness model with less glue code;
- People who want to verify the link in the panel first, then decide whether to connect to real QQ;
- People who want to default to not configuring any API key and directly reuse the current Harness model.
Notes:
- The plugin runs with the permissions of the current dsh process. Before installing, you should check the source code and license (MIT); do not expose it to a non-local network without reading the code.
- QQ official has no client-free bot API, so the so-called “zero download” means the plugin downloads nothing; real QQ sending and receiving still relies on an existing OneBot v11 endpoint.
- The plugin is pure Node implementation, zero npm dependencies, but
engines.dshrequires>=0.1.7-rc.1; this information comes frompackage.json, and actual compatibility depends on the installation environment. - Remember to disable → re-enable after changing configuration or code, otherwise it will not take effect.
- This repository has 0 stars, limited community verification. If you encounter issues, it is recommended to read the README and source code directly, or provide feedback to the maintainer luchengfj.
Conclusion¶
The value of this plugin lies in splitting “QQ bot connection” into a zero-download default path and an optional real connection path: the former allows debugging to start immediately, while the latter does not bear the cost of installing the QQ endpoint for you. If you already have a running OneBot v11 implementation and want it to chat directly in Harness with memory and images, you can try the auto-detection path.
Directory: https://www.skillhub.cn/plugins/luchengfj/qq-bot
GitHub: https://github.com/luchengfj/qq-bot