@deadragdoll/tellymcp 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example.client +42 -52
- package/.env.example.gateway +48 -62
- package/CHANGELOG.md +3 -3
- package/README-ru.md +226 -376
- package/README.md +213 -1184
- package/TOOLS.md +320 -377
- package/VERSION.md +13 -13
- package/config/codex/plugins/telly-workflows/.codex-plugin/plugin.json +18 -0
- package/config/codex/plugins/telly-workflows/references/invariants.md +10 -0
- package/config/codex/plugins/telly-workflows/skills/telly-browser-screenshot/SKILL.md +27 -0
- package/config/codex/plugins/telly-workflows/skills/telly-collab-artifact/SKILL.md +22 -0
- package/config/codex/plugins/telly-workflows/skills/telly-human-telegram/SKILL.md +31 -0
- package/config/codex/plugins/telly-workflows/skills/telly-partner-note/SKILL.md +36 -0
- package/config/templates/env.both.template +39 -20
- package/config/templates/env.client.template +34 -19
- package/config/templates/env.gateway.template +37 -22
- package/dist/cli.js +322 -75
- package/dist/codexPluginInstaller.js +215 -0
- package/dist/lib/mixins/session.errors.js +34 -1
- package/dist/lib/pinoTargets.js +2 -2
- package/dist/moleculer.config.js +7 -5
- package/dist/services/features/telegram-mcp/browser.service.js +94 -1
- package/dist/services/features/telegram-mcp/collaboration.service.js +40 -3
- package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
- package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
- package/dist/services/features/telegram-mcp/gateway-socket.service.js +907 -85
- package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
- package/dist/services/features/telegram-mcp/mcp-http.service.js +8 -0
- package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
- package/dist/services/features/telegram-mcp/notify.service.js +127 -1
- package/dist/services/features/telegram-mcp/session-context.service.js +28 -1
- package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +132 -10
- package/dist/services/features/telegram-mcp/src/app/config/env.js +158 -52
- package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
- package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
- package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
- package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
- package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +120 -104
- package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
- package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +306 -26
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +697 -75
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
- package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
- package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
- package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
- package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +143 -42
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +139 -38
- package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
- package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +69 -70
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +444 -7093
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +149 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +642 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +65 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +108 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +665 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +226 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
- package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +409 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
- package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
- package/dist/services/features/telegram-mcp/standalone-http.service.js +12 -0
- package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
- package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
- package/dist/services/features/telegram-mcp/tools-sync.service.js +15 -1
- package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
- package/docs/STANDALONE-ru.md +172 -0
- package/docs/STANDALONE.md +172 -0
- package/package.json +10 -5
- package/scripts/build-package-artifact.sh +27 -0
- package/scripts/deploy-gateway.sh +64 -0
- package/scripts/deploy-onebot-branch.sh +27 -0
- package/scripts/postinstall.js +11 -36
- package/STANDALONE-ru.md +0 -274
- package/STANDALONE.md +0 -274
- package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
- package/dist/services/features/telegram-mcp/pair.service.js +0 -33
- package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
- package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
package/README.md
CHANGED
|
@@ -1,1341 +1,370 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
[English](README.md) | [Русский](README-ru.md) | [Standalone Guide](STANDALONE.md) | [Standalone RU](STANDALONE-ru.md) | [Screenshots](screenshots/README.md) | [Gallery](screenshots/GALLERY.md) | [Release Notes](VERSION.md)
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@deadragdoll/tellymcp)
|
|
6
|
-
[](https://www.npmjs.com/package/@deadragdoll/tellymcp)
|
|
7
|
-
[](https://nodejs.org/)
|
|
8
|
-
[](LICENSE)
|
|
9
|
-
|
|
10
|
-
TellyMCP is a self-hosted Telegram control plane for coding agents.
|
|
11
|
-
|
|
12
|
-
It pairs real agent sessions with Telegram, keeps them reachable from mobile, and lets them collaborate across local and remote machines.
|
|
13
|
-
|
|
14
|
-
It is not tied to one vendor or one coding assistant. If your agent can talk to an MCP server, it can use TellyMCP.
|
|
15
|
-
|
|
16
|
-
## Why it exists
|
|
17
|
-
|
|
18
|
-
Coding agents are useful until they leave the terminal:
|
|
19
|
-
|
|
20
|
-
- they need clarification while you are away from the desk
|
|
21
|
-
- they need approval before doing something risky
|
|
22
|
-
- they need screenshots, files, or notes passed between sessions
|
|
23
|
-
- they need a human or another agent to unblock work without breaking flow
|
|
24
|
-
|
|
25
|
-
TellyMCP gives each session a mobile control surface and a collaboration layer:
|
|
26
|
-
|
|
27
|
-
- `Live` tmux view and light control from Telegram
|
|
28
|
-
- session-scoped inbox and notifications
|
|
29
|
-
- workspace-aware file and note handoffs
|
|
30
|
-
- local and remote session collaboration
|
|
31
|
-
- support for mixed agent setups, as long as they speak MCP
|
|
32
|
-
|
|
33
|
-
## Core ideas
|
|
34
|
-
|
|
35
|
-
- `Live` tmux view and control inside Telegram Mini App
|
|
36
|
-
- `Collab` flows for local and remote agent sessions
|
|
37
|
-
- `.mcp-xchange` as a workspace-level handoff bus for notes, files, and screenshots
|
|
38
|
-
- MCP-native session pairing and session-scoped tools
|
|
39
|
-
- optional gateway mode for cross-machine and cross-bot projects
|
|
40
|
-
|
|
41
|
-
## Human-in-the-loop is one layer, not the whole product
|
|
42
|
-
|
|
43
|
-
Telegram HITL is still supported, but it is not the whole story:
|
|
44
|
-
|
|
45
|
-
- ask a human for clarification through Telegram
|
|
46
|
-
- receive unsolicited Telegram messages later through an inbox
|
|
47
|
-
- notify a human about progress, blockers, and approvals
|
|
48
|
-
|
|
49
|
-
## What makes it different from a simple Telegram bot bridge
|
|
50
|
-
|
|
51
|
-
- it is session-based, not just chat-based
|
|
52
|
-
- it understands local and remote collaboration targets
|
|
53
|
-
- it has a live terminal surface, not only message exchange
|
|
54
|
-
- it moves files through workspace-aware exchange paths, not just ad hoc uploads
|
|
55
|
-
- it can run as a standalone node or as a gateway-backed control plane
|
|
56
|
-
|
|
57
|
-
## Typical use cases
|
|
58
|
-
|
|
59
|
-
- keep a long-running agent reachable from your phone
|
|
60
|
-
- run different agents side by side, as long as each one can connect over MCP
|
|
61
|
-
- steer a tmux-based session without opening a laptop
|
|
62
|
-
- route work between `frontend`, `backend`, `review`, or other local sessions
|
|
63
|
-
- collaborate with remote sessions through a gateway-backed project
|
|
64
|
-
- send notes, screenshots, and real files through `.mcp-xchange`
|
|
65
|
-
- inspect or screenshot a local web app with `browser_*` tools and send results back to Telegram
|
|
66
|
-
|
|
67
|
-
## Tool groups
|
|
68
|
-
|
|
69
|
-
- session pairing and context
|
|
70
|
-
- Telegram ask/notify/inbox
|
|
71
|
-
- `Live` tmux control
|
|
72
|
-
- browser inspection and screenshots
|
|
73
|
-
- partner notes and partner files
|
|
74
|
-
- tools sync and version checks
|
|
75
|
-
|
|
76
|
-
The full MCP tool surface is documented later in this README and through the MCP server itself.
|
|
77
|
-
|
|
78
|
-
## Prerequisites
|
|
79
|
-
|
|
80
|
-
- Node.js 24+
|
|
81
|
-
- `tmux`
|
|
82
|
-
- Redis
|
|
83
|
-
- a Telegram bot token from BotFather
|
|
84
|
-
- for `gateway` / `both`: Postgres
|
|
85
|
-
- optional for durable fanout on gateway: RabbitMQ
|
|
86
|
-
- for `browser_*` tools: Playwright Chromium browser binaries
|
|
87
|
-
|
|
88
|
-
## tmux is strongly recommended
|
|
89
|
-
|
|
90
|
-
TellyMCP works best when the agent itself runs inside `tmux`.
|
|
91
|
-
|
|
92
|
-
Without `tmux`, the service can still run, but you lose the full interactive path:
|
|
93
|
-
|
|
94
|
-
- no Live View
|
|
95
|
-
- no tmux nudges
|
|
96
|
-
- no direct tmux control from Telegram Mini App
|
|
97
|
-
|
|
98
|
-
Typical start:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
tmux new -s backend
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
or attach later:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
tmux attach -t backend
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Why the tmux session name matters:
|
|
111
|
-
|
|
112
|
-
- it helps you distinguish running agents
|
|
113
|
-
- it appears in tmux-related UI and diagnostics
|
|
114
|
-
- it makes Telegram session switching and Live targeting easier to understand
|
|
115
|
-
|
|
116
|
-
Use short, meaningful names such as:
|
|
117
|
-
|
|
118
|
-
- `backend`
|
|
119
|
-
- `frontend`
|
|
120
|
-
- `review`
|
|
121
|
-
- `ops`
|
|
122
|
-
|
|
123
|
-
If you run multiple agents, put each one in its own tmux session or pane and pair them separately.
|
|
124
|
-
|
|
125
|
-
If a tmux pane is recreated and its pane id changes, TellyMCP now tries to recover the live pane target automatically from saved tmux session, window, and pane hints.
|
|
126
|
-
|
|
127
|
-
If auto-recovery fails, Telegram sends an operational warning so the problem is visible to the human user, not only in backend logs.
|
|
128
|
-
|
|
129
|
-
## Quick start
|
|
130
|
-
|
|
131
|
-
### Standalone client node
|
|
132
|
-
|
|
133
|
-
This is the simplest setup. No shared gateway, no Postgres, no RabbitMQ.
|
|
134
|
-
|
|
135
|
-
1. Install:
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
npm install -g @deadragdoll/tellymcp
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
2. Create a client config:
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
tellymcp init client
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
3. Edit the generated `.env` and set at minimum:
|
|
148
|
-
|
|
149
|
-
- `TELEGRAM_BOT_TOKEN`
|
|
150
|
-
- `TELEGRAM_BOT_USERNAME`
|
|
151
|
-
- `REDIS_HOST`
|
|
152
|
-
- `MCP_HTTP_BEARER_TOKEN`
|
|
153
|
-
|
|
154
|
-
4. Validate the setup:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
tellymcp doctor --env .env
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
5. Run the node:
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
tellymcp run --env .env
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
6. Add MCP to your agent:
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
tellymcp mcp --help
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Typical local MCP endpoint in `client` mode:
|
|
173
|
-
|
|
174
|
-
- `http://127.0.0.1:8787/mcp`
|
|
175
|
-
|
|
176
|
-
If you plan to use `browser_*` tools, install Chromium once:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
tellymcp browser install
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Detailed step-by-step guide:
|
|
183
|
-
|
|
184
|
-
- [STANDALONE.md](STANDALONE.md)
|
|
185
|
-
- [STANDALONE-ru.md](STANDALONE-ru.md)
|
|
186
|
-
|
|
187
|
-
### Shared gateway or combined `both` node
|
|
188
|
-
|
|
189
|
-
Use this when you want:
|
|
190
|
-
|
|
191
|
-
- cross-machine collaboration
|
|
192
|
-
- cross-bot projects
|
|
193
|
-
- gateway-relayed Live View
|
|
194
|
-
- persistent gateway-side project and delivery state
|
|
195
|
-
|
|
196
|
-
1. Create a gateway or combined config:
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
tellymcp init gateway
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
or
|
|
203
|
-
|
|
204
|
-
```bash
|
|
205
|
-
tellymcp init both
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
2. Edit `.env` and configure:
|
|
209
|
-
|
|
210
|
-
- `DISTRIBUTED_MODE=gateway|both`
|
|
211
|
-
- `PORT`
|
|
212
|
-
- `ROOT_PREFIX=/api`
|
|
213
|
-
- `TELEGRAM_BOT_TOKEN`
|
|
214
|
-
- `REDIS_*`
|
|
215
|
-
- `DB_*`
|
|
216
|
-
- `WEBAPP_PUBLIC_URL`
|
|
217
|
-
- `GATEWAY_PUBLIC_URL`
|
|
218
|
-
- `GATEWAY_WS_URL`
|
|
219
|
-
- optional `RMQ_*`
|
|
220
|
-
|
|
221
|
-
3. Put the node behind nginx or another reverse proxy on the same prefix:
|
|
222
|
-
|
|
223
|
-
- `/api/mcp`
|
|
224
|
-
- `/api/webapp`
|
|
225
|
-
- `/api/gateway`
|
|
226
|
-
- `/api/healthz`
|
|
1
|
+
<div align="center">
|
|
227
2
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
tellymcp doctor --env .env
|
|
232
|
-
```
|
|
3
|
+
# TellyMCP
|
|
233
4
|
|
|
234
|
-
|
|
5
|
+
**Telegram control plane for MCP-connected coding agents**
|
|
235
6
|
|
|
236
|
-
|
|
237
|
-
tellymcp run --env .env
|
|
238
|
-
```
|
|
7
|
+
[English](./README.md) · [Русский](./README-ru.md) · [Standalone](./docs/STANDALONE.md) · [Standalone RU](./docs/STANDALONE-ru.md)
|
|
239
8
|
|
|
240
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/@deadragdoll/tellymcp)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
[](./README.md#current-runtime-model)
|
|
13
|
+
[](./README.md#webhook-mode)
|
|
241
14
|
|
|
242
|
-
|
|
15
|
+
</div>
|
|
243
16
|
|
|
244
|
-
|
|
17
|
+
`@deadragdoll/tellymcp` is a Telegram control plane for MCP-connected coding agents.
|
|
245
18
|
|
|
246
|
-
|
|
19
|
+
The current model is gateway-first:
|
|
247
20
|
|
|
248
|
-
|
|
21
|
+
- one gateway process owns the Telegram bot, web app, project state, and live console registry
|
|
22
|
+
- one or more agent processes connect to that gateway
|
|
23
|
+
- each running agent console is a routable target
|
|
24
|
+
- Telegram users work through the gateway menu instead of pairing individual sessions
|
|
249
25
|
|
|
250
|
-
|
|
251
|
-
- `link to Telegram`
|
|
252
|
-
- `connect this session to Telegram`
|
|
253
|
-
- `register this session in Telegram`
|
|
254
|
-
- `create a Telegram pairing code`
|
|
255
|
-
- `bind this agent to Telegram`
|
|
26
|
+
## What It Does
|
|
256
27
|
|
|
257
|
-
|
|
28
|
+
- exposes MCP tools for human Telegram interaction
|
|
29
|
+
- lets one agent ask another agent to do work and return files or notes
|
|
30
|
+
- stores structured xchange records in `.mcp-xchange`
|
|
31
|
+
- supports browser automation with Playwright
|
|
32
|
+
- serves the Telegram Mini App / Live View from the gateway
|
|
33
|
+
- supports Telegram polling or webhook mode on the gateway
|
|
34
|
+
- ships a bundled Codex workflow plugin for better agent behavior
|
|
258
35
|
|
|
259
|
-
|
|
260
|
-
2. It returns a short code and, when possible, a deep link.
|
|
261
|
-
3. You open Telegram and send `/start <code>` or `/link <code>` to the bot.
|
|
262
|
-
4. After successful pairing, `/menu` opens the session menu.
|
|
36
|
+
## Current Runtime Model
|
|
263
37
|
|
|
264
|
-
|
|
38
|
+
Topology:
|
|
265
39
|
|
|
266
40
|
```text
|
|
267
|
-
|
|
41
|
+
Telegram user
|
|
42
|
+
|
|
|
43
|
+
Telegram bot + WebApp
|
|
44
|
+
|
|
|
45
|
+
Gateway
|
|
46
|
+
|
|
|
47
|
+
+-- Agent console A
|
|
48
|
+
+-- Agent console B
|
|
49
|
+
+-- Agent console C
|
|
268
50
|
```
|
|
269
51
|
|
|
270
|
-
|
|
52
|
+
Important consequences:
|
|
271
53
|
|
|
272
|
-
|
|
54
|
+
- there is no session pairing flow in the normal model
|
|
55
|
+
- `/menu` on the gateway bot shows live consoles directly
|
|
56
|
+
- cross-console work uses canonical `session_id = client_uuid:local_session_id`
|
|
57
|
+
- unsolicited work is handled through structured xchange records, not inbox polling APIs
|
|
273
58
|
|
|
274
|
-
|
|
275
|
-
2. Create a bot with `/newbot`.
|
|
276
|
-
3. Save the bot token.
|
|
277
|
-
4. Set `TELEGRAM_BOT_USERNAME` if you want deep-link pairing hints.
|
|
59
|
+
## Main Surfaces
|
|
278
60
|
|
|
279
|
-
|
|
61
|
+
Human-facing:
|
|
280
62
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
tellymcp mcp --help
|
|
287
|
-
```
|
|
63
|
+
- `telegram_message` records
|
|
64
|
+
- `notify_telegram`
|
|
65
|
+
- `browser_screenshot(send_to_telegram=true)`
|
|
288
66
|
|
|
289
|
-
|
|
67
|
+
Agent-to-agent:
|
|
290
68
|
|
|
291
|
-
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
69
|
+
- `partner_note` records
|
|
70
|
+
- `send_partner_note`
|
|
71
|
+
- `send_partner_file`
|
|
72
|
+
- `list_gateway_sessions`
|
|
294
73
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
`doctor` is mode-aware.
|
|
298
|
-
|
|
299
|
-
`client` checks:
|
|
300
|
-
|
|
301
|
-
- `tmux`
|
|
302
|
-
- `.env`
|
|
303
|
-
- Redis
|
|
304
|
-
- local MCP bind
|
|
305
|
-
- external gateway `healthz` when `GATEWAY_PUBLIC_URL` is configured
|
|
306
|
-
- `GATEWAY_WS_URL`
|
|
307
|
-
- `WEBAPP_PUBLIC_URL`
|
|
308
|
-
|
|
309
|
-
`gateway` / `both` checks:
|
|
310
|
-
|
|
311
|
-
- `tmux`
|
|
312
|
-
- `.env`
|
|
313
|
-
- Redis
|
|
314
|
-
- local `healthz`
|
|
315
|
-
- public `healthz`
|
|
316
|
-
- public `ws`
|
|
317
|
-
- public `webapp`
|
|
318
|
-
- Postgres
|
|
319
|
-
- RabbitMQ when `RMQ_*` is configured
|
|
320
|
-
|
|
321
|
-
## Important configuration
|
|
322
|
-
|
|
323
|
-
Common:
|
|
324
|
-
|
|
325
|
-
- `TELEGRAM_BOT_TOKEN`
|
|
326
|
-
- `TELEGRAM_BOT_USERNAME`
|
|
327
|
-
- `REDIS_HOST`
|
|
328
|
-
- `REDIS_PORT`
|
|
329
|
-
- `REDIS_DB`
|
|
330
|
-
- `MODE=queue|reject`
|
|
331
|
-
- `PAIR_CODE_TTL_SECONDS`
|
|
332
|
-
- `MCP_HTTP_HOST`
|
|
333
|
-
- `MCP_HTTP_PORT`
|
|
334
|
-
- `MCP_HTTP_PATH`
|
|
335
|
-
- `MCP_HTTP_BEARER_TOKEN`
|
|
336
|
-
- `TMUX_SOCKET_PATH`
|
|
337
|
-
- `TMUX_NUDGE_ENABLED`
|
|
338
|
-
- `TMUX_NUDGE_DEBOUNCE_SECONDS`
|
|
339
|
-
- `TMUX_NUDGE_COOLDOWN_SECONDS`
|
|
340
|
-
- `WEBAPP_ENABLED`
|
|
341
|
-
- `WEBAPP_BASE_PATH`
|
|
342
|
-
- `WEBAPP_LAUNCH_MODE=default|expand|fullscreen`
|
|
343
|
-
- `MCP_XCHANGE_DIR`
|
|
344
|
-
- `PROXY_USE=http|socks5`
|
|
345
|
-
- `HTTP_PROXY`
|
|
346
|
-
- `SOCKS5_PROXY`
|
|
347
|
-
|
|
348
|
-
Client-only:
|
|
349
|
-
|
|
350
|
-
- `DISTRIBUTED_MODE=client`
|
|
351
|
-
- `GATEWAY_PUBLIC_URL` optional
|
|
352
|
-
- `GATEWAY_WS_URL` optional
|
|
353
|
-
- `GATEWAY_WS_PATH`
|
|
354
|
-
- `GATEWAY_AUTH_TOKEN` optional
|
|
355
|
-
|
|
356
|
-
Gateway / both:
|
|
357
|
-
|
|
358
|
-
- `DISTRIBUTED_MODE=gateway|both`
|
|
359
|
-
- `PORT`
|
|
360
|
-
- `ROOT_PREFIX=/api`
|
|
361
|
-
- `DB_HOST`
|
|
362
|
-
- `DB_PORT`
|
|
363
|
-
- `DB_USER`
|
|
364
|
-
- `DB_PASSWORD`
|
|
365
|
-
- `DB_NAME`
|
|
366
|
-
- optional `RMQ_HOST`
|
|
367
|
-
- optional `RMQ_PORT`
|
|
368
|
-
- optional `RMQ_USER`
|
|
369
|
-
- optional `RMQ_PASSWORD`
|
|
370
|
-
- optional `RMQ_VHOST`
|
|
371
|
-
- optional `RMQ_EXCHANGE`
|
|
372
|
-
|
|
373
|
-
For ready-to-edit templates, use:
|
|
374
|
-
|
|
375
|
-
- `.env.example.client`
|
|
376
|
-
- `.env.example.gateway`
|
|
377
|
-
- `tellymcp init client|gateway|both`
|
|
378
|
-
|
|
379
|
-
## What it does
|
|
380
|
-
|
|
381
|
-
Flow:
|
|
382
|
-
|
|
383
|
-
1. The MCP client creates or updates a session context.
|
|
384
|
-
2. The MCP client creates a short one-time 3-digit session pairing code.
|
|
385
|
-
It should also pass the agent `cwd` when available.
|
|
386
|
-
3. The human user links that session in Telegram with `/start <code>` or `/link <code>`.
|
|
387
|
-
4. After pairing, Telegram shows an inline menu for session switching, inbox, content export, live tmux view, and maintenance actions. `/menu` opens the root switcher.
|
|
388
|
-
5. The MCP client calls `ask_user_telegram` with the linked `session_id`.
|
|
389
|
-
6. The server sends a redacted Telegram message and waits for the answer.
|
|
390
|
-
7. The answer is returned as structured MCP tool output.
|
|
391
|
-
8. Unsolicited Telegram messages are stored in a per-session inbox for later agent processing.
|
|
392
|
-
9. If the Telegram message contains a photo or document, the file is written into the session `.mcp-xchange/` and delivered according to the currently open session or collaboration target.
|
|
393
|
-
|
|
394
|
-
## Architecture
|
|
395
|
-
|
|
396
|
-
- TypeScript, strict mode
|
|
397
|
-
- official MCP SDK over Streamable HTTP
|
|
398
|
-
- `grammy` for Telegram transport
|
|
399
|
-
- pluggable `HumanTransport` interface
|
|
400
|
-
- `ioredis` for Redis access
|
|
401
|
-
- `@grammyjs/storage-redis` for Redis-backed session storage
|
|
402
|
-
- FSD-inspired backend structure
|
|
403
|
-
|
|
404
|
-
Telegram is implemented as the first transport backend. Tool orchestration does not depend on Telegram-specific APIs directly.
|
|
405
|
-
|
|
406
|
-
For maintainers and future extension work, see [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md).
|
|
407
|
-
|
|
408
|
-
Canonical instructions:
|
|
409
|
-
|
|
410
|
-
- gateway `TOOLS.md` is the canonical instruction source
|
|
411
|
-
- `TOOLS.md` now carries a human-readable version marker near the top of the file
|
|
412
|
-
- gateway/client sync still relies on content hash, not on the version string
|
|
413
|
-
- gateway/client runtime compatibility is checked separately in `ws hello/hello_ack`
|
|
414
|
-
- protocol major mismatch blocks gateway transport until the older side is upgraded
|
|
415
|
-
- when behavior changes materially, bump both:
|
|
416
|
-
- the `TOOLS.md` version marker
|
|
417
|
-
- the file content itself
|
|
418
|
-
|
|
419
|
-
Logs use one runtime model:
|
|
420
|
-
|
|
421
|
-
- `pino-pretty` console output to `stderr`
|
|
422
|
-
- optional JSONL file sink via `LOG_FILE_ENABLED=true` and `LOG_FILE_PATH=...`
|
|
423
|
-
- optional in-app `LogFeed` buffer for Telegram/UI diagnostics when `ENABLE_LOGFEED=1`
|
|
424
|
-
|
|
425
|
-
If Telegram access requires a proxy, the bot transport can use:
|
|
426
|
-
|
|
427
|
-
- HTTP proxy through `HTTP_PROXY`
|
|
428
|
-
- SOCKS5 proxy through `SOCKS5_PROXY`
|
|
429
|
-
|
|
430
|
-
The chosen proxy mode is controlled by `PROXY_USE`.
|
|
431
|
-
|
|
432
|
-
Debug/admin HTTP routes are disabled by default:
|
|
433
|
-
|
|
434
|
-
- `/sessions` requires `MCP_HTTP_ENABLE_DEBUG_ROUTES=true`
|
|
435
|
-
- `/prune` requires `MCP_HTTP_ENABLE_PRUNE_ROUTE=true`
|
|
436
|
-
|
|
437
|
-
If exposed outside localhost, also set `MCP_HTTP_BEARER_TOKEN`.
|
|
438
|
-
|
|
439
|
-
## Distributed modes
|
|
440
|
-
|
|
441
|
-
The service now has a role-oriented distributed scaffold:
|
|
442
|
-
|
|
443
|
-
- `DISTRIBUTED_MODE=client`
|
|
444
|
-
- current default
|
|
445
|
-
- full local Telegram/MCP/tmux/browser flow
|
|
446
|
-
- local `🏠 Local` flow works directly
|
|
447
|
-
- remote `👥 Collab` flow goes through gateway when `GATEWAY_PUBLIC_URL` is configured
|
|
448
|
-
- `DISTRIBUTED_MODE=gateway`
|
|
449
|
-
- enables `/gateway/*` HTTP surface
|
|
450
|
-
- serves as the shared relay/control plane
|
|
451
|
-
- `DISTRIBUTED_MODE=both`
|
|
452
|
-
- exposes both local service behavior and gateway HTTP surface in one process
|
|
453
|
-
|
|
454
|
-
Current implementation status:
|
|
455
|
-
|
|
456
|
-
- `GET /gateway/healthz` works
|
|
457
|
-
- `POST /gateway/client/register` works
|
|
458
|
-
- `POST /gateway/projects/create` works
|
|
459
|
-
- `POST /gateway/projects/join` works
|
|
460
|
-
- `POST /gateway/sessions/register` works
|
|
461
|
-
- `POST /gateway/partner-note` works
|
|
462
|
-
- `ws` control-plane is active
|
|
463
|
-
- optional `RabbitMQ` exchange can be enabled for durable gateway-side event fanout
|
|
464
|
-
- if `GATEWAY_PUBLIC_URL` is configured, partner-note delivery goes through the gateway HTTP surface
|
|
465
|
-
- in `DISTRIBUTED_MODE=both`, this also covers same-bot local delivery transparently
|
|
466
|
-
- remote project messaging and delivery status go through the gateway DB and `ws`
|
|
467
|
-
- gateway-relayed `Live View` goes through `ws` for client nodes without their own public domain
|
|
468
|
-
- `Collab -> Tools -> History` sends a markdown export of the last 5 Collab events
|
|
469
|
-
for the current active session
|
|
470
|
-
- `TOOLS.md` sync is state-based:
|
|
471
|
-
- client sends per-session `tools_hash` in `ws hello`
|
|
472
|
-
- gateway compares against canonical gateway `TOOLS.md`
|
|
473
|
-
- mismatch triggers `tools_event`
|
|
474
|
-
- client also self-checks on `hello_ack`
|
|
475
|
-
- gateway periodically rechecks online sockets for changed gateway `TOOLS.md`
|
|
476
|
-
|
|
477
|
-
Mode-specific runtime requirements:
|
|
478
|
-
|
|
479
|
-
- `client`
|
|
480
|
-
- local Redis
|
|
481
|
-
- `GATEWAY_PUBLIC_URL`
|
|
482
|
-
- no gateway Postgres bootstrap is performed
|
|
483
|
-
- `gateway`
|
|
484
|
-
- Postgres is required for gateway persistence
|
|
485
|
-
- optional `RMQ_*` enables durable gateway-side event dispatch
|
|
486
|
-
- `both`
|
|
487
|
-
- Postgres is required because the gateway role is active
|
|
488
|
-
- optional `RMQ_*` enables durable gateway-side event dispatch
|
|
489
|
-
|
|
490
|
-
Current file model:
|
|
491
|
-
|
|
492
|
-
- exchange files and screenshots live directly in local `.mcp-xchange`
|
|
493
|
-
- remote delivery sends payloads through gateway delivery events
|
|
494
|
-
- `vfs/minio` are no longer part of the active Telegram file exchange path
|
|
495
|
-
- if an agent must send a real local file to a partner, prefer `send_partner_file`
|
|
496
|
-
over plain `send_partner_note`
|
|
497
|
-
- for `Share`, the current session must do the work itself and send only the result
|
|
498
|
-
- `Share` must not forward the original task into the target session as a new assignment
|
|
499
|
-
|
|
500
|
-
Current presence model:
|
|
501
|
-
|
|
502
|
-
- gateway knows whether a client node is online through active `ws`
|
|
503
|
-
- gateway also updates `gateway_clients.last_seen_at`
|
|
504
|
-
- there is no separate heartbeat of the coding agent process inside each session yet
|
|
505
|
-
- because of that, a status screen can honestly show client `online/offline`, but not guaranteed agent `online/offline`
|
|
506
|
-
|
|
507
|
-
## Mini App
|
|
508
|
-
|
|
509
|
-
If `WEBAPP_ENABLED=true`, the session menu exposes `🖥 Live`.
|
|
510
|
-
|
|
511
|
-
The Mini App:
|
|
512
|
-
|
|
513
|
-
- is served by this same Node service under `WEBAPP_BASE_PATH`
|
|
514
|
-
- in `client` mode can also be opened through the shared gateway domain
|
|
515
|
-
- uses vanilla JS and reads the visible tmux pane area through gateway/client relay
|
|
516
|
-
- validates Telegram `initData` server-side using the official hash check
|
|
517
|
-
- can auto-apply launch mode from env:
|
|
518
|
-
- `default`
|
|
519
|
-
- `expand`
|
|
520
|
-
- `fullscreen` with fallback to `expand` when the Telegram client does not support fullscreen
|
|
521
|
-
- requires the Telegram user from `initData` to match the bound session user
|
|
522
|
-
- resolves the active session from the bound Telegram user, so a session id in the URL is not required for normal use
|
|
523
|
-
- deletes the temporary `Open Live View` launcher message after successful Mini App bootstrap
|
|
524
|
-
- auto-recovers after a short gateway restart:
|
|
525
|
-
- short `502/503` periods are tolerated by polling
|
|
526
|
-
- expired in-process WebApp sessions (`401/403`) trigger an automatic re-bootstrap
|
|
527
|
-
- in normal restart cases the user does not need to reopen `Live`
|
|
528
|
-
- allows only a fixed control set:
|
|
529
|
-
- `Esc`
|
|
530
|
-
- `Tab`
|
|
531
|
-
- `/`
|
|
532
|
-
- `Backspace`
|
|
533
|
-
- `Up`
|
|
534
|
-
- `Down`
|
|
535
|
-
- `Enter`
|
|
536
|
-
|
|
537
|
-
`WEBAPP_VISIBLE_SCREENS` controls how much content the live viewport captures relative to the visible tmux height. The default `2` means about two visible screens of content.
|
|
538
|
-
|
|
539
|
-
`WEBAPP_PUBLIC_URL` is only required when the node exposes its own public Mini App URL directly. In `DISTRIBUTED_MODE=client` with `GATEWAY_PUBLIC_URL` configured, `🖥 Live` can be opened through the gateway domain instead.
|
|
540
|
-
|
|
541
|
-
## Browser feedback
|
|
542
|
-
|
|
543
|
-
The service can also launch an internal Playwright runtime and keep one isolated browser context per `session_id`.
|
|
544
|
-
|
|
545
|
-
Current browser model:
|
|
546
|
-
|
|
547
|
-
- one shared browser process
|
|
548
|
-
- one isolated `BrowserContext + Page` per MCP session
|
|
549
|
-
- events are captured per session:
|
|
550
|
-
- console messages
|
|
551
|
-
- page runtime errors
|
|
552
|
-
- failed or HTTP-error network requests
|
|
553
|
-
- screenshots are written into the same `.mcp-xchange` flow as Telegram file exchange
|
|
554
|
-
- exchange files use the same local `.mcp-xchange` handoff model as Telegram uploads
|
|
555
|
-
|
|
556
|
-
Recommended local dev settings:
|
|
557
|
-
|
|
558
|
-
- `BROWSER_ENABLED=true`
|
|
559
|
-
- `BROWSER_HEADLESS=false`
|
|
560
|
-
- `BROWSER_ADDRESS=http://localhost:5173`
|
|
561
|
-
- start your SPA dev server on `0.0.0.0:5173`
|
|
562
|
-
- open it through `browser_open`
|
|
563
|
-
- install browser binaries once with `npx playwright install chromium`
|
|
564
|
-
- install browser binaries once with `tellymcp browser install`
|
|
565
|
-
|
|
566
|
-
Recommended headless server settings:
|
|
567
|
-
|
|
568
|
-
- `BROWSER_HEADLESS=true`
|
|
569
|
-
- target the app through a reachable host or LAN address, for example `http://127.0.0.1:3000` or `http://192.168.x.x:3000`
|
|
570
|
-
|
|
571
|
-
Current browser tools:
|
|
74
|
+
Browser:
|
|
572
75
|
|
|
573
76
|
- `browser_open`
|
|
574
|
-
- `browser_reload`
|
|
575
77
|
- `browser_click`
|
|
576
78
|
- `browser_fill`
|
|
577
79
|
- `browser_press`
|
|
578
80
|
- `browser_wait_for`
|
|
579
|
-
- `browser_wait_for_url`
|
|
580
|
-
- `browser_console`
|
|
581
|
-
- `browser_errors`
|
|
582
|
-
- `browser_network_failures`
|
|
583
|
-
- `browser_clear_logs`
|
|
584
|
-
- `browser_dom`
|
|
585
|
-
- `browser_computed_style`
|
|
586
81
|
- `browser_screenshot`
|
|
587
|
-
- `browser_close`
|
|
588
|
-
|
|
589
|
-
Browser target convention:
|
|
590
|
-
|
|
591
|
-
- browser interaction tools support `ai_tag` in addition to `selector` and `text`
|
|
592
|
-
- frontend code may annotate elements with:
|
|
593
|
-
- `data-drive-tag="save-button"`
|
|
594
|
-
- or `ai-tag="save-button"`
|
|
595
|
-
- recommended convention is `data-drive-tag="..."` with an explicit value
|
|
596
|
-
|
|
597
|
-
If `BROWSER_ADDRESS` is configured, `browser_open` may use either:
|
|
598
|
-
|
|
599
|
-
- a full URL like `http://localhost:5173/settings`
|
|
600
|
-
- or a relative path like `/settings`
|
|
601
|
-
|
|
602
|
-
`browser_screenshot` returns:
|
|
603
|
-
|
|
604
|
-
- `file_path` full path to the written screenshot file
|
|
605
|
-
- `workspace_dir` the resolved workspace root for that session
|
|
606
|
-
- `exchange_dir` the resolved `.mcp-xchange` directory used for the write
|
|
607
|
-
- `telegram_message_id` when `send_to_telegram=true`
|
|
608
|
-
|
|
609
|
-
## Telegram UI
|
|
610
|
-
|
|
611
|
-
The Telegram bot exposes one root entrypoint:
|
|
612
|
-
|
|
613
|
-
- `/menu`
|
|
614
|
-
|
|
615
|
-
Current root menu behavior:
|
|
616
|
-
|
|
617
|
-
- shows the current active session
|
|
618
|
-
- shows the last worked session and update time
|
|
619
|
-
- shows tmux status
|
|
620
|
-
- lists paired sessions as one button per row
|
|
621
|
-
- keeps `Refresh` and `Tools` on the final row
|
|
622
|
-
|
|
623
|
-
Current session menu behavior:
|
|
624
|
-
|
|
625
|
-
- title is `Session: <name>`
|
|
626
|
-
- first row: `Live | Content | Browser`
|
|
627
|
-
- second row: `Local | Collab`
|
|
628
|
-
- third row: `Inbox | Storage | Settings`
|
|
629
|
-
- final row: `Back`
|
|
630
|
-
|
|
631
|
-
`Settings` contains:
|
|
632
|
-
|
|
633
|
-
- `Info`
|
|
634
|
-
- `Rename`
|
|
635
|
-
- `Unpair`
|
|
636
|
-
- `Back`
|
|
637
|
-
|
|
638
|
-
Current browser menu behavior:
|
|
639
|
-
|
|
640
|
-
- `Screenshots`
|
|
641
|
-
- browser screenshots are separated from ordinary uploaded files
|
|
642
|
-
|
|
643
|
-
Current storage behavior:
|
|
644
|
-
|
|
645
|
-
- `Storage` shows `.mcp-xchange` contents for the active session
|
|
646
|
-
- storage entries can be opened and sent back to Telegram as files
|
|
647
|
-
|
|
648
|
-
Current file behavior:
|
|
649
|
-
|
|
650
|
-
- top-level `Files` menu is removed
|
|
651
|
-
- `Browser -> Screenshots` still shows screenshots created by `browser_screenshot`
|
|
652
|
-
- if the user is inside:
|
|
653
|
-
- the current session
|
|
654
|
-
- `🏠 Local -> Напарник`
|
|
655
|
-
- `👥 Collab -> Project -> Member`
|
|
656
|
-
then the next uploaded file is delivered directly into that target
|
|
657
|
-
|
|
658
|
-
Local link behavior:
|
|
659
|
-
|
|
660
|
-
- `Link` opens a list of other sessions visible to the same Telegram identity
|
|
661
|
-
- choosing one creates a mutual partner link between the two sessions
|
|
662
|
-
- once linked, the button becomes `Unlink`
|
|
663
|
-
- this link is intended for backend/frontend or similar agent collaboration
|
|
664
|
-
- linked agents should use `send_partner_note` for structured collaboration
|
|
665
|
-
|
|
666
|
-
Local partner menu behavior:
|
|
667
|
-
|
|
668
|
-
- `Local` opens a linked-session collaboration menu
|
|
669
|
-
- available actions are:
|
|
670
|
-
- `Ask`
|
|
671
|
-
- `Share`
|
|
672
|
-
- `Unlink`
|
|
673
|
-
- the Telegram prompt format is:
|
|
674
|
-
- first line = short summary
|
|
675
|
-
- optional blank line
|
|
676
|
-
- remaining text = full message body
|
|
677
|
-
- partner wake-up semantics:
|
|
678
|
-
- `TMUX_PARTNER_NUDGE_MESSAGE` is for collaboration notes, not for human Telegram inbox
|
|
679
|
-
- the receiving agent should read `.mcp-xchange/SHARED_INDEX.md` and the newest note first
|
|
680
|
-
|
|
681
|
-
Linked-session collaboration contract:
|
|
682
|
-
|
|
683
|
-
- `send_partner_note` writes one note per event into the partner workspace
|
|
684
|
-
- collaborative notes live under `.mcp-xchange/shares/`
|
|
685
|
-
- copied artifacts live under `.mcp-xchange/shares/files/<share_id>/`
|
|
686
|
-
- `.mcp-xchange/SHARED_INDEX.md` acts as the append-only index of partner-facing notes
|
|
687
|
-
- `.mcp-xchange/LOCAL_INDEX.md` acts as the append-only index of local agent-facing handoffs
|
|
688
|
-
- supported note kinds are:
|
|
689
|
-
- `share`
|
|
690
|
-
- `question`
|
|
691
|
-
- `reply`
|
|
692
|
-
- `request`
|
|
693
|
-
- `handoff`
|
|
694
|
-
- useful partner-facing content usually includes:
|
|
695
|
-
- API summaries
|
|
696
|
-
- what changed
|
|
697
|
-
- current errors
|
|
698
|
-
- sample payloads
|
|
699
|
-
- relevant git changes from the agent workspace
|
|
700
|
-
- do not send raw implementation source files as partner artifacts; prefer summaries, specs, payload examples, logs, screenshots, and Markdown notes
|
|
701
|
-
- recommended mapping:
|
|
702
|
-
- `question` for "what APIs do you expose?", "what's new?", "send the error details"
|
|
703
|
-
- `reply` for direct answers, usually with `in_reply_to`
|
|
704
|
-
- `share` for one-way status updates
|
|
705
|
-
- `request` for explicit teammate actions
|
|
706
|
-
- `handoff` for transferring results or artifacts
|
|
707
|
-
- before sending a local partner note, the agent should call `get_session_context` and verify that `linked_session_id` exists
|
|
708
|
-
|
|
709
|
-
Collab project behavior:
|
|
710
|
-
|
|
711
|
-
- `👥 Collab` is the project-based multi-machine and multi-bot collaboration flow
|
|
712
|
-
- target session is chosen from `Projects -> <project> -> <member>`
|
|
713
|
-
- member screen layout is:
|
|
714
|
-
- first row: `Ask | Share`
|
|
715
|
-
- second row: `Live`
|
|
716
|
-
- semantics inside `Project -> Member` depend on the action:
|
|
717
|
-
- `Ask` sends a task to the selected member session
|
|
718
|
-
- expected reply route is `member -> current session`
|
|
719
|
-
- `Share` creates a task for the current session
|
|
720
|
-
- expected send route is `current session -> member`
|
|
721
|
-
- `Live` now uses an approval flow before opening the selected member session
|
|
722
|
-
- after approval, the requester receives a fresh `Open Live View` button through the existing webapp relay path
|
|
723
|
-
- direct file uploads still go to that exact target session when a member screen is open
|
|
724
|
-
- if an old member-menu message becomes stale, clicking it deletes that outdated Telegram message instead of leaving a dead keyboard
|
|
725
|
-
|
|
726
|
-
Recommended share-note structure:
|
|
727
|
-
|
|
728
|
-
```md
|
|
729
|
-
---
|
|
730
|
-
share_id: 2026-05-12T22-10-00Z-frontend-question-api
|
|
731
|
-
kind: question
|
|
732
|
-
from_session_id: frontend-session
|
|
733
|
-
to_session_id: backend-session
|
|
734
|
-
created_at: 2026-05-12T22:10:00Z
|
|
735
|
-
requires_reply: true
|
|
736
|
-
in_reply_to: null
|
|
737
|
-
artifacts: []
|
|
738
|
-
---
|
|
739
|
-
|
|
740
|
-
# Summary
|
|
741
|
-
Need an up-to-date backend API summary.
|
|
742
|
-
|
|
743
|
-
# Message
|
|
744
|
-
- what endpoints exist
|
|
745
|
-
- what auth is required
|
|
746
|
-
- what changed recently
|
|
747
|
-
|
|
748
|
-
# Expected Reply
|
|
749
|
-
Short Markdown summary plus spec or sample payload files when available.
|
|
750
|
-
```
|
|
751
|
-
|
|
752
|
-
Current content menu behavior:
|
|
753
|
-
|
|
754
|
-
- `Visible`
|
|
755
|
-
- `Full`
|
|
756
|
-
- `Last 300`
|
|
757
|
-
- `Last 1000`
|
|
758
|
-
|
|
759
|
-
`Tools` currently contains:
|
|
760
|
-
|
|
761
|
-
- `Broadcast`
|
|
762
|
-
- `Prune all`
|
|
763
|
-
|
|
764
|
-
`Broadcast` uses a one-shot prompt. After a successful broadcast, only that prompt is deleted. Cancel returns to `Tools` without destroying the existing menu message.
|
|
765
|
-
|
|
766
|
-
## Telegram file exchange
|
|
767
|
-
|
|
768
|
-
Ordinary Telegram messages may include:
|
|
769
|
-
|
|
770
|
-
- text only
|
|
771
|
-
- photo with optional caption
|
|
772
|
-
- document with optional caption
|
|
773
|
-
|
|
774
|
-
When a photo or document arrives:
|
|
775
|
-
|
|
776
|
-
- the file is downloaded into `MCP_XCHANGE_DIR`, default `.mcp-xchange`, under the paired agent workspace
|
|
777
|
-
- if the user is already inside a concrete target context, the upload itself is the handoff action
|
|
778
|
-
- otherwise the file is delivered into the currently open session as a local session handoff
|
|
779
|
-
- there is no separate `Files` confirmation screen anymore
|
|
780
|
-
|
|
781
|
-
Runtime note:
|
|
782
|
-
|
|
783
|
-
- the main service writes these files directly in the local workspace
|
|
784
82
|
|
|
785
|
-
|
|
83
|
+
Tools sync:
|
|
786
84
|
|
|
787
|
-
|
|
85
|
+
- `refresh_tools_markdown`
|
|
86
|
+
- `.mcpsession.json` keeps startup identity and the last known tools hashes
|
|
788
87
|
|
|
789
|
-
|
|
88
|
+
## Requirements
|
|
790
89
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
The derived `session_id` is built from that title plus a short stable hash of the project path, so it remains consistent across restarts.
|
|
797
|
-
|
|
798
|
-
This means you can call session-oriented tools without explicitly passing `session_id` when working in a single project context.
|
|
799
|
-
|
|
800
|
-
## Repository development
|
|
801
|
-
|
|
802
|
-
```bash
|
|
803
|
-
yarn install
|
|
804
|
-
```
|
|
805
|
-
|
|
806
|
-
### Build
|
|
807
|
-
|
|
808
|
-
```bash
|
|
809
|
-
yarn build
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
### Run
|
|
90
|
+
- Node.js `>= 24`
|
|
91
|
+
- Redis
|
|
92
|
+
- PostgreSQL for gateway mode
|
|
93
|
+
- optional RabbitMQ for durable gateway fanout
|
|
94
|
+
- Playwright browser binaries if you use browser tools
|
|
813
95
|
|
|
814
|
-
|
|
96
|
+
## Installation
|
|
815
97
|
|
|
816
98
|
```bash
|
|
817
|
-
|
|
99
|
+
npm install -g @deadragdoll/tellymcp
|
|
818
100
|
```
|
|
819
101
|
|
|
820
|
-
|
|
102
|
+
Optional browser runtime:
|
|
821
103
|
|
|
822
104
|
```bash
|
|
823
|
-
|
|
824
|
-
yarn start:gw
|
|
105
|
+
tellymcp browser install
|
|
825
106
|
```
|
|
826
107
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
In repository dev mode, the HTTP service exposes:
|
|
830
|
-
|
|
831
|
-
- MCP endpoint at `http://127.0.0.1:8787/mcp` by default
|
|
832
|
-
- health check at `http://127.0.0.1:8787/healthz`
|
|
833
|
-
|
|
834
|
-
If `MCP_HTTP_BEARER_TOKEN` is configured:
|
|
835
|
-
|
|
836
|
-
- `/mcp` requires `Authorization: Bearer ...`
|
|
837
|
-
- `/sessions` and `/prune` also require the same bearer when enabled
|
|
838
|
-
- Telegram Mini App does not use this bearer directly; it has its own `initData` bootstrap and a short-lived WebApp session token
|
|
839
|
-
|
|
840
|
-
`yarn dev:gw:telegram` is still available, but it only starts the `telegram_mcp` feature node.
|
|
841
|
-
It does not expose HTTP by itself anymore. `/mcp`, `/webapp`, and `/healthz` are now served only through the Moleculer API gateway aliases in the full `dev:gw` / `start:gw` runtime, or through a separate gateway node in the same namespace.
|
|
842
|
-
|
|
843
|
-
## Optional Docker infrastructure
|
|
844
|
-
|
|
845
|
-
Docker is no longer the default way to run TellyMCP, but there is one supported container path:
|
|
846
|
-
|
|
847
|
-
- `gateway`-only container deployment
|
|
848
|
-
|
|
849
|
-
This is intended for a pure control-plane node:
|
|
850
|
-
|
|
851
|
-
- no local agent sessions
|
|
852
|
-
- no local `tmux`
|
|
853
|
-
- no `client` mode
|
|
854
|
-
- no `both` mode
|
|
855
|
-
|
|
856
|
-
The repository also keeps Docker for local infrastructure:
|
|
857
|
-
|
|
858
|
-
- `redis` for all modes
|
|
859
|
-
- `postgres` for `gateway` / `both`
|
|
860
|
-
- `rabbitmq` only if you want durable fanout on the gateway
|
|
861
|
-
|
|
862
|
-
Start Redis only, for `standalone` or `client` mode:
|
|
108
|
+
Optional Codex workflow plugin:
|
|
863
109
|
|
|
864
110
|
```bash
|
|
865
|
-
|
|
111
|
+
tellymcp codex-plugin install
|
|
866
112
|
```
|
|
867
113
|
|
|
868
|
-
|
|
114
|
+
## Quick Start
|
|
869
115
|
|
|
870
|
-
|
|
871
|
-
docker compose --profile gateway up -d
|
|
872
|
-
```
|
|
116
|
+
### 1. Gateway
|
|
873
117
|
|
|
874
|
-
|
|
118
|
+
Create a gateway workspace and env:
|
|
875
119
|
|
|
876
120
|
```bash
|
|
877
|
-
|
|
121
|
+
mkdir -p ~/telly-gateway
|
|
122
|
+
cd ~/telly-gateway
|
|
123
|
+
tellymcp init gateway
|
|
878
124
|
```
|
|
879
125
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
1. Copy the example:
|
|
126
|
+
Or copy the sample from this package:
|
|
883
127
|
|
|
884
|
-
|
|
885
|
-
cp .env.example.gateway .env-gateway
|
|
886
|
-
```
|
|
128
|
+
- [.env.example.gateway](./.env.example.gateway)
|
|
887
129
|
|
|
888
|
-
|
|
130
|
+
Required gateway values:
|
|
889
131
|
|
|
890
132
|
- `TELEGRAM_BOT_TOKEN`
|
|
891
|
-
- `
|
|
892
|
-
- `
|
|
133
|
+
- `REDIS_HOST`
|
|
134
|
+
- `DB_HOST`
|
|
135
|
+
- `DB_USER`
|
|
136
|
+
- `DB_PASSWORD`
|
|
137
|
+
- `DB_NAME`
|
|
893
138
|
- `GATEWAY_PUBLIC_URL`
|
|
894
139
|
- `GATEWAY_WS_URL`
|
|
895
|
-
- `
|
|
896
|
-
|
|
897
|
-
3. Start the stack:
|
|
898
|
-
|
|
899
|
-
```bash
|
|
900
|
-
docker compose up -d
|
|
901
|
-
```
|
|
902
|
-
|
|
903
|
-
This starts:
|
|
904
|
-
|
|
905
|
-
- `redis`
|
|
906
|
-
- `postgres`
|
|
907
|
-
- `tellymcp-gateway`
|
|
908
|
-
|
|
909
|
-
Inside Docker, compose overrides:
|
|
140
|
+
- `GATEWAY_TOKEN`
|
|
910
141
|
|
|
911
|
-
|
|
912
|
-
- `REDIS_HOST=redis`
|
|
913
|
-
- `DB_HOST=postgres`
|
|
914
|
-
|
|
915
|
-
Public endpoint expectations stay the same:
|
|
916
|
-
|
|
917
|
-
- `http://127.0.0.1:8080/api/healthz`
|
|
918
|
-
- `http://127.0.0.1:8080/api/mcp`
|
|
919
|
-
- `http://127.0.0.1:8080/api/webapp`
|
|
920
|
-
- `http://127.0.0.1:8080/api/gateway`
|
|
921
|
-
|
|
922
|
-
Stop everything:
|
|
923
|
-
|
|
924
|
-
```bash
|
|
925
|
-
docker compose down
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
Default published ports:
|
|
929
|
-
|
|
930
|
-
- Redis: `6379`
|
|
931
|
-
- Postgres: `5432`
|
|
932
|
-
- RabbitMQ AMQP: `5672`
|
|
933
|
-
- RabbitMQ UI: `15672`
|
|
934
|
-
|
|
935
|
-
The TellyMCP process itself should run directly on the host:
|
|
142
|
+
Then run:
|
|
936
143
|
|
|
937
144
|
```bash
|
|
938
145
|
tellymcp run --env .env
|
|
939
146
|
```
|
|
940
147
|
|
|
941
|
-
|
|
148
|
+
### 2. Agent
|
|
942
149
|
|
|
943
|
-
|
|
944
|
-
- simpler debugging
|
|
945
|
-
- the same runtime model for `standalone`, `client`, `gateway`, and `both`
|
|
946
|
-
|
|
947
|
-
For `client` and `both`, host execution is still the recommended model.
|
|
948
|
-
|
|
949
|
-
Optional if the local tmux server uses a non-default socket:
|
|
150
|
+
Create one workspace per agent console:
|
|
950
151
|
|
|
951
152
|
```bash
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
## MCP usage
|
|
956
|
-
|
|
957
|
-
### 1. Save session context
|
|
958
|
-
|
|
959
|
-
Call `set_session_context`:
|
|
960
|
-
|
|
961
|
-
```json
|
|
962
|
-
{
|
|
963
|
-
"session_id": "backend-refactor",
|
|
964
|
-
"session_label": "Backend refactor",
|
|
965
|
-
"task": "Admin API cleanup",
|
|
966
|
-
"summary": "We are simplifying admin API response shapes and need product confirmations on compatibility-sensitive changes.",
|
|
967
|
-
"files": [
|
|
968
|
-
"backend/src/routes/admin.ts",
|
|
969
|
-
"backend/src/services/adminService.ts"
|
|
970
|
-
],
|
|
971
|
-
"decisions": ["Keep Telegram as the human clarification channel"],
|
|
972
|
-
"risks": ["Breaking existing clients"]
|
|
973
|
-
}
|
|
153
|
+
mkdir -p ~/agent-a
|
|
154
|
+
cd ~/agent-a
|
|
155
|
+
tellymcp init client
|
|
974
156
|
```
|
|
975
157
|
|
|
976
|
-
|
|
158
|
+
Or copy:
|
|
977
159
|
|
|
978
|
-
|
|
160
|
+
- [.env.example.client](./.env.example.client)
|
|
979
161
|
|
|
980
|
-
|
|
981
|
-
{
|
|
982
|
-
"session_id": "backend-refactor"
|
|
983
|
-
}
|
|
984
|
-
```
|
|
162
|
+
Required client values:
|
|
985
163
|
|
|
986
|
-
|
|
164
|
+
- `GATEWAY_PUBLIC_URL`
|
|
165
|
+
- `GATEWAY_WS_URL`
|
|
166
|
+
- `GATEWAY_TOKEN`
|
|
167
|
+
- `GATEWAY_USER_UUID` if this console should be scoped to a specific Telegram owner
|
|
987
168
|
|
|
988
|
-
|
|
989
|
-
- whether the session is currently paired
|
|
990
|
-
- stored tmux targeting data if configured
|
|
991
|
-
- Telegram binding metadata if pairing exists
|
|
992
|
-
- a `status_message` describing whether pairing and tmux delivery are active
|
|
169
|
+
Recommended:
|
|
993
170
|
|
|
994
|
-
|
|
171
|
+
- built-in PTY terminal runtime is used by default
|
|
172
|
+
- explicit `TELLYMCP_SESSION_ID` and `TELLYMCP_SESSION_LABEL` for the first run
|
|
995
173
|
|
|
996
|
-
|
|
174
|
+
First run:
|
|
997
175
|
|
|
998
176
|
```bash
|
|
999
|
-
|
|
177
|
+
tellymcp run --env .env -s NEW
|
|
1000
178
|
```
|
|
1001
179
|
|
|
1002
|
-
|
|
180
|
+
After that, `.mcpsession.json` stores:
|
|
1003
181
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
"tmux_window_name": "test",
|
|
1008
|
-
"tmux_window_index": 1,
|
|
1009
|
-
"tmux_pane_id": "%7",
|
|
1010
|
-
"tmux_pane_index": 0
|
|
1011
|
-
}
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
Important:
|
|
182
|
+
- `local_session_id`
|
|
183
|
+
- `session_label`
|
|
184
|
+
- `env_file`
|
|
1015
185
|
|
|
1016
|
-
|
|
1017
|
-
- but `tmux_target` stays empty
|
|
1018
|
-
- in that state tmux nudges and Mini App controls will not work until `set_tmux_target` is called later
|
|
1019
|
-
|
|
1020
|
-
You can still call `set_tmux_target` later if you need to update or override the stored target:
|
|
1021
|
-
|
|
1022
|
-
```json
|
|
1023
|
-
{
|
|
1024
|
-
"session_id": "backend-refactor",
|
|
1025
|
-
"tmux_session_name": "work",
|
|
1026
|
-
"tmux_window_name": "test",
|
|
1027
|
-
"tmux_window_index": 1,
|
|
1028
|
-
"tmux_pane_id": "%7",
|
|
1029
|
-
"tmux_pane_index": 0,
|
|
1030
|
-
"tmux_target": "%7"
|
|
1031
|
-
}
|
|
1032
|
-
```
|
|
1033
|
-
|
|
1034
|
-
After that, when the paired session receives an unsolicited inbox message, the service can run:
|
|
186
|
+
So later the same workspace can usually start with:
|
|
1035
187
|
|
|
1036
188
|
```bash
|
|
1037
|
-
|
|
189
|
+
tellymcp run
|
|
1038
190
|
```
|
|
1039
191
|
|
|
1040
|
-
|
|
1041
|
-
If several Telegram messages arrive close together, the nudge is debounced by `TMUX_NUDGE_DEBOUNCE_SECONDS` so the agent gets one wake-up for the batch instead of one wake-up per message.
|
|
1042
|
-
Ordinary Telegram messages are always stored in the inbox of the currently active session for that Telegram identity.
|
|
1043
|
-
|
|
1044
|
-
### 3. Pair a session
|
|
1045
|
-
|
|
1046
|
-
If the user asks to register or link the current agent in Telegram, the agent should first collect:
|
|
192
|
+
## Webhook Mode
|
|
1047
193
|
|
|
1048
|
-
|
|
1049
|
-
- tmux attributes when running inside tmux
|
|
1050
|
-
|
|
1051
|
-
Only after that should it call `create_session_pair_code`.
|
|
1052
|
-
|
|
1053
|
-
Call `create_session_pair_code` with a stable session id:
|
|
1054
|
-
|
|
1055
|
-
```json
|
|
1056
|
-
{
|
|
1057
|
-
"session_id": "backend-refactor",
|
|
1058
|
-
"session_label": "Backend refactor"
|
|
1059
|
-
}
|
|
1060
|
-
```
|
|
194
|
+
Gateway supports Telegram webhook mode.
|
|
1061
195
|
|
|
1062
|
-
|
|
196
|
+
Typical nginx setup can proxy everything under `/api/` to the standalone gateway listener. The webhook route is just another backend route:
|
|
1063
197
|
|
|
1064
|
-
|
|
198
|
+
- `/api/telegram/webhook`
|
|
1065
199
|
|
|
1066
|
-
|
|
200
|
+
Relevant env:
|
|
1067
201
|
|
|
1068
|
-
```
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
"tmux_pane_id": "%7",
|
|
1074
|
-
"tmux_pane_index": 0
|
|
1075
|
-
}
|
|
202
|
+
```env
|
|
203
|
+
TELEGRAM_WEBHOOK_ENABLED=true
|
|
204
|
+
TELEGRAM_WEBHOOK_PATH=/telegram/webhook
|
|
205
|
+
TELEGRAM_WEBHOOK_PUBLIC_URL=https://your-domain.example/api/telegram/webhook
|
|
206
|
+
TELEGRAM_WEBHOOK_SECRET=change_me_webhook_secret
|
|
1076
207
|
```
|
|
1077
208
|
|
|
1078
|
-
|
|
209
|
+
When webhook mode is enabled:
|
|
1079
210
|
|
|
1080
|
-
|
|
211
|
+
- the gateway registers Telegram webhook on startup
|
|
212
|
+
- polling is not started
|
|
213
|
+
- the secret is checked via `x-telegram-bot-api-secret-token`
|
|
1081
214
|
|
|
1082
|
-
|
|
215
|
+
## MCP Usage
|
|
1083
216
|
|
|
1084
|
-
|
|
1085
|
-
/start ABCD-EFGH
|
|
1086
|
-
```
|
|
217
|
+
### Local HTTP
|
|
1087
218
|
|
|
1088
|
-
|
|
219
|
+
In client mode the local MCP endpoint is usually:
|
|
1089
220
|
|
|
1090
221
|
```text
|
|
1091
|
-
/
|
|
222
|
+
http://127.0.0.1:8787/mcp
|
|
1092
223
|
```
|
|
1093
224
|
|
|
1094
|
-
|
|
225
|
+
Helper:
|
|
1095
226
|
|
|
1096
|
-
```
|
|
1097
|
-
/
|
|
227
|
+
```bash
|
|
228
|
+
tellymcp mcp --url http://127.0.0.1:8787/mcp
|
|
1098
229
|
```
|
|
1099
230
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
Call `ask_user_telegram`:
|
|
1103
|
-
|
|
1104
|
-
```json
|
|
1105
|
-
{
|
|
1106
|
-
"session_id": "backend-refactor",
|
|
1107
|
-
"question": "Can I change the response shape for the admin API?",
|
|
1108
|
-
"task": "Admin API cleanup",
|
|
1109
|
-
"context": "The old shape is inconsistent and adds special cases in the client.",
|
|
1110
|
-
"options": [
|
|
1111
|
-
"Keep current response shape",
|
|
1112
|
-
"Change response shape and update all callers"
|
|
1113
|
-
],
|
|
1114
|
-
"recommended_option": "Keep current response shape",
|
|
1115
|
-
"fallback_if_timeout": "Keep current response shape"
|
|
1116
|
-
}
|
|
1117
|
-
```
|
|
231
|
+
Use the MCP HTTP endpoint exposed by `tellymcp run` for Codex and similar agents.
|
|
1118
232
|
|
|
1119
|
-
|
|
233
|
+
## Codex Plugin
|
|
1120
234
|
|
|
1121
|
-
|
|
1122
|
-
{
|
|
1123
|
-
"use_saved_context": true
|
|
1124
|
-
}
|
|
1125
|
-
```
|
|
235
|
+
The package bundles a local Codex plugin with workflow skills for:
|
|
1126
236
|
|
|
1127
|
-
|
|
237
|
+
- human Telegram replies
|
|
238
|
+
- partner notes
|
|
239
|
+
- browser screenshot tasks
|
|
240
|
+
- artifact-return flows
|
|
1128
241
|
|
|
1129
|
-
|
|
242
|
+
Commands:
|
|
1130
243
|
|
|
1131
|
-
```
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
}
|
|
244
|
+
```bash
|
|
245
|
+
tellymcp codex-plugin status
|
|
246
|
+
tellymcp codex-plugin install
|
|
1135
247
|
```
|
|
1136
248
|
|
|
1137
|
-
|
|
249
|
+
The installer:
|
|
1138
250
|
|
|
1139
|
-
|
|
251
|
+
- copies the bundled plugin into a managed local Codex path
|
|
252
|
+
- updates the personal marketplace manifest
|
|
253
|
+
- installs or updates the plugin if the Codex CLI is available
|
|
1140
254
|
|
|
1141
|
-
|
|
255
|
+
## Browser Workflows
|
|
1142
256
|
|
|
1143
|
-
|
|
1144
|
-
{
|
|
1145
|
-
"session_id": "backend-refactor"
|
|
1146
|
-
}
|
|
1147
|
-
```
|
|
257
|
+
Browser tools use Playwright Chromium.
|
|
1148
258
|
|
|
1149
|
-
|
|
259
|
+
Preferred path:
|
|
1150
260
|
|
|
1151
|
-
|
|
261
|
+
1. `browser_open`
|
|
262
|
+
2. `browser_screenshot`
|
|
263
|
+
3. either:
|
|
264
|
+
- `send_to_telegram=true` for direct human reply
|
|
265
|
+
- `send_partner_file` for cross-console artifact return
|
|
1152
266
|
|
|
1153
|
-
|
|
267
|
+
If browser binaries are missing:
|
|
1154
268
|
|
|
1155
|
-
```
|
|
1156
|
-
|
|
1157
|
-
"session_id": "backend-refactor",
|
|
1158
|
-
"message": "Build finished successfully. Ready for review.",
|
|
1159
|
-
"task": "Admin API cleanup",
|
|
1160
|
-
"risk_level": "low",
|
|
1161
|
-
"use_saved_context": true
|
|
1162
|
-
}
|
|
269
|
+
```bash
|
|
270
|
+
tellymcp browser install
|
|
1163
271
|
```
|
|
1164
272
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
### 9. Poll unsolicited Telegram inbox messages
|
|
1168
|
-
|
|
1169
|
-
If the user writes to the bot without replying to an active question, the message is stored in the session inbox.
|
|
273
|
+
Do not replace browser workflows with ad hoc shell Playwright commands unless you are debugging the runtime itself.
|
|
1170
274
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
- Telegram message arrives
|
|
1174
|
-
- service stores it in inbox
|
|
1175
|
-
- service nudges tmux
|
|
1176
|
-
- agent wakes up and calls `get_telegram_inbox`
|
|
1177
|
-
|
|
1178
|
-
If there is no tmux nudge path, use passive mode. First call `get_telegram_inbox_count`:
|
|
1179
|
-
|
|
1180
|
-
```json
|
|
1181
|
-
{
|
|
1182
|
-
"session_id": "backend-refactor"
|
|
1183
|
-
}
|
|
1184
|
-
```
|
|
275
|
+
## Terminal Blockers
|
|
1185
276
|
|
|
1186
|
-
|
|
277
|
+
Gateway prompt scanning is now live-client driven:
|
|
1187
278
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
}
|
|
1192
|
-
```
|
|
279
|
+
- the scanner is armed on gateway startup but starts working only after a live client connects
|
|
280
|
+
- relay console materialization happens from gateway hello/owner-route hydration, not from `/menu`
|
|
281
|
+
- prompt detection works on the tail of the captured terminal buffer
|
|
1193
282
|
|
|
1194
|
-
|
|
283
|
+
Primary blocker heuristic:
|
|
1195
284
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
"message_id": "inbox_20260504120000_ab12cd"
|
|
1200
|
-
}
|
|
1201
|
-
```
|
|
285
|
+
- contiguous numbered choices like `1.`, `2.`, `3.`
|
|
286
|
+
- nearby action hints such as `press`, `input`, `choose`, `enter`, `esc`, `yes`, `no`
|
|
287
|
+
- optional context lines above the menu block are included in the Telegram notice
|
|
1202
288
|
|
|
1203
|
-
|
|
289
|
+
When a blocker is detected, the gateway can send inline Telegram buttons for:
|
|
1204
290
|
|
|
1205
|
-
|
|
291
|
+
- `1..N`
|
|
292
|
+
- `Enter`
|
|
293
|
+
- `Esc`
|
|
1206
294
|
|
|
1207
|
-
|
|
1208
|
-
- tapping an inbox item opens its full contents
|
|
1209
|
-
- the detail card has a `Delete` action
|
|
1210
|
-
- `Session: ...` shows the currently active linked session
|
|
1211
|
-
- `Refresh` re-renders the current menu state
|
|
295
|
+
Those buttons send exactly the digit or terminal action to the target console. No marker navigation is used.
|
|
1212
296
|
|
|
1213
|
-
|
|
297
|
+
Operational notes:
|
|
1214
298
|
|
|
1215
|
-
|
|
299
|
+
- repeated scans of the same blocker fingerprint do not resend the notice
|
|
300
|
+
- relay capture misses for offline agents are treated as debug-only noise
|
|
301
|
+
- `Storage` and `Screenshots` on the gateway are relay-aware and read console metadata through gateway routes instead of the gateway filesystem
|
|
1216
302
|
|
|
1217
|
-
|
|
303
|
+
## Collaboration Model
|
|
1218
304
|
|
|
1219
|
-
|
|
305
|
+
Projects:
|
|
1220
306
|
|
|
1221
|
-
|
|
307
|
+
- live console presence comes from gateway live registry
|
|
308
|
+
- project membership is tracked separately from live presence
|
|
309
|
+
- one console can participate in a project
|
|
310
|
+
- one client can have several live consoles at the same time
|
|
1222
311
|
|
|
1223
|
-
|
|
1224
|
-
- queued requests are not sent to Telegram until they become active
|
|
312
|
+
Expected agent behavior:
|
|
1225
313
|
|
|
1226
|
-
|
|
314
|
+
- resolve targets through `list_gateway_sessions`
|
|
315
|
+
- read incoming work through `list_xchange_records` and `get_xchange_record`
|
|
316
|
+
- return real files with `send_partner_file`
|
|
317
|
+
- call `mark_xchange_record_read` only after the required reply was successfully sent
|
|
1227
318
|
|
|
1228
|
-
|
|
319
|
+
## Environment Files
|
|
1229
320
|
|
|
1230
|
-
|
|
321
|
+
Use the shipped samples as the canonical starting point:
|
|
1231
322
|
|
|
1232
|
-
|
|
323
|
+
- [.env.example.gateway](./.env.example.gateway)
|
|
324
|
+
- [.env.example.client](./.env.example.client)
|
|
1233
325
|
|
|
1234
|
-
|
|
1235
|
-
yarn dev:client
|
|
1236
|
-
```
|
|
326
|
+
Bundled init templates:
|
|
1237
327
|
|
|
1238
|
-
|
|
328
|
+
- [config/templates/env.gateway.template](./config/templates/env.gateway.template)
|
|
329
|
+
- [config/templates/env.client.template](./config/templates/env.client.template)
|
|
330
|
+
- [config/templates/env.both.template](./config/templates/env.both.template)
|
|
1239
331
|
|
|
1240
|
-
|
|
1241
|
-
codex mcp add telegramHuman --url http://127.0.0.1:8787/mcp
|
|
1242
|
-
```
|
|
332
|
+
The samples were cleaned to match the current runtime:
|
|
1243
333
|
|
|
1244
|
-
|
|
334
|
+
- removed old inbox-only settings
|
|
335
|
+
- removed obsolete pairing-oriented wording
|
|
336
|
+
- removed unused secrets like `SESSION_SECRET`
|
|
337
|
+
- removed unused `APP_NAME`
|
|
1245
338
|
|
|
1246
|
-
|
|
1247
|
-
yarn dev:builder
|
|
1248
|
-
```
|
|
339
|
+
## Operational Commands
|
|
1249
340
|
|
|
1250
|
-
|
|
341
|
+
Health check:
|
|
1251
342
|
|
|
1252
343
|
```bash
|
|
1253
|
-
|
|
344
|
+
tellymcp doctor --env .env
|
|
1254
345
|
```
|
|
1255
346
|
|
|
1256
|
-
|
|
347
|
+
Destructive local+gateway cleanup:
|
|
1257
348
|
|
|
1258
349
|
```bash
|
|
1259
|
-
|
|
1260
|
-
codex mcp add telegramHuman \
|
|
1261
|
-
--url http://127.0.0.1:8080/api/mcp \
|
|
1262
|
-
--bearer-token-env-var TELEGRAM_MCP_BEARER_TOKEN
|
|
1263
|
-
```
|
|
1264
|
-
|
|
1265
|
-
Why these URLs differ:
|
|
1266
|
-
|
|
1267
|
-
- `dev:client` serves MCP directly from the local standalone listener, by default at `http://127.0.0.1:8787/mcp`
|
|
1268
|
-
- `dev:builder` / `both` mode serves MCP through the shared backend ingress, by default at `http://127.0.0.1:8080/api/mcp`
|
|
1269
|
-
|
|
1270
|
-
For externally exposed deployments:
|
|
1271
|
-
|
|
1272
|
-
- prefer enabling `MCP_HTTP_BEARER_TOKEN`
|
|
1273
|
-
- keep `/sessions` and `/prune` disabled unless you actively need them
|
|
1274
|
-
- leave WebApp access to Telegram `initData` validation plus its short-lived session token flow
|
|
1275
|
-
|
|
1276
|
-
This project no longer uses stdio mode. MCP access is exposed only through the HTTP endpoint.
|
|
1277
|
-
|
|
1278
|
-
Current Moleculer feature services:
|
|
1279
|
-
|
|
1280
|
-
- `telegramMcp.runtime`
|
|
1281
|
-
- `telegramMcp.pair`
|
|
1282
|
-
- `telegramMcp.sessionContext`
|
|
1283
|
-
- `telegramMcp.notify`
|
|
1284
|
-
- `telegramMcp.inbox`
|
|
1285
|
-
- `telegramMcp.approval`
|
|
1286
|
-
- `telegramMcp.browser`
|
|
1287
|
-
- `telegramMcp.collaboration`
|
|
1288
|
-
- `telegramMcp.mcpServer`
|
|
1289
|
-
- `telegramMcp.http`
|
|
1290
|
-
|
|
1291
|
-
## Example AGENTS.md snippet
|
|
1292
|
-
|
|
1293
|
-
```md
|
|
1294
|
-
## Telegram clarification
|
|
1295
|
-
|
|
1296
|
-
If you need clarification from the user and the answer is required to continue safely,
|
|
1297
|
-
use the MCP tools `create_session_pair_code` and `ask_user_telegram`.
|
|
1298
|
-
|
|
1299
|
-
Rules:
|
|
1300
|
-
|
|
1301
|
-
- prefer explicit `session_id` when multiple projects or sessions share one Telegram bot; otherwise the derived default session is acceptable
|
|
1302
|
-
- save or refresh session context before risky question flows when it helps reuse context
|
|
1303
|
-
- if the agent runs inside tmux, capture `#{session_name} #{window_name} #{window_index} #{pane_id} #{pane_index}` and pass them to `create_session_pair_code`; use `set_tmux_target` later only if you need to refresh or override the target
|
|
1304
|
-
- if the session is not linked yet, create a pair code first
|
|
1305
|
-
- if a paired session has a configured tmux target, treat a tmux nudge as the signal to check the inbox
|
|
1306
|
-
- if a paired session has no tmux target, periodically call `get_telegram_inbox_count`
|
|
1307
|
-
- call `get_telegram_inbox` only if the count is greater than zero
|
|
1308
|
-
- before the final answer in passive no-tmux mode, check `get_telegram_inbox_count`
|
|
1309
|
-
- after handling an inbox item, call `delete_telegram_inbox_message`
|
|
1310
|
-
- include concise task context
|
|
1311
|
-
- include affected files when relevant
|
|
1312
|
-
- include a conservative fallback if the request times out
|
|
1313
|
-
- never send secrets, tokens, private keys, database URLs, or raw customer data
|
|
350
|
+
tellymcp system-prune --env .env --yes
|
|
1314
351
|
```
|
|
1315
352
|
|
|
1316
|
-
##
|
|
1317
|
-
|
|
1318
|
-
Commands run locally:
|
|
1319
|
-
|
|
1320
|
-
- `npm run format:check`
|
|
1321
|
-
- `npm run build`
|
|
1322
|
-
- `npm run lint`
|
|
353
|
+
## Documentation Map
|
|
1323
354
|
|
|
1324
|
-
|
|
355
|
+
- [README-ru.md](./README-ru.md)
|
|
356
|
+
- [STANDALONE.md](./docs/STANDALONE.md)
|
|
357
|
+
- [STANDALONE-ru.md](./docs/STANDALONE-ru.md)
|
|
358
|
+
- [TOOLS.md](./TOOLS.md)
|
|
359
|
+
- [screenshots/README.md](./screenshots/README.md)
|
|
1325
360
|
|
|
1326
|
-
##
|
|
361
|
+
## Status
|
|
1327
362
|
|
|
1328
|
-
|
|
1329
|
-
- no webhook support, long polling only
|
|
1330
|
-
- no automated tests in the current iteration
|
|
1331
|
-
- queued requests are coordinated in-process, with Redis used as the shared state backend
|
|
1332
|
-
- session context tools are implemented, but there is no version history or merge strategy beyond last write wins
|
|
1333
|
-
- inbox polling is explicit; unsolicited Telegram messages are not pushed into the agent automatically
|
|
1334
|
-
- MCP HTTP sessions are kept in-process; restarting the service drops active MCP client sessions and they reconnect cleanly
|
|
363
|
+
This README describes the current gateway-first model.
|
|
1335
364
|
|
|
1336
|
-
|
|
365
|
+
Legacy concepts that should not be used for new setups:
|
|
1337
366
|
|
|
1338
|
-
-
|
|
1339
|
-
-
|
|
1340
|
-
-
|
|
1341
|
-
-
|
|
367
|
+
- pairing codes
|
|
368
|
+
- session inbox APIs
|
|
369
|
+
- `Local` partner menu
|
|
370
|
+
- linked-session flows outside `partner_note` / project collaboration
|