@deadragdoll/tellymcp 0.0.9 → 0.0.11

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.
Files changed (157) hide show
  1. package/.env.example.client +42 -50
  2. package/.env.example.gateway +49 -61
  3. package/CHANGELOG.md +3 -3
  4. package/README-ru.md +205 -384
  5. package/README.md +195 -1194
  6. package/TOOLS.md +294 -377
  7. package/VERSION.md +36 -10
  8. package/config/codex/plugins/telly-workflows/.codex-plugin/plugin.json +18 -0
  9. package/config/codex/plugins/telly-workflows/references/invariants.md +10 -0
  10. package/config/codex/plugins/telly-workflows/skills/telly-browser-screenshot/SKILL.md +27 -0
  11. package/config/codex/plugins/telly-workflows/skills/telly-collab-artifact/SKILL.md +22 -0
  12. package/config/codex/plugins/telly-workflows/skills/telly-human-telegram/SKILL.md +31 -0
  13. package/config/codex/plugins/telly-workflows/skills/telly-partner-note/SKILL.md +36 -0
  14. package/config/templates/env.both.template +40 -20
  15. package/config/templates/env.client.template +34 -18
  16. package/config/templates/env.gateway.template +38 -22
  17. package/dist/cli.js +322 -75
  18. package/dist/codexPluginInstaller.js +215 -0
  19. package/dist/lib/mixins/session.errors.js +34 -1
  20. package/dist/lib/pinoTargets.js +2 -2
  21. package/dist/moleculer.config.js +7 -5
  22. package/dist/services/features/telegram-mcp/approval.service.js +1 -1
  23. package/dist/services/features/telegram-mcp/browser.service.js +95 -2
  24. package/dist/services/features/telegram-mcp/collaboration.service.js +41 -4
  25. package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
  26. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
  27. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +3 -2
  28. package/dist/services/features/telegram-mcp/gateway-socket.service.js +905 -87
  29. package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
  30. package/dist/services/features/telegram-mcp/mcp-http.service.js +9 -1
  31. package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
  32. package/dist/services/features/telegram-mcp/notify.service.js +128 -2
  33. package/dist/services/features/telegram-mcp/runtime.service.js +27 -7
  34. package/dist/services/features/telegram-mcp/session-context.service.js +29 -2
  35. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +133 -10
  36. package/dist/services/features/telegram-mcp/src/app/config/env.js +161 -51
  37. package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
  38. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
  39. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
  40. package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
  41. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +116 -104
  42. package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
  43. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
  44. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  45. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +249 -19
  46. package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
  47. package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
  48. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
  49. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
  50. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
  51. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
  52. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
  53. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
  54. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +649 -75
  55. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
  56. package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
  57. package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
  58. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
  59. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
  60. package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
  61. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
  62. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
  63. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
  64. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
  65. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
  66. package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
  67. package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
  68. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
  69. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
  70. package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
  72. package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
  73. package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
  74. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
  75. package/dist/services/features/telegram-mcp/src/shared/i18n/index.js +46 -0
  76. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +652 -0
  77. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +652 -0
  78. package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
  79. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
  80. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +51 -71
  81. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
  82. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +411 -6524
  83. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
  84. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
  85. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +143 -0
  86. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +633 -0
  87. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
  88. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
  89. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
  90. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
  91. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
  92. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
  93. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
  94. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
  95. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
  96. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
  97. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
  98. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
  99. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
  100. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
  101. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +62 -0
  102. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
  103. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
  104. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
  105. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +101 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
  114. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
  115. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
  116. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +468 -0
  117. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +171 -0
  118. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
  119. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
  120. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
  121. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
  122. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
  123. package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
  124. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
  125. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
  126. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
  127. package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
  128. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +237 -0
  129. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
  130. package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
  131. package/dist/services/features/telegram-mcp/standalone-http.service.js +13 -1
  132. package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
  133. package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
  134. package/dist/services/features/telegram-mcp/tools-sync.service.js +16 -2
  135. package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
  136. package/docs/STANDALONE-ru.md +172 -0
  137. package/docs/STANDALONE.md +172 -0
  138. package/package.json +11 -5
  139. package/scripts/build-package-artifact.sh +27 -0
  140. package/scripts/deploy-gateway.sh +64 -0
  141. package/scripts/deploy-onebot-branch.sh +27 -0
  142. package/scripts/postinstall.js +11 -36
  143. package/STANDALONE-ru.md +0 -274
  144. package/STANDALONE.md +0 -274
  145. package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
  146. package/dist/services/features/telegram-mcp/pair.service.js +0 -33
  147. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
  148. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
  149. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
  150. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
  151. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
  152. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
  153. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
  154. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
  155. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
  156. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
  157. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
