DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Plugin Discord — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
P

dsh-plugin-discord

Plugin Discord

DeepSeek Harness 的 Discord 桥接:在 Discord 中与您的 dsh 会话聊天,并与网页界面共享完全相同的会话

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:ghbhiee/dsh-plugin-discord#2eb3fec49af040a282ecc0ae365c918fd997ff66
README兼容性版本

兼容性与来源证明

Plugin Discord 以 dsh-plugin-discord 发布,当前版本为 0.6.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/8/29

版本

0.6.0stable
2026/8/29
0.5.3stable
2026/8/25
0.5.1stable
2026/8/20

相关插件

正在加载相关插件…

最新版
0.6.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 2
周下载
0
最近提交
2026/9/10
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Im@xmanrui/dsh-im将十一种 IM 渠道和一个公网 AI Office 接入本地 DeepSeek Harness。Pocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理

README

dsh-plugin-discord

Discord bridge for DeepSeek Harness (dsh): chat with your dsh sessions from Discord — the very same sessions the web UI shows, so a conversation started at your desk continues on your phone through Discord, and vice versa.

  • Messages from allowlisted Discord users/channels are relayed into a dsh session; the reply comes back as Discord messages (long replies are split, code fences survive the split).
  • /new starts a fresh session named like [Discord] 08-18 15:04 — the pinned title marks its origin in the web sidebar.
  • Sessions are created through the same agent-preset composition the web host uses, so they carry the full toolchain and can be opened, continued, and renamed in the web UI at any time. A session created on the web can be adopted from Discord with /use <id>.
  • Zero runtime dependencies: the gateway runs on Node's built-in WebSocket, REST on built-in fetch.

Commands

On startup the bridge registers these as real Discord slash commands (they appear in the / picker). Plain-text forms keep working as a fallback — typing /new and hitting Enter works even before registration propagates.

CommandEffect
(any text)Prompt the channel's current session (auto-creates one)
/new [标题]New session, date-stamped [Discord] title
/sessions (/list)Recent Discord-bridged sessions
/use <id> (/switch, /resume)Bind this channel to a session — web-created ids work too
/current (/session)Show the bound session and its status
/stop (/cancel)Cancel the running turn
/helpHelp

Any other /-prefixed text passes through as a prompt.

Proactive notify: HTTP API + MCP (monitoring / reminders / alerts)

Every deployment's bridge also serves its own bot as a push channel, so agents and daemons can message the user proactively instead of only replying. Because each dsh serves its own bot, sender identity follows the deployment: your local dsh notifies as its bot, your server's dsh as its bot.

What is automatic vs manual:

PieceAutomatic?
MCP server endpoint (POST /plugins/discord/mcp)✅ served on plugin boot, nothing to do
HTTP API (POST /plugins/discord/api/notify)✅ served on plugin boot
Bearer secret✅ auto-generated on first boot → <profile dir>/discord-notify.secret (0600); override via config notifySecret or env DSH_DISCORD_NOTIFY_SECRET
MCP client registration (making an agent see the tool)❌ one-time manual step per client, recipes below

Disable the whole surface with notifyEnabled: false.

HTTP API reference (for any application)

POST http://127.0.0.1:<dsh port>/plugins/discord/api/notify

AuthAuthorization: Bearer <secret> — read the secret from <profile dir>/discord-notify.secret (e.g. ~/.dsh/profiles/web/discord-notify.secret)
Body{"content": "text", "userId"?: "...", "channelId"?: "..."} — JSON, content required
Targetdefault = DM of the first allowedUsers entry; userId = another user's DM; channelId = a guild channel the bot can post in
ContentDiscord markdown; text over 2000 chars is split into several messages automatically
200{"ok": true, "channelId": "...", "messageIds": ["..."]}
400bad JSON / empty content
401missing or wrong bearer token
502Discord-side delivery failure ({"ok": false, "error": "..."})
curl -s -X POST http://127.0.0.1:3080/plugins/discord/api/notify \
  -H "authorization: Bearer $(cat ~/.dsh/profiles/web/discord-notify.secret)" \
  -H 'content-type: application/json' \
  -d '{"content": "⚠️ 磁盘使用率 92%"}'

