中文说明 · Security · Troubleshooting · Contributing · Changelog
Self-hosted QQ -> Codex / Claude Code CLI bridge for private chat and group @bot workflows.
It is designed for people who want to talk to Codex or Claude from QQ while keeping sessions, workspaces, long-running service behavior, and attachment handling under their own control.
- independent QQ bot credentials and
.env - QQ C2C and group
@botsupport - per-peer, per-provider session and workspace isolation
/status,/progress,/queue,/retry,/stop,/new,/sessions,/rename,/pin,/fork,/workspace,/repo,/changed,/patch,/open,/export,/branch,/diff,/commit,/rollback,/diag,/version,/stats,/audit- progress updates, queueing, cancellation, and session recovery
- attachment download, provider-aware image handling, text extraction, and optional image OCR
- context compaction and retry-on-stale-session behavior
- quick-action keyboards for short control messages, plus numeric fallback menus and risky-command confirmations in plain-text QQ sessions
- launchd support on macOS and systemd user-service support on Linux
Good fit:
- personal self-hosted use
- trusted small-team internal use
- power users who already run Codex CLI or Claude Code locally
Not a great fit without extra hardening:
- broad public multi-user deployments
- untrusted users with
dangerousmode enabled - hosts where downloaded attachments or generated file edits are unacceptable
This project can:
- execute Codex CLI or Claude Code tasks
- download attachments to local disk
- let the configured CLI read/write workspace files
- run in
dangerousmode
If you are exposing it beyond yourself, read SECURITY.md first.
- macOS: foreground run +
launchd - Linux: foreground run +
systemd --user - Windows: not officially supported yet
- Node.js
>=20 - npm
- Codex CLI or Claude Code installed and available on
PATHviaCODEX_BIN/CLAUDE_BIN - a dedicated QQ bot AppID / ClientSecret
- Copy config:
cp .env.example .envThe bundled .env.example includes every supported runtime knob with safe starter values.
If you want to use Claude Code, set PROVIDER=claude; otherwise the default stays on Codex.
- Fill in your dedicated QQ bot credentials:
QQBOT_APP_IDQQBOT_CLIENT_SECRET
- Install dependencies:
npm install- Run checks:
npm run ci
npm run doctor
npm run doctor:json- Start in foreground:
npm start- Or install as a long-running service for the current OS:
npm run install:service
npm run service:status- Common service lifecycle commands:
npm run service:restart
npm run uninstall:servicenpm run install:launchd
npm run service:status:launchd
npm run service:restart:launchd
npm run uninstall:launchdnpm run install:systemd
npm run service:status:systemd
npm run service:restart:systemd
npm run uninstall:systemdForeground / macOS:
npm run logsLinux systemd:
journalctl --user -u codex-cli-qq.service -f- send a normal message: hand it to the active provider
/help/help quick/whoami/status/state/diag/doctor/version/stats/audit/session/sessions/rename <title>/pin [session_id|clear]/fork [source_session_id] [title]/history/new/start/files/workspace [show|recent|set <path|index>|reset]/repo [status|log|path]/changed/patch [file]/open <file>/export diff [working|staged|all]/branch [name]/diff [working|staged|all]/commit <message>/rollback [tracked|all]/progress/queue/cancel/stop/retry/reset/resume <session_id|clear>/confirm-action list/profile default|code|docs|review|image/mode safe/mode dangerous/model <name|default>/effort low|medium|high|default
- Quick start
- send
/help quick - then send a normal message to let the active provider start working
- send
- Continue the last task
- just keep chatting
- use
/retryif you want to rerun the last executed request
- Jump back to an older session
- send
/sessions - reply with a number, or use
/resume <index|id>
- send
- Switch to another project directory
- send
/workspace recent - reply with a number, or use
/workspace set demo
- send
- Inspect changes
- send
/changed - then use
/diff,/open <file>, or/patch
- send
- Risky operations
- commands like
/rollback allor/mode dangerous - now require an explicit confirmation step; use
/confirm-action listif the prompt scrolled away
- commands like
QQBOT_ALLOW_FROM=*: allow all direct-message senders only if you trust the host/user scopeQQBOT_ALLOW_GROUPS=: leave empty for all groups, or set explicit allowlist valuesQQBOT_ENABLE_GROUP=true: enable group@botDEFAULT_MODE=dangerous: convenient for personal-only trusted useSHOW_REASONING=false: avoid flooding QQDOWNLOAD_ATTACHMENTS=true: let the active provider read downloaded files directlyEXTRACT_ATTACHMENT_TEXT=true: improve “summarize this document” style promptsMAX_GLOBAL_ACTIVE_RUNS=2: avoid saturating the machineCOMPACT_CONTEXT_ON_THRESHOLD=true: summarize before forcing a hard resetSEND_ACK_ON_RECEIVE=true: confirm receipt quicklyPROACTIVE_FINAL_REPLY_AFTER_MS=30000: switch to proactive reply for slow tasksAUTO_PROGRESS_PING_MS=15000: periodic progress updatesMAX_AUTO_PROGRESS_PINGS=2: cap periodic progress messagesPHASE_PROGRESS_NOTIFY=true: send milestone progress updates in private chatENABLE_QUICK_ACTIONS=true: attach quick-action keyboards to short control messagesQUICK_ACTION_RETRY_MS=21600000: if QQ rejects custom keyboards for this peer, auto-downgrade to plain text and retry laterTEXT_SHORTCUT_TTL_MS=600000: keep the plain-text numeric shortcut menu alive for a short timePENDING_ACTION_TTL_MS=600000: keep risky-command confirmation menus alive for a short timeRETRACT_PROGRESS_MESSAGES=false: recommended; QQ visibly shows recall noticesDELIVERY_AUDIT_MAX=120: keep recent delivery/run audit entriesQQ_API_TIMEOUT_MS=15000: timeout for QQ API requestsQQ_DOWNLOAD_TIMEOUT_MS=30000: timeout for attachment downloadsIMAGE_OCR_MODE=auto: image OCR mode (auto/on/off);autois biased toward screenshots / UI capturesMAX_IMAGE_OCR_CHARS_PER_FILE=1200: max OCR text injected per image
- private chat can proactively open a fresh session with
/new /sessions+/resume <id>lets you jump back to older sessions/rename,/pin,/forklet you treat long-running provider sessions as reusable “work threads”/queueshows the active job plus pending backlog, and/retryreplays the most recent executed prompt/workspace set demoquickly moves a peer toWORKSPACE_ROOT/demo, while absolute paths let you bind an existing local project/workspace recentlists recent paths and lets you switch by replying with a number- every workspace is also a lightweight Git repo, so
/repo,/branch,/diff,/commit, and/rollbackwork directly in chat /changed,/patch,/open, and/export diffmake it easier to inspect and hand off actual workspace artifacts from QQ- risky operations like
/rollback alland switching todangerousmode now require an explicit confirmation step - if a confirmation prompt scrolls away,
/confirm-action listbrings it back and/confirm-action latest confirmhandles the newest one directly - quick-action keyboards now auto-downgrade per peer when QQ rejects custom keyboards, so logs stay quieter and replies still arrive
/helpnow auto-switches to a shorter “QQ hand-typing menu” when the current peer is in text-only mode, with reply-by-number shortcuts; you can also jump straight to/help quick- images can optionally contribute OCR text in addition to being passed as image input;
automode is biased toward screenshots and UI error captures instead of ordinary photos - quick-action keyboards are optimized for QQ mobile layout, but client rendering can still vary
- progress recall is disabled by default because QQ shows a visible “message recalled” notice
Runtime-generated files are intentionally ignored by git:
.envlogs/data/workspaces/
Downloaded attachments are stored under:
workspaces/<peer>/.attachments/<messageId>/
For common setup and runtime issues, see docs/TROUBLESHOOTING.md.
QQ client layouts vary by platform and viewport width. This project uses a mobile-friendlier multi-row layout, but QQ may still compress or hide parts of the keyboard depending on the client.
Because QQ shows an explicit recall notice, which usually feels noisier than simply leaving the old progress message in place.
Yes, but it is intended for trusted self-hosted use. Do not share a dangerous deployment with untrusted users.
To avoid credential confusion, isolate permissions, and reduce blast radius if you rotate or revoke secrets.
They store session state, audit history, downloaded attachments, and per-peer workspaces so the active provider can continue context-aware work across chats.
See CONTRIBUTING.md.
See SECURITY.md.
See CHANGELOG.md.