package/README.md CHANGED
@@ -1,1341 +1,342 @@
1
- # TellyMCP
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
- [![npm version](https://img.shields.io/npm/v/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
6
- [![npm downloads](https://img.shields.io/npm/dm/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
7
- [![node >= 24](https://img.shields.io/badge/node-%3E%3D24-339933)](https://nodejs.org/)
8
- [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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:
1
+ <div align="center">
105
2
 
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`
227
-
228
- 4. Validate the setup:
229
-
230
- ```bash
231
- tellymcp doctor --env .env
232
- ```
3
+ # TellyMCP
233
4
 
234
- 5. Run it:
5
+ **Telegram control plane for MCP-connected coding agents**
235
6
 
236
- ```bash
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
- Typical public MCP endpoint in `gateway` / `both` mode:
9
+ [![npm version](https://img.shields.io/npm/v/@deadragdoll/tellymcp.svg)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
10
+ [![node](https://img.shields.io/badge/node-%3E%3D24-339933.svg)](https://nodejs.org/)
11
+ [![license](https://img.shields.io/npm/l/@deadragdoll/tellymcp.svg)](./LICENSE)
12
+ [![gateway--first](https://img.shields.io/badge/runtime-gateway--first-1f6feb.svg)](./README.md#current-runtime-model)
13
+ [![telegram webhook](https://img.shields.io/badge/telegram-webhook%20%7C%20polling-26A5E4.svg)](./README.md#webhook-mode)
241
14
 
242
- - `https://your-host.example/api/mcp`
15
+ </div>
243
16
 
244
- ## Start with the bot from inside an agent
17
+ `@deadragdoll/tellymcp` is a Telegram control plane for MCP-connected coding agents.
245
18
 
246
- Once MCP is connected, you can start Telegram pairing by asking the agent in plain language.
19
+ The current model is gateway-first:
247
20
 
248
- Typical phrases the agent should understand:
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
- - `pair with Telegram`
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
- Expected pairing flow:
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
- 1. The agent calls `create_session_pair_code`.
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
- Recommended prompt if you want to be explicit:
38
+ Topology:
265
39
 
266
40
  ```text
267
- Pair this session with Telegram and give me the link code.
268
- ```
269
-
270
- If the agent works inside `tmux`, it should also pass tmux attributes and `cwd` during pairing so Live View and nudges work immediately.
271
-
272
- ### Telegram setup
273
-
274
- 1. Open BotFather in Telegram.
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.
278
-
279
- ## MCP configuration helper
280
-
281
- TellyMCP does not modify your agent config automatically.
282
-
283
- Use:
284
-
285
- ```bash
286
- tellymcp mcp --help
41
+ Telegram user
42
+ |
43
+ Telegram bot + WebApp
44
+ |
45
+ Gateway
46
+ |
47
+ +-- Agent console A
48
+ +-- Agent console B
49
+ +-- Agent console C
287
50
  ```
288
51
 
289
- This prints ready-to-paste MCP JSON snippets for:
52
+ Important consequences:
290
53
 
291
- - local standalone client
292
- - shared gateway endpoint
293
- - optional bearer token usage
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
294
58
 
295
- ## Doctor
59
+ ## Main Surfaces
296
60
 
297
- `doctor` is mode-aware.
61
+ Human-facing:
298
62
 
299
- `client` checks:
63
+ - `telegram_message` records
64
+ - `notify_telegram`
65
+ - `browser_screenshot(send_to_telegram=true)`
300
66
 
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`
67
+ Agent-to-agent:
308
68
 
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
69
+ - `partner_note` records
70
+ - `send_partner_note`
71
+ - `send_partner_file`
72
+ - `list_gateway_sessions`
320
73
 
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
82
 
752
- Current content menu behavior:
83
+ Tools sync:
753
84
 
754
- - `Visible`
755
- - `Full`
756
- - `Last 300`
757
- - `Last 1000`
85
+ - `refresh_tools_markdown`
86
+ - `.mcpsession.json` keeps startup identity and the last known tools hashes
758
87
 
759
- `Tools` currently contains:
88
+ ## Requirements
760
89
 
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
-
785
- ## Default session identity
786
-
787
- If a tool call omits `session_id`, the server derives a stable default session automatically.
788
-
789
- Resolution order for the human-readable project/session title:
790
-
791
- 1. `PROJECT_NAME` from `.env`
792
- 2. `package.json` `name`
793
- 3. git root directory name
794
- 4. current working directory name
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
- Development:
96
+ ## Installation
815
97
 
816
98
  ```bash
817
- yarn dev:gw
99
+ npm install -g @deadragdoll/tellymcp
818
100
  ```
819
101
 
820
- Production build:
102
+ Optional browser runtime:
821
103
 
822
104
  ```bash
823
- yarn build
824
- yarn start:gw
105
+ tellymcp browser install
825
106
  ```
826
107
 
827
- After startup you should see readiness logs in the console.
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
- docker compose up -d redis
111
+ tellymcp codex-plugin install
866
112
  ```
867
113
 
868
- Start Redis + Postgres, for `gateway` or `both` mode:
114
+ ## Quick Start
869
115
 
870
- ```bash
871
- docker compose --profile gateway up -d
872
- ```
116
+ ### 1. Gateway
873
117
 
874
- Add RabbitMQ only when you need it:
118
+ Create a gateway workspace and env:
875
119
 
876
120
  ```bash
877
- docker compose --profile gateway --profile rmq up -d
121
+ mkdir -p ~/telly-gateway
122
+ cd ~/telly-gateway
123
+ tellymcp init gateway
878
124
  ```
879
125
 
880
- Run a full gateway container stack with Redis and Postgres:
126
+ Or copy the sample from this package:
881
127
 
882
- 1. Copy the example:
128
+ - [.env.example.gateway](./.env.example.gateway)
883
129
 
884
- ```bash
885
- cp .env.example.gateway .env-gateway
886
- ```
887
-
888
- 2. Edit `.env-gateway` and set at minimum:
130
+ Required gateway values:
889
131
 
890
132
  - `TELEGRAM_BOT_TOKEN`
891
- - `TELEGRAM_BOT_USERNAME`
892
- - `WEBAPP_PUBLIC_URL`
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
- - `MCP_HTTP_BEARER_TOKEN`
896
-
897
- 3. Start the stack:
140
+ - `GATEWAY_TOKEN`
898
141
 
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:
910
-
911
- - `MCP_HTTP_HOST=0.0.0.0`
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
- This keeps:
942
-
943
- - direct `tmux` access
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.
148
+ ### 2. Agent
948
149
 
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
- TMUX_SOCKET_PATH=/tmp/tmux-1000/default tellymcp run
153
+ mkdir -p ~/agent-a
154
+ cd ~/agent-a
155
+ tellymcp init client
953
156
  ```
954
157
 
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
- }
974
- ```
158
+ Or copy:
975
159
 
976
- ### 2. Inspect session state
160
+ - [.env.example.client](./.env.example.client)
977
161
 
978
- Call `get_session_context`:
162
+ Required client values:
979
163
 
980
- ```json
981
- {
982
- "session_id": "backend-refactor"
983
- }
984
- ```
985
-
986
- This returns:
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
- - saved context if it exists
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
- ### 2. Bind tmux context for Telegram delivery
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
- If Codex is running inside tmux, capture the current tmux context before you leave the workstation. A reliable way is:
174
+ First run:
997
175
 
998
176
  ```bash
999
- tmux display-message -p '#{session_name} #{window_name} #{window_index} #{pane_id} #{pane_index}'
1000
- ```
1001
-
1002
- The preferred path is to pass these attributes, together with the agent workspace `cwd`, directly into `create_session_pair_code`, so pairing immediately creates a distinct session identity for this agent and gives the server the correct `.mcp-xchange` root:
1003
-
1004
- ```json
1005
- {
1006
- "tmux_session_name": "dev",
1007
- "tmux_window_name": "test",
1008
- "tmux_window_index": 1,
1009
- "tmux_pane_id": "%7",
1010
- "tmux_pane_index": 0
1011
- }
177
+ tellymcp run --env .env -s NEW
1012
178
  ```
1013
179
 
1014
- Important:
180
+ After that, `.mcpsession.json` stores:
1015
181
 
1016
- - if you pair without tmux attributes, Telegram linking still succeeds
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
182
+ - `local_session_id`
183
+ - `session_label`
184
+ - `env_file`
1019
185
 
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
- tmux send-keys -t %7 "проверь inbox" C-m
189
+ tellymcp run
1038
190
  ```
1039
191
 
1040
- The service does not forward the Telegram message text into tmux. It only nudges the agent. The agent still reads actual message contents through `get_telegram_inbox` and `delete_telegram_inbox_message`, or through `get_telegram_inbox_count` first in passive no-tmux mode.
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:
1047
-
1048
- - current `cwd`
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:
192
+ ## Webhook Mode
1054
193
 
1055
- ```json
1056
- {
1057
- "session_id": "backend-refactor",
1058
- "session_label": "Backend refactor"
1059
- }
1060
- ```
194
+ Gateway supports Telegram webhook mode.
1061
195
 
1062
- The tool returns a short-lived code, a status message for the agent, and optionally a Telegram deep link.
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
- If you omit `session_id`, the server derives one automatically.
198
+ - `/api/telegram/webhook`
1065
199
 
1066
- If multiple agents work from different tmux windows or panes, pass tmux attributes during pairing so the server derives distinct session identities automatically:
200
+ Relevant env:
1067
201
 
1068
- ```json
1069
- {
1070
- "tmux_session_name": "dev",
1071
- "tmux_window_name": "test",
1072
- "tmux_window_index": 1,
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
- With tmux attributes present, they participate in the derived default `session_id` and `session_label`, which prevents multiple agents from collapsing into one Telegram session even if they share similar project structure. In practice this means `/menu` can later show both agents separately and let Telegram switch the active async context between them.
209
+ When webhook mode is enabled:
1079
210
 
1080
- ### 4. Link in Telegram
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
- In Telegram, send one of:
215
+ ## MCP Usage
1083
216
 
1084
- ```text
1085
- /start ABCD-EFGH
1086
- ```
217
+ ### Local HTTP
1087
218
 
1088
- or
219
+ In client mode the local MCP endpoint is usually:
1089
220
 
1090
221
  ```text
1091
- /link ABCD-EFGH
1092
- ```
1093
-
1094
- After successful pairing, the bot sends a main inline menu. You can also reopen it later with:
1095
-
1096
- ```text
1097
- /menu
1098
- ```
1099
-
1100
- ### 5. Ask the user
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
- }
222
+ http://127.0.0.1:8787/mcp
1117
223
  ```
1118
224
 
1119
- If you want the saved session context to be appended automatically, set:
225
+ Helper:
1120
226
 
1121
- ```json
1122
- {
1123
- "use_saved_context": true
1124
- }
1125
- ```
1126
-
1127
- ### 6. Clear session context
1128
-
1129
- Call `clear_session_context`:
1130
-
1131
- ```json
1132
- {
1133
- "session_id": "backend-refactor"
1134
- }
227
+ ```bash
228
+ tellymcp mcp --url http://127.0.0.1:8787/mcp
1135
229
  ```
1136
230
 
1137
- This removes saved context and also removes Telegram pairing for the same session.
1138
-
1139
- ### 7. Clear session pairing
231
+ Use the MCP HTTP endpoint exposed by `tellymcp run` for Codex and similar agents.
1140
232
 
1141
- Call `clear_session_pairing`:
1142
-
1143
- ```json
1144
- {
1145
- "session_id": "backend-refactor"
1146
- }
1147
- ```
233
+ ## Codex Plugin
1148
234
 
1149
- This removes the Telegram binding so the session can be paired again.
235
+ The package bundles a local Codex plugin with workflow skills for:
1150
236
 
1151
- ### 8. Send one-way notification
237
+ - human Telegram replies
238
+ - partner notes
239
+ - browser screenshot tasks
240
+ - artifact-return flows
1152
241
 
1153
- Call `notify_telegram`:
242
+ Commands:
1154
243
 
1155
- ```json
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
- }
244
+ ```bash
245
+ tellymcp codex-plugin status
246
+ tellymcp codex-plugin install
1163
247
  ```
1164
248
 
1165
- This sends a Telegram message without waiting for a reply.
1166
-
1167
- ### 9. Poll unsolicited Telegram inbox messages
249
+ The installer:
1168
250
 
1169
- If the user writes to the bot without replying to an active question, the message is stored in the session inbox.
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
1170
254
 
1171
- If the paired session has a tmux target, the preferred path is event-driven:
255
+ ## Browser Workflows
1172
256
 
1173
- - Telegram message arrives
1174
- - service stores it in inbox
1175
- - service nudges tmux
1176
- - agent wakes up and calls `get_telegram_inbox`
257
+ Browser tools use Playwright Chromium.
1177
258
 
1178
- If there is no tmux nudge path, use passive mode. First call `get_telegram_inbox_count`:
259
+ Preferred path:
1179
260
 
1180
- ```json
1181
- {
1182
- "session_id": "backend-refactor"
1183
- }
1184
- ```
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
1185
266
 
1186
- Only if `total > 0`, call `get_telegram_inbox`:
1187
-
1188
- ```json
1189
- {
1190
- "session_id": "backend-refactor"
1191
- }
1192
- ```
267
+ If browser binaries are missing:
1193
268
 
1194
- After the agent processes an inbox item, delete it explicitly with `delete_telegram_inbox_message`:
1195
-
1196
- ```json
1197
- {
1198
- "session_id": "backend-refactor",
1199
- "message_id": "inbox_20260504120000_ab12cd"
1200
- }
269
+ ```bash
270
+ tellymcp browser install
1201
271
  ```
1202
272
 
1203
- ## Telegram menu
273
+ Do not replace browser workflows with ad hoc shell Playwright commands unless you are debugging the runtime itself.
1204
274
 
1205
- The bot now exposes a small inline menu for Telegram-side control:
275
+ ## Collaboration Model
1206
276
 
1207
- - `Inbox` shows the latest unsolicited inbox messages for the active session
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
277
+ Projects:
1212
278
 
1213
- Menu callback payloads stay short. Buttons only carry a short Redis key, while the actual menu state is stored server-side with TTL in Redis.
279
+ - live console presence comes from gateway live registry
280
+ - project membership is tracked separately from live presence
281
+ - one console can participate in a project
282
+ - one client can have several live consoles at the same time
1214
283
 
1215
- ## Queue mode
284
+ Expected agent behavior:
1216
285
 
1217
- `MODE=reject`
286
+ - resolve targets through `list_gateway_sessions`
287
+ - read incoming work through `list_xchange_records` and `get_xchange_record`
288
+ - return real files with `send_partner_file`
289
+ - call `mark_xchange_record_read` only after the required reply was successfully sent
1218
290
 
1219
- - if one request is already active, the next tool call fails immediately
291
+ ## Environment Files
1220
292
 
1221
- `MODE=queue`
293
+ Use the shipped samples as the canonical starting point:
1222
294
 
1223
- - requests are queued FIFO
1224
- - queued requests are not sent to Telegram until they become active
295
+ - [.env.example.gateway](./.env.example.gateway)
296
+ - [.env.example.client](./.env.example.client)
1225
297
 
1226
- ## Connect to Codex
298
+ Bundled init templates:
1227
299
 
1228
- Recommended long-running service flow:
300
+ - [config/templates/env.gateway.template](./config/templates/env.gateway.template)
301
+ - [config/templates/env.client.template](./config/templates/env.client.template)
302
+ - [config/templates/env.both.template](./config/templates/env.both.template)
1229
303
 
1230
- 1. Start the service.
304
+ The samples were cleaned to match the current runtime:
1231
305
 
1232
- For local client mode:
306
+ - removed old inbox-only settings
307
+ - removed obsolete pairing-oriented wording
308
+ - removed unused secrets like `SESSION_SECRET`
309
+ - removed unused `APP_NAME`
1233
310
 
1234
- ```bash
1235
- yarn dev:client
1236
- ```
1237
-
1238
- Then register:
1239
-
1240
- ```bash
1241
- codex mcp add telegramHuman --url http://127.0.0.1:8787/mcp
1242
- ```
1243
-
1244
- For gateway/both mode behind nginx:
1245
-
1246
- ```bash
1247
- yarn dev:builder
1248
- ```
311
+ ## Operational Commands
1249
312
 
1250
- 2. Register the already-running MCP endpoint in Codex:
313
+ Health check:
1251
314
 
1252
315
  ```bash
1253
- codex mcp add telegramHuman --url http://127.0.0.1:8080/api/mcp
316
+ tellymcp doctor --env .env
1254
317
  ```
1255
318
 
1256
- If you enable bearer auth with `MCP_HTTP_BEARER_TOKEN`, register it like this:
319
+ Destructive local+gateway cleanup:
1257
320
 
1258
321
  ```bash
1259
- export TELEGRAM_MCP_BEARER_TOKEN="your-token"
1260
- codex mcp add telegramHuman \
1261
- --url http://127.0.0.1:8080/api/mcp \
1262
- --bearer-token-env-var TELEGRAM_MCP_BEARER_TOKEN
322
+ tellymcp system-prune --env .env --yes
1263
323
  ```
1264
324
 
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
1314
- ```
1315
-
1316
- ## Verification
1317
-
1318
- Commands run locally:
1319
-
1320
- - `npm run format:check`
1321
- - `npm run build`
1322
- - `npm run lint`
325
+ ## Documentation Map
1323
326
 
1324
- Tests are not implemented in this iteration.
327
+ - [README-ru.md](./README-ru.md)
328
+ - [STANDALONE.md](./docs/STANDALONE.md)
329
+ - [STANDALONE-ru.md](./docs/STANDALONE-ru.md)
330
+ - [TOOLS.md](./TOOLS.md)
331
+ - [screenshots/README.md](./screenshots/README.md)
1325
332
 
1326
- ## Known limitations
333
+ ## Status
1327
334
 
1328
- - Telegram is the only transport backend implemented right now
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
335
+ This README describes the current gateway-first model.
1335
336
 
1336
- ## Security notes
337
+ Legacy concepts that should not be used for new setups:
1337
338
 
1338
- - all outbound question content is redacted before sending to Telegram
1339
- - replies are accepted only from the Telegram user/chat bound to the session
1340
- - pairing codes are short-lived and one-time use
1341
- - do not use this server to send secrets, raw `.env` content, tokens, private keys, or customer data
339
+ - pairing codes
340
+ - session inbox APIs
341
+ - `Local` partner menu
342
+ - linked-session flows outside `partner_note` / project collaboration