Back to home@sazzadurrahmaan

dsh-telegram

Telegram channel for DeepSeek Harness — chat with your agent from Telegram, with a deny-by-default allowlist and in-chat approval for destructive tools.

Stars
0
Language
TypeScript
Created
Aug 22, 2026
Updated
Aug 22, 2026

Introduction

dsh-telegram

A Telegram channel for DeepSeek Harness. Message your bot, and the agent answers in the chat — the same agent, the same tools, the same session log as the Web UI.

Built for the case OpenClaw and Hermes already serve and Harness does not: reaching your agent from a phone, without leaving a shell open on a server that anyone with the bot's username can talk to.

What makes this one different

A Telegram bot wired to a coding agent is remote shell access through a chat app. Most bridges treat that as a detail. This one treats it as the design:

  • Deny by default. An empty allowlist admits nobody. Access is by numeric Telegram user id, checked before a message reaches the agent. There is no "allow everyone" flag.
  • In-chat approval for destructive tools. bash, pwsh, terminal, write, edit and str_replace_editor stop at a tools/pre-execute gate and ask in the chat, with Allow / Deny buttons. Only the chat the prompt was shown in can answer it, and the callback token is a random UUID. An unanswered prompt denies after a timeout.
  • One agent per chat, disposed with the plugin. No shared session between users.
  • No dependencies for the wire. The Bot API is called with fetch and long polling — no webhook, no framework, no bot library to audit. The whole client is one small file.

Install

dsh plugin --profile web add github:sazzadurrahmaan/dsh-telegram

Then set the token and your user id:

export DSH_TELEGRAM_TOKEN='123456:ABC...'          # from @BotFather
export DSH_TELEGRAM_ALLOWED_USER_IDS='123456789'   # yours; see /whoami below

Or configure it in ~/.dsh/cordis.patch.yml:

plugins:
  dsh-telegram:
    token: ${DSH_TELEGRAM_TOKEN}
    allowedUserIds: [123456789]
    cwd: /home/dsh/workspace

Don't know your numeric id? Message the bot /whoami — that one command answers anyone, because it only tells you your own id, which you need before you can be allowlisted. Every other message from an unlisted user is dropped.

Commands

CommandEffect
/startShow the command list
/newDispose this chat's agent and start a fresh session
/stopCancel the running turn
/statusSession id and agent state
/whoamiYour Telegram user id — the only command answered without allowlisting

Anything else is sent to the agent as a follow-up turn.

Configuration

KeyDefaultMeaning
token$DSH_TELEGRAM_TOKENBot token from @BotFather
allowedUserIds$DSH_TELEGRAM_ALLOWED_USER_IDS, else []Numeric ids allowed to talk to the agent
cwdharness defaultWorking directory for Telegram sessions
showToolActivitytruePost a line to the chat when a tool runs
allowDestructiveToolsfalseSkip the approval prompt entirely
gatedToolsshell and edit toolsTools that require approval
approvalTimeoutSec120An unanswered approval denies after this
pollTimeoutSec30Long-poll timeout for getUpdates

How it works

The plugin is an ordinary Cordis plugin on three extension points:

  • ctx.agents.create() mints one agent per chat; AgentHandle.dispose() tears it down.
  • session/event streams assistant/message back to the chat, split at Telegram's 4096-character limit after a newline where one fits. The split is lossless — rejoining the parts returns the original — so indentation inside a code block survives.
  • tools/pre-execute returns { kind: 'deny' } for a gated tool the user did not approve.

Every registration goes through ctx.effect(), so a reload unwinds the poll loop and disposes live agents.

Security notes

Read these before you point this at a machine you care about.

  1. The allowlist is the only thing between a stranger and your shell. Anyone can find a bot by username and message it. Keep allowedUserIds accurate and never set it from untrusted input.
  2. allowDestructiveTools: true removes the approval prompt. With it on, an allowed user can run any command the harness can run, from a phone, with no confirmation.
  3. Group chats are not supported. Add the bot to a group and every member's messages arrive; only allowlisted ids are answered, but the surface is larger than intended. Use a direct chat.
  4. The token grants control of the bot. Keep it in the environment, not in a committed config file.
  5. Developer preview. Harness is 0.1.x and its README warns of compatibility-breaking changes. Pin your Harness version, or expect to re-fix this against seam changes.

Project

Development

npm install --legacy-peer-deps   # the published rc packages have an internal peer conflict
npm run build
npm test

--legacy-peer-deps is needed because @deepseek-ai/dsh-agent@0.1.0-rc.6 requires dsh-invariants ^0.1.0-rc.6 while the dsh-llm@0.0.1-rc.1 chain requires ^0.0.1-rc.1. Those packages are peer dependencies here — at runtime they are resolved from the host harness, so this affects local type-checking only.

License

MIT