The endpoint is loopback by default (dsh binds 127.0.0.1): callers on the same machine hit it directly; remote callers tunnel (ssh -L 3080:127.0.0.1:3080 host) or go through whatever reverse proxy already fronts your dsh.

Registering the MCP client (one-time, per agent)

The MCP server side (Streamable HTTP, tool discord_notify) is already running — these recipes just point a client at it.

dsh itself (gives every dsh agent the tool) — machine-wide ~/.dsh/cordis.patch.yml, then restart dsh:

- insert:
    - id: mcp-discord-notify
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: discord
        transport: streamable-http
        url: http://127.0.0.1:3080/plugins/discord/mcp
        headers:
          authorization: Bearer <contents of discord-notify.secret>

Claude Code:

claude mcp add --transport http discord \
  http://127.0.0.1:3080/plugins/discord/mcp \
  --header "Authorization: Bearer $(cat ~/.dsh/profiles/web/discord-notify.secret)"

Stdio-only MCP clients (via mcp-remote):

{ "command": "npx", "args": ["-y", "mcp-remote", "http://127.0.0.1:3080/plugins/discord/mcp", "--header", "Authorization: Bearer <secret>"] }

Copy-paste prompts for other agents

Give an agent this to make it register the MCP itself (fill in your paths):

帮我接入本机 dsh 的 Discord 通知能力:MCP 端点是 http://127.0.0.1:3080/plugins/discord/mcp(transport: streamable-http), 鉴权头 Authorization: Bearer <密钥>,密钥内容读文件 ~/.dsh/profiles/web/discord-notify.secret。请把它注册进你的 MCP 配置, 然后调用 discord_notify 工具发一条测试消息「MCP 接入成功」验证。

Give an agent this to make it use the HTTP API in code/scripts (no MCP needed):

本机有一个 Discord 推送接口,写监控/定时脚本需要通知我时调用它: POST http://127.0.0.1:3080/plugins/discord/api/notify, 请求头 Authorization: Bearer $(cat ~/.dsh/profiles/web/discord-notify.secret) 和 Content-Type: application/json,请求体 {"content": "通知文本"}。 返回 {"ok": true} 即送达;非 200 时把状态码和响应体记入日志,不要重试超过 3 次。

Or drop this one-liner into an agent's standing instructions (CLAUDE.md 等), so it always knows the channel exists:

需要主动通知用户时(任务完成、告警、提醒),POST http://127.0.0.1:3080/plugins/discord/api/notify,Bearer 密钥在 ~/.dsh/profiles/web/discord-notify.secret,body {"content": "..."}。

Inline questions (ask_user_question → Discord components)

When the agent asks the user a question (dsh's ask_user_question tool — option picks, confirmations, plan reviews), the bridge renders it as Discord inline components in the bound channel: a select menu for the options (multi-select supported), an ✏️ button that opens a modal for a free-text answer, and a cancel button. Picking an option updates the message in place and the agent's turn continues with the answer.

How it works: the harness dispatches questions on the Cordis waterfall user-questions/request, and the bridge takes a prepended seat on it — the browser's answerer claims a question outright, so a seat behind it would never see one. From the front, the bridge posts the Discord card and hands the same question on with next(), so both surfaces stay live and the first answer wins. A web answer visibly closes the Discord card.

Requires dsh >= 0.1.1 (the waterfall). On older hosts the seat simply never fires and questions stay web-only.

File transfer

Both directions work, and the agent is told about them (a capability notice is injected once per session when it is first driven from Discord):

  • Agent → Discord: the agent writes a line [discord-file: /absolute/path] in its reply; the bridge strips the line, and uploads the file as a Discord attachment (images render inline). Only files under the session's working directory (plus configured uploadRoots) and within maxUploadBytes are sent — a refusal is reported in the reply.
  • Discord → agent: files/images the user attaches are saved under the session cwd's .discord-uploads/ and their paths are appended to the prompt, so the agent can read them directly.

Install

dsh plugin --profile web add github:ghbhiee/dsh-plugin-discord

Provide the bot token via the DSH_DISCORD_TOKEN environment variable of the dsh process (recommended — nothing secret touches the profile YAML). Under a launchd deployment that means the service plist's EnvironmentVariables dict; under systemd, an Environment= line; in a shell, plain export.

Then configure the row in the profile's cordis.patch.yml:

- id: discord-bridge
  config:
    allowedUsers: ["<your discord user id>"]
    # allowedChannels: ["<guild channel id>"]   # empty = DM-only
    cwd: /Users/you/projects         # where new sessions live
    # preset: ""                     # agent preset; empty = deployment default
    # titlePrefix: "[Discord] "

Token lookup order: config.token → $DSH_DISCORD_TOKEN (name configurable via tokenEnv) → tokenFile (raw token or an env-style file).

The bridge refuses to start when both allowlists are empty — an unrestricted bridge would hand your agent (and its tools) to anyone who can DM the bot.

Configuration

FieldDefaultMeaning
token""Bot token; empty falls back to tokenEnv, then tokenFile
tokenEnvDSH_DISCORD_TOKENEnvironment variable consulted when token is empty
tokenFile""File holding the token — raw, or env-style KEY=value lines. Keeps the secret out of profile YAML
tokenFileKeyDISCORD_BOT_TOKENKey looked up when tokenFile is env-style
allowedUsers[]Discord user ids allowed to talk (required for DMs)
allowedChannels[]Guild channel ids the bridge listens in; empty = DM-only
cwdhome dirWorking directory of newly created sessions (created if missing). An already-bound session keeps the cwd it was created with — use /new after changing this
preset""Agent preset for new sessions; empty composes the default
titlePrefix"[Discord] "Title prefix marking Discord-originated sessions
maxChunksPerReply6Cap on Discord messages per reply (overflow truncated with a notice)
maxUploadBytes8000000Cap on one outgoing attachment ([discord-file: …])
uploadRoots[]Extra directories the agent may upload from (session cwd is always allowed)
maxIncomingBytes25000000Cap on one incoming Discord attachment saved to disk
stateFile""Channel→session binding file; empty derives one in the profile dir

Local end-to-end test without Discord

scripts/fake-discord.mjs runs a scripted fake Discord (gateway + REST) on ws://127.0.0.1:8931 / http://127.0.0.1:8932. Point the plugin at it via gatewayUrl/restBaseUrl (any token), restart dsh, and the script drives a whole conversation — session creation, /new, /use, context continuity — against your real dsh deployment, printing every reply the bridge sends.

Discord application setup

  1. Discord developer portal → your application → Bot.
  2. Enable the Message Content Intent (needed for guild-channel text; DMs work without it — the bridge automatically retries without the intent if refused and warns in the log).
  3. Invite the bot to your server, or just DM it.

How the shared-session part works

  • New sessions go through agentPresets.resolve/mount — the identical composition path session.create uses on the web wire — and are persisted by the host's session persistence, so session.list shows them like any other session.
  • Resuming a cold session composes the preset recorded in its log, mirroring the web host's cold-resume path.
  • The bridge stamps each relayed prompt's message source with the Discord message id (the same pattern the web client uses with rpcId), then folds exactly the turn that prompt opened — a concurrently running web prompt in the same session is never mistaken for the Discord answer.
  • Model selection follows the session log (the web host's behavior), so switching models in the web UI carries over to later Discord turns.

Known limits

  • Replies arrive when the turn completes (typing indicator while it runs); no partial streaming edits yet.
  • Attachments/images from Discord are ignored — text only for now.
  • Approval prompts (tool permission questions) cannot be answered from Discord; sessions run with whatever approval policy the profile composes.
  • One bot token drives one gateway connection: do not reuse a token that another running bot (e.g. Hermes) is using, or you will knock it offline.
typingIntervalMs
8000
Typing-indicator refresh while a turn runs
gatewayUrl""Gateway URL override — a test seam for scripts/fake-discord.mjs
restBaseUrl""REST origin override — same test seam