@deadragdoll/tellymcp 0.0.10 → 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 (153) hide show
  1. package/.env.example.client +42 -52
  2. package/.env.example.gateway +48 -62
  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 +11 -11
  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 +39 -20
  15. package/config/templates/env.client.template +34 -19
  16. package/config/templates/env.gateway.template +37 -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/browser.service.js +94 -1
  23. package/dist/services/features/telegram-mcp/collaboration.service.js +40 -3
  24. package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
  25. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
  26. package/dist/services/features/telegram-mcp/gateway-socket.service.js +897 -85
  27. package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
  28. package/dist/services/features/telegram-mcp/mcp-http.service.js +8 -0
  29. package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
  30. package/dist/services/features/telegram-mcp/notify.service.js +127 -1
  31. package/dist/services/features/telegram-mcp/session-context.service.js +28 -1
  32. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +132 -10
  33. package/dist/services/features/telegram-mcp/src/app/config/env.js +158 -52
  34. package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
  35. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
  36. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
  37. package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
  38. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +116 -104
  39. package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
  40. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
  41. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  42. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +249 -19
  43. package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
  44. package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
  45. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
  46. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
  47. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
  48. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
  49. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
  50. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
  51. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +649 -75
  52. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
  53. package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
  54. package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
  55. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
  56. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
  57. package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
  58. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
  59. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
  60. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
  61. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
  62. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
  63. package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
  64. package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
  65. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
  66. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
  67. package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
  68. package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
  69. package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
  70. package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
  71. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
  72. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +139 -42
  73. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +135 -38
  74. package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
  75. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
  76. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +42 -71
  77. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
  78. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +415 -7101
  79. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
  80. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
  81. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +143 -0
  82. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +633 -0
  83. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
  84. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
  85. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
  86. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
  87. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
  88. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
  89. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
  90. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
  91. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
  92. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
  93. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
  94. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
  95. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
  96. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
  97. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +62 -0
  98. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
  99. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
  100. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
  101. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
  102. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
  103. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +101 -0
  104. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
  105. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +468 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +171 -0
  114. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
  115. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
  116. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
  117. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
  118. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
  119. package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
  120. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
  121. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
  122. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
  123. package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
  124. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +237 -0
  125. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
  126. package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
  127. package/dist/services/features/telegram-mcp/standalone-http.service.js +12 -0
  128. package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
  129. package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
  130. package/dist/services/features/telegram-mcp/tools-sync.service.js +15 -1
  131. package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
  132. package/docs/STANDALONE-ru.md +172 -0
  133. package/docs/STANDALONE.md +172 -0
  134. package/package.json +10 -5
  135. package/scripts/build-package-artifact.sh +27 -0
  136. package/scripts/deploy-gateway.sh +64 -0
  137. package/scripts/deploy-onebot-branch.sh +27 -0
  138. package/scripts/postinstall.js +11 -36
  139. package/STANDALONE-ru.md +0 -274
  140. package/STANDALONE.md +0 -274
  141. package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
  142. package/dist/services/features/telegram-mcp/pair.service.js +0 -33
  143. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
  144. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
  145. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
  146. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
  147. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
  148. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
  149. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
  150. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
  151. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
  152. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
  153. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
package/TOOLS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Tools
2
2
 
3
- Version: `2026-05-18.1`
3
+ Version: `2026-05-22.1`
4
4
 
5
5
  Gateway/client runtime compatibility:
6
6
 
@@ -10,7 +10,7 @@ Gateway/client runtime compatibility:
10
10
  - `TOOLS.md` sync tells the agent to refresh instructions.
11
11
  - `ws hello/hello_ack` checks `package_version`, `protocol_version`, and `capabilities`.
12
12
  - If protocol major versions differ, gateway transport is blocked until the older side is upgraded.
13
- - If you receive a system inbox message about gateway/client version mismatch, treat it as operational priority before continuing collaboration or live-relay work.
13
+ - If you receive a system notice or structured record about gateway/client version mismatch, treat it as operational priority before continuing collaboration or live-relay work.
14
14
 
15
15
  This MCP server currently exposes the following tools.
16
16
 
@@ -40,6 +40,10 @@ Browser runtime rule:
40
40
 
41
41
  Collaboration tools:
42
42
 
43
+ - `list_gateway_sessions`
44
+ - `list_xchange_records`
45
+ - `get_xchange_record`
46
+ - `mark_xchange_record_read`
43
47
  - `send_partner_note`
44
48
  - `send_partner_file`
45
49
 
@@ -47,131 +51,42 @@ Utility tools:
47
51
 
48
52
  - `refresh_tools_markdown`
49
53
 
50
- ## `create_session_pair_code`
54
+ ## Console model
51
55
 
52
- Purpose:
53
-
54
- - Create a short-lived Telegram pairing code for a session.
55
-
56
- Typical use:
57
-
58
- - first-time session linking
59
- - re-linking after `clear_session_pairing`
60
- - any request like "register me in Telegram", "link this session to Telegram", "pair this agent", or similar
61
-
62
- Input:
63
-
64
- - `session_id?`
65
- - `session_label?`
66
- - `cwd?`
67
- - `expires_in_seconds?`
68
- - `tmux_session_name?`
69
- - `tmux_window_name?`
70
- - `tmux_window_index?`
71
- - `tmux_pane_id?`
72
- - `tmux_pane_index?`
73
-
74
- Output:
56
+ Gateway-first runtime model:
75
57
 
76
- - `session_id`
77
- - `code`
78
- - `expires_at`
79
- - `status`
80
- - `status_message`
81
- - `telegram_link_hint?`
82
-
83
- Behavior:
84
-
85
- - generated pairing codes are short numeric 3-digit one-time codes
86
- - if `session_id` is omitted, the server derives it automatically
87
- - if `cwd` is provided, the server uses it as the agent workspace root for default session identity and for `.mcp-xchange` file downloads
88
- - `.mcp-xchange` is the active local exchange workspace for files, screenshots, notes, and handoffs
89
- - one directory now maps to one logical session by default
90
- - the service stores that logical identity in `.mcpsession.json` inside the workspace
91
- - tmux attributes are runtime metadata only and no longer change `session_id`
92
- - if tmux attributes are not provided here, the Telegram session can still pair successfully, but tmux nudges, Mini App controls, and other tmux-driven features will remain unavailable until `set_tmux_target` is called later
58
+ - agents register themselves on the gateway automatically through `GATEWAY_TOKEN`
59
+ - Telegram no longer links sessions with pair codes
60
+ - `/menu` in the gateway bot shows available remote consoles directly
61
+ - one running agent console is one logical session/console target
93
62
 
94
63
  Required agent practice:
95
64
 
96
- This is mandatory for the agent:
97
-
98
- - when the user asks to register, link, pair, or connect the current agent/session to Telegram, do not call `create_session_pair_code` immediately from memory
99
- - first determine the correct workspace `cwd`
100
- - if tmux is available, collect the current tmux attributes too
101
- - then call `create_session_pair_code` with them
102
-
103
- Required order:
104
-
105
- 1. Determine the agent workspace `cwd`.
106
- 2. If running inside tmux, collect tmux attributes:
107
-
108
- ```bash
109
- tmux display-message -p '#{session_name} #{window_name} #{window_index} #{pane_id} #{pane_index}'
110
- ```
111
-
112
- 3. Call `create_session_pair_code` and pass:
113
- - `cwd`
114
- - tmux attributes when available
115
- 4. Use `set_tmux_target` later only as a repair, refresh, or override path.
116
-
117
- Do not skip `cwd`. It is now the anchor for the stable session marker.
118
-
119
- After `create_session_pair_code` succeeds:
120
-
121
- - treat the returned `session_id` as the canonical session identity for this agent
122
- - remember it in the current task context
123
- - pass it explicitly to later session-scoped tools
124
- - do not rely on implicit session defaults unless you also know that `cwd` is already correct for this exact agent workspace
125
-
126
- Why this matters:
127
-
128
- - many MCP tools resolve `session_id` from explicit input first
129
- - if it is omitted, the server may derive it from `cwd`
130
- - if the agent did not pass the correct `cwd`, or the MCP client does not preserve it, a later tool call can hit the wrong session
131
-
132
- Mandatory rule:
133
-
134
- - after pairing, prefer:
135
- - `session_id: "<returned value>"`
136
- - for tools like:
137
- - `ask_user_telegram`
138
- - `notify_telegram`
139
- - `get_telegram_inbox_count`
140
- - `get_telegram_inbox`
141
- - `delete_telegram_inbox_message`
142
- - browser/session-context tools
143
- - do not assume Telegram "active session" in the bot menu affects MCP tool defaults.
144
-
145
- If you skip `cwd`:
146
-
147
- - the service may create or reuse the wrong `.mcpsession.json`
148
- - Telegram file exchange into `.mcp-xchange` may not know the correct agent workspace
149
-
150
- If you skip tmux attributes:
151
-
152
- - pairing may still succeed
153
- - but tmux nudges and Mini App controls may not work until repaired later
154
-
155
- ## `clear_session_pairing`
156
-
157
- Purpose:
158
-
159
- - Remove the Telegram binding for a session.
160
-
161
- Input:
162
-
163
- - `session_id?`
164
-
165
- Output:
166
-
167
- - `cleared`
168
- - `session_id`
65
+ - when the user asks to contact another agent, inspect consoles through `list_gateway_sessions`
66
+ - when the user asks to work with Telegram-linked human interaction, use the current console `session_id` explicitly
67
+ - in gateway mode, `session_id` means the live console id from `-s`
68
+ - do not use workspace-derived ids like `project-abc12345` for gateway routing
69
+ - do not use `cwd` to route to a console through the gateway
70
+ - if you need a `session_id` and do not know it yet, call `list_gateway_sessions` and use canonical `session_id` from the matching live console
71
+ - do not ask the user for the live console id when it can be resolved from `list_gateway_sessions`
72
+ - assume gateway is the only user-facing control plane
73
+ - do not mention pair codes, `/link`, admin menus, or session pairing unless the user is explicitly asking about legacy behavior
74
+
75
+ Preferred order for cross-console work:
76
+
77
+ 1. Call `list_gateway_sessions`.
78
+ 2. Choose the correct target by `session_label`, `node_id`, `client_label`, or canonical `session_id`.
79
+ 3. Use:
80
+ - `send_partner_note`
81
+ - `send_partner_file`
82
+ - browser tools
83
+ with explicit `session_id` for the current console or explicit target routing fields for another console.
169
84
 
170
85
  ## `set_session_context`
171
86
 
172
87
  Purpose:
173
88
 
174
- - Save compact reusable session context in Redis.
89
+ - Save compact reusable console context.
175
90
 
176
91
  Input:
177
92
 
@@ -189,18 +104,19 @@ Output:
189
104
  - `session_id`
190
105
  - `updated_at`
191
106
  - `has_binding`
107
+ Legacy field name. Read it as: whether this console currently has an active Telegram route through the gateway.
192
108
 
193
109
  ## `rename_session`
194
110
 
195
111
  Purpose:
196
112
 
197
- - Rename the session title/label only.
113
+ - Rename only the human-readable console title/label.
198
114
 
199
115
  Rules:
200
116
 
201
117
  - this changes only the human-readable title
202
118
  - it does not change `session_id`
203
- - it does not change pairing, tmux target, inbox, or saved context
119
+ - it does not change routing or saved context
204
120
 
205
121
  Input:
206
122
 
@@ -214,57 +130,76 @@ Output:
214
130
  - `session_label`
215
131
  - `updated_at`
216
132
 
217
- ## `set_tmux_target`
133
+ ## `get_session_context`
218
134
 
219
135
  Purpose:
220
136
 
221
- - Save the tmux pane target for a session so the long-running service can nudge the agent when new non-reply Telegram messages arrive for that paired session.
137
+ - Read saved console context and routing status.
222
138
 
223
139
  Recommended use:
224
140
 
225
- - run this while still at the workstation
226
- - do not treat this as the source of session identity
227
- - use it immediately after pairing only if you need to repair, override, or refresh the target
228
- - prefer a pane id such as `%7`
229
-
230
- How to obtain tmux attributes:
231
-
232
- ```bash
233
- tmux display-message -p '#{session_name} #{window_name} #{window_index} #{pane_id} #{pane_index}'
234
- ```
141
+ - setup/debug only
142
+ - use this while diagnosing state or inspecting saved metadata
143
+ - do not call this in the normal processing path unless you are diagnosing state
235
144
 
236
145
  Input:
237
146
 
238
147
  - `session_id?`
239
- - `tmux_session_name?`
240
- - `tmux_window_name?`
241
- - `tmux_window_index?`
242
- - `tmux_pane_id?`
243
- - `tmux_pane_index?`
244
- - `tmux_target`
245
148
 
246
149
  Output:
247
150
 
248
151
  - `session_id`
249
- - `tmux_target`
250
- - `tmux_session_name?`
251
- - `tmux_window_name?`
252
- - `tmux_window_index?`
253
- - `tmux_pane_id?`
254
- - `tmux_pane_index?`
152
+ - `exists`
153
+ - `has_binding`
154
+ Legacy field name. Read it as: whether this console is currently reachable from Telegram through the gateway.
255
155
  - `status_message`
156
+ - `context?`
157
+ - `binding?`
158
+ Legacy field name. If present, this is the current Telegram route metadata for the console.
159
+ - `terminal?`
160
+ Terminal runtime metadata for the console.
256
161
 
257
- ## `get_tmux_target`
162
+ ## `refresh_tools_markdown`
258
163
 
259
164
  Purpose:
260
165
 
261
- - Check whether a tmux target is configured for the current session and when it was last nudged.
166
+ - Download the canonical `TOOLS.md` from the configured gateway.
167
+ - Return the canonical instructions in a hash-based form so the agent can refresh without mandatory local file writes.
168
+
169
+ Input:
262
170
 
263
- Recommended use:
171
+ - `session_id`
172
+ - `known_hash?`
264
173
 
265
- - setup/debug only
266
- - use this when configuring tmux delivery or diagnosing why nudges do not happen
267
- - do not call this in the normal inbox-processing path after a tmux nudge
174
+ Output:
175
+
176
+ - `source`
177
+ - `session_id?`
178
+ - `current_hash`
179
+ - `changed`
180
+ - `content?`
181
+ - `bytes`
182
+
183
+ Behavior:
184
+
185
+ - if `GATEWAY_PUBLIC_URL` is configured, the tool fetches `GET /api/gateway/tools-md`
186
+ - if no gateway is configured, the tool falls back to the installed package copy
187
+ - the canonical source is the installed gateway package copy, not an arbitrary current working directory
188
+ - in gateway mode, routing to the target console is done only by explicit canonical `session_id = client_uuid:local_session_id`
189
+ - `cwd` is workspace metadata for the target console after routing succeeds; it is not a routing key
190
+ - if the live console id is not already known, call `list_gateway_sessions` first and use `session_id`
191
+ - prefer hash-based refresh:
192
+ - pass `known_hash` from the last applied TOOLS state
193
+ - if `changed=false`, keep current instructions
194
+ - if `changed=true`, read and apply returned `content`
195
+ - there is no local file-save mode in the normal flow
196
+ - do not create or rely on workspace `TOOLS.md` copies
197
+
198
+ ## `clear_session_context`
199
+
200
+ Purpose:
201
+
202
+ - Remove saved session context and related per-session state for the console.
268
203
 
269
204
  Input:
270
205
 
@@ -272,79 +207,162 @@ Input:
272
207
 
273
208
  Output:
274
209
 
210
+ - `cleared`
275
211
  - `session_id`
276
- - `configured`
277
- - `tmux_target?`
278
- - `tmux_session_name?`
279
- - `last_nudge_at?`
280
- - `status_message`
212
+ - `cleared_pairing`
213
+ Compatibility field name. Treat it as legacy cleanup metadata, not as an instruction to use pairing.
281
214
 
282
- ## `get_session_context`
215
+ ## `send_partner_note`
216
+
217
+ ## `list_gateway_sessions`
283
218
 
284
219
  Purpose:
285
220
 
286
- - Read saved session context and Telegram binding status.
221
+ - List all consoles currently known to the configured gateway.
222
+ - Merge:
223
+ - connected consoles from gateway WS presence
224
+ - registered project consoles from the gateway database
225
+ - Use this before direct cross-console communication outside one collab project.
226
+ - Use this to resolve the authoritative live console id for other gateway-routed tools.
287
227
 
288
- Recommended use:
228
+ Input:
289
229
 
290
- - setup/debug only
291
- - use this while pairing, diagnosing state, or inspecting saved metadata
292
- - do not call this in the normal inbox-processing path after a tmux nudge
230
+ - `client_uuid?`
231
+ - `connected_only?`
232
+
233
+ Output:
234
+
235
+ - `total`
236
+ - `sessions[]`
237
+ - `session_id`
238
+ - `local_session_id`
239
+ - `client_uuid`
240
+ - `local_session_id`
241
+ - `session_label?`
242
+ - `client_label?`
243
+ - `telegram_username?`
244
+ - `telegram_display_name?`
245
+ - `bot_username?`
246
+ - `node_id?`
247
+ - `package_version?`
248
+ - `project_uuids?`
249
+ - `project_names?`
250
+ - `connected`
251
+ - `registered`
252
+
253
+ Rules:
254
+
255
+ - use this when the user asks to contact a session that is not the current linked partner and not necessarily part of the current collab project
256
+ - for direct gateway-wide routing, resolve the target from this list and then call:
257
+ - `send_partner_note`
258
+ - or `send_partner_file`
259
+ - in that direct mode, pass:
260
+ - `target_client_uuid`
261
+ - `target_local_session_id`
262
+ - do not invent `target_session_id` for direct gateway-wide routing
263
+ - prefer connected sessions for direct gateway-wide messaging
264
+ - if a session is not connected, do not assume direct delivery will succeed
265
+
266
+ ## `list_xchange_records`
267
+
268
+ Purpose:
269
+
270
+ - List structured `.mcp-xchange` records from the local sqlite store for the current session.
271
+ - Use this as the first lookup path for partner notes, local handoffs, unread collaboration items, and follow-up work.
293
272
 
294
273
  Input:
295
274
 
296
275
  - `session_id?`
276
+ - `status?`
277
+ - `new`
278
+ - `read`
279
+ - `archived`
280
+ - `category?`
281
+ - `partner_note`
282
+ - `local_handoff`
283
+ - `direction?`
284
+ - `incoming`
285
+ - `outgoing`
286
+ - `local`
287
+ - `limit?`
297
288
 
298
289
  Output:
299
290
 
300
291
  - `session_id`
301
- - `exists`
302
- - `has_binding`
303
- - `status_message`
304
- - `context?`
305
- - `binding?`
306
- - `tmux?`
292
+ - `total`
293
+ - `records`
307
294
 
308
- ## `refresh_tools_markdown`
295
+ Each record includes:
296
+
297
+ - `record_id`
298
+ - `category`
299
+ - `direction`
300
+ - `status`
301
+ - `kind?`
302
+ - `summary`
303
+ - `action_desc`
304
+ - `tools`
305
+ - `attachments`
306
+ - `source_*` and `target_*` routing fields when available
307
+ - `project_uuid?`
308
+ - `project_name?`
309
+ - `requires_reply?`
310
+ - `expected_reply?`
311
+ - `in_reply_to?`
312
+ - `created_at`
313
+ - `updated_at`
314
+ - `read_at?`
315
+
316
+ Rules:
317
+
318
+ - use this first when the session is nudged for partner collaboration or local handoff work
319
+ - prefer `status = "new"` for fresh work
320
+ - after selecting the relevant record, call `get_xchange_record`
321
+
322
+ ## `get_xchange_record`
309
323
 
310
324
  Purpose:
311
325
 
312
- - Download the canonical `TOOLS.md` from the configured gateway.
313
- - Overwrite the local `TOOLS.md` so the agent can refresh instructions without manual copying.
326
+ - Read one structured `.mcp-xchange` record in full.
327
+ - This gives the canonical `body_text`, `action_desc`, `tools`, attachments, and routing metadata for the next step.
314
328
 
315
329
  Input:
316
330
 
317
- - `save_locally?`
331
+ - `session_id?`
332
+ - `record_id`
318
333
 
319
334
  Output:
320
335
 
321
- - `source`
322
- - `saved`
323
- - `bytes`
324
- - `path?`
336
+ - `session_id`
337
+ - `record`
325
338
 
326
- Behavior:
339
+ Rules:
327
340
 
328
- - if `GATEWAY_PUBLIC_URL` is configured, the tool fetches `GET /api/gateway/tools-md`
329
- - if no gateway is configured, the tool falls back to the local file
330
- - on the gateway node, the local `TOOLS.md` is the canonical source and should always be kept current
331
- - after successful refresh, treat the local `TOOLS.md` as updated state for this session and re-read it before continuing
341
+ - after `list_xchange_records`, call this on the chosen `record_id`
342
+ - trust `action_desc` and `tools` over old markdown-index habits
343
+ - use `body_text` as the structured note content; only open the note file directly if you need the raw markdown artifact
332
344
 
333
- ## `clear_session_context`
345
+ ## `mark_xchange_record_read`
334
346
 
335
347
  Purpose:
336
348
 
337
- - Remove saved session context and Telegram pairing for the session.
349
+ - Mark a structured `.mcp-xchange` record as read after consuming it.
338
350
 
339
351
  Input:
340
352
 
341
353
  - `session_id?`
354
+ - `record_id`
342
355
 
343
356
  Output:
344
357
 
345
- - `cleared`
346
358
  - `session_id`
347
- - `cleared_pairing`
359
+ - `record_id`
360
+ - `updated`
361
+
362
+ Rules:
363
+
364
+ - do this after you have consumed `body_text`, attachments, and next-step instructions
365
+ - do not mark a record read before you have actually processed it
348
366
 
349
367
  ## `send_partner_note`
350
368
 
@@ -352,14 +370,16 @@ Purpose:
352
370
 
353
371
  - Send a structured collaboration note to another session.
354
372
  - Write a note file into the partner workspace under `.mcp-xchange/shares/`.
355
- - Append a line to the partner `.mcp-xchange/SHARED_INDEX.md`.
373
+ - Create a structured xchange record in the partner sqlite store.
356
374
  - Optionally copy listed artifacts from the current workspace into the partner `.mcp-xchange/shares/files/<share_id>/`.
357
- - Create an inbox message for the partner agent and trigger the normal tmux nudge path.
375
+ - Create a structured xchange wake-up for the partner agent through the normal gateway delivery path.
358
376
 
359
377
  Input:
360
378
 
361
379
  - `session_id?`
362
380
  - `target_session_id?`
381
+ - `target_client_uuid?`
382
+ - `target_local_session_id?`
363
383
  - `project_uuid?`
364
384
  - `kind`
365
385
  - `share`
@@ -381,9 +401,10 @@ Output:
381
401
  - `kind`
382
402
  - `share_id`
383
403
  - `note_path`
384
- - `share_index_path`
404
+ - `xchange_record_id`
385
405
  - `copied_artifacts`
386
406
  - `inbox_message_id`
407
+ Legacy compatibility field name for delivery bookkeeping.
387
408
  - `requires_reply`
388
409
 
389
410
  Required agent practice:
@@ -400,15 +421,22 @@ Required agent practice:
400
421
  How to find the partner correctly:
401
422
 
402
423
  - never guess the target session from labels, menu text, or memory
403
- - there are two valid targeting modes:
424
+ - there are three valid targeting modes:
404
425
  - local linked mode:
405
426
  - call `get_session_context`
406
427
  - use `context.linked_session_id`
407
428
  - project / collab mode:
408
429
  - use the explicit `target_session_id` that came from the project note, Telegram prompt, or task context
409
430
  - if available, also pass `project_uuid`
431
+ - direct gateway-wide mode:
432
+ - call `list_gateway_sessions`
433
+ - resolve the exact target from the returned `client_uuid` + `local_session_id`
434
+ - pass them as:
435
+ - `target_client_uuid`
436
+ - `target_local_session_id`
410
437
  - for project replies, do not fall back to `linked_session_id`
411
438
  - if `target_session_id` is explicitly known, it has priority over any linked partner
439
+ - if `target_client_uuid` + `target_local_session_id` are explicitly known, they define direct gateway-wide routing and have priority over linked partner memory
412
440
  - if neither `target_session_id` nor `linked_session_id` is available:
413
441
  - do not retry blindly
414
442
  - tell the user the target session is unknown
@@ -419,6 +447,7 @@ Minimal safe sequence:
419
447
  1. Call `get_session_context`.
420
448
  2. Resolve the target:
421
449
  - prefer explicit `target_session_id` for project/collab work
450
+ - for gateway-wide direct work, use explicit `target_client_uuid` + `target_local_session_id`
422
451
  - otherwise use `linked_session_id` for local partner work
423
452
  3. Decide the correct note kind: `question`, `reply`, `share`, `request`, or `handoff`.
424
453
  4. Call `send_partner_note`.
@@ -445,11 +474,14 @@ Reply rule for project asks:
445
474
  - `Reply message_uuid: ...`
446
475
  - `Reply target_session_id: ...`
447
476
  - `Reply project_uuid: ...`
477
+ - `Reply target_client_uuid: ...`
478
+ - `Reply target_local_session_id: ...`
448
479
  or a `Reply Params` section with the same data
449
480
  - then reply with those exact values
450
481
  - if `in_reply_to` is available, prefer `Reply message_uuid`
451
482
  - if only the note `share_id` is available, gateway now also accepts that value in `in_reply_to`
452
483
  - do not use `linked_session_id` for that reply
484
+ - if direct reply params contain `target_client_uuid` + `target_local_session_id`, do not replace them with `target_session_id`
453
485
  - if the note contains an `Action Required` section, treat it as mandatory execution guidance, not as optional commentary
454
486
  - do not stop after local analysis when `Action Required` says to reply
455
487
  - when `Reply Params` are present, prefer an explicit `send_partner_note(...)` call with those exact values
@@ -489,6 +521,8 @@ Input:
489
521
 
490
522
  - `session_id?`
491
523
  - `target_session_id?`
524
+ - `target_client_uuid?`
525
+ - `target_local_session_id?`
492
526
  - `project_uuid?`
493
527
  - `cwd?`
494
528
  - `file_path`
@@ -515,10 +549,12 @@ Minimal file-delivery rule:
515
549
  Routing priority:
516
550
 
517
551
  1. explicit `Reply target_session_id`
518
- 2. explicit `target_session_id` from the current project/task context
519
- 3. local `linked_session_id`
552
+ 2. explicit `Reply target_client_uuid` + `Reply target_local_session_id`
553
+ 3. explicit `target_session_id` from the current project/task context
554
+ 4. explicit `target_client_uuid` + `target_local_session_id` from `list_gateway_sessions`
555
+ 5. local `linked_session_id`
520
556
 
521
- For project/collab traffic, step 3 is fallback only when no explicit target exists.
557
+ For project/collab traffic, step 5 is fallback only when no explicit target exists.
522
558
 
523
559
  Canonical example for a project reply:
524
560
 
@@ -536,19 +572,22 @@ Canonical example for a project reply:
536
572
 
537
573
  How the receiving agent must react:
538
574
 
539
- - partner collaboration wake-ups are not ordinary Telegram inbox wake-ups
540
- - if the tmux nudge says things like:
541
- - `прочитай SHARED_INDEX.md`
542
- - `partner note`
543
- - `partner notes`
544
- then do not start with `get_telegram_inbox`
575
+ - wake-ups now point to the unified `.mcp-xchange` flow
576
+ - if the wake-up says things like:
577
+ - `проверь xchange records`
578
+ - `telegram_message`
579
+ - `partner_note`
580
+ then do not start with a legacy inbox-specific tool
545
581
  - instead:
546
- 1. open `.mcp-xchange/SHARED_INDEX.md`
547
- 2. find the newest partner note
548
- 3. open that note file
549
- 4. read any copied artifacts referenced there
550
- - only use `get_telegram_inbox` for the normal Telegram human-message path
551
- - do not confuse partner collaboration notes with human Telegram inbox traffic
582
+ 1. call `list_xchange_records`
583
+ 2. identify the newest relevant record by category:
584
+ - `telegram_message` if the sender is a human from Telegram
585
+ - `partner_note` if the sender is another agent
586
+ 3. call `get_xchange_record`
587
+ 4. read `body_text`, `action_desc`, `tools`, and any attachments
588
+ - reply according to the record category:
589
+ - `telegram_message` -> answer with `notify_telegram`
590
+ - `partner_note` -> answer with `send_partner_note`
552
591
 
553
592
  What to do after reading the note:
554
593
 
@@ -603,8 +642,8 @@ Note contract:
603
642
 
604
643
  - the service writes one note per message to:
605
644
  - `.mcp-xchange/shares/<share_id>.md`
606
- - the partner index is append-only:
607
- - `.mcp-xchange/SHARED_INDEX.md`
645
+ - the structured source of truth is the local sqlite xchange store:
646
+ - `.mcp-xchange/xchange.sqlite3`
608
647
  - artifacts are copied into:
609
648
  - `.mcp-xchange/shares/files/<share_id>/...`
610
649
 
@@ -675,107 +714,6 @@ Output:
675
714
  - `sent`
676
715
  - `message_id?`
677
716
 
678
- ## `get_telegram_inbox_count`
679
-
680
- Purpose:
681
-
682
- - Fast inbox check.
683
- - Returns only the number of stored unsolicited Telegram messages.
684
-
685
- Recommended use:
686
-
687
- - use this for lightweight passive checks
688
- - use this when no tmux nudge path is configured
689
- - after a tmux nudge, prefer calling `get_telegram_inbox` directly instead of spending an extra step on count
690
-
691
- Input:
692
-
693
- - `session_id?`
694
-
695
- Output:
696
-
697
- - `session_id`
698
- - `total`
699
-
700
- ## `get_telegram_inbox`
701
-
702
- Purpose:
703
-
704
- - Read unsolicited Telegram inbox messages stored for a session.
705
- - Return a bounded batch rather than forcing the agent to pull the whole backlog at once.
706
-
707
- Input:
708
-
709
- - `session_id?`
710
-
711
- Notes:
712
-
713
- - Browser tools require Playwright Chromium browser binaries.
714
- - If the runtime is missing, run `tellymcp browser install`, then retry `browser_open`.
715
-
716
- - the server always uses `TELEGRAM_INBOX_BATCH_SIZE`
717
- - the agent should not try to choose its own batch size
718
-
719
- Output:
720
-
721
- - `session_id`
722
- - `total`
723
- - `has_more`
724
- - `messages`
725
-
726
- Per-message fields:
727
-
728
- - `message_id`
729
- - `source = "telegram"`
730
- - `message_kind`
731
- - `human`
732
- - `system`
733
- - `telegram_message_id`
734
- - `telegram_chat_id`
735
- - `telegram_user_id`
736
- - `text`
737
- - `attachments?`
738
- - `received_at`
739
-
740
- Meaning:
741
-
742
- - when a task starts from one of these inbox items, treat it as a Telegram-originated task
743
- - use `notify_telegram` for progress updates and `ask_user_telegram` for clarifications during that task
744
- - if `message_kind = "system"`:
745
- - treat it as an operational instruction from the service
746
- - do not reinterpret it as a normal user request
747
- - if it contains `Action Required`, follow that operational flow first
748
- - for example, a `TOOLS.md updated` system message means:
749
- 1. call `refresh_tools_markdown`
750
- 2. re-read the local `TOOLS.md`
751
- 3. apply the updated rules before continuing
752
- - do not answer this kind of message with a normal human-facing reply unless the instruction explicitly says to notify the user
753
- - process the batch one message at a time
754
- - move to the next inbox item only if the current one did not create a blocker
755
- - if the current message leads to a clarification wait or another blocking condition, stop batch processing there and leave the remaining inbox items pending
756
- - if `attachments` is present, those are local paths inside `.mcp-xchange` that the agent can read from the workspace
757
- - those paths are ordinary local workspace paths inside `.mcp-xchange`
758
- - file upload itself is now the handoff action when the user is inside a target context
759
- - there is no separate Telegram `Files` menu anymore
760
- - browser screenshots created by `browser_screenshot` are tracked separately and appear under Telegram `Browser -> Screenshots`
761
-
762
- ## `delete_telegram_inbox_message`
763
-
764
- Purpose:
765
-
766
- - Remove a processed inbox message so it is not handled again.
767
-
768
- Input:
769
-
770
- - `session_id?`
771
- - `message_id`
772
-
773
- Output:
774
-
775
- - `deleted`
776
- - `session_id`
777
- - `message_id`
778
-
779
717
  ## `browser_open`
780
718
 
781
719
  Purpose:
@@ -1134,30 +1072,29 @@ Output:
1134
1072
 
1135
1073
  Telegram UI summary:
1136
1074
 
1137
- - `/menu` is the only top-level Telegram command for session navigation
1138
- - root menu shows one session button per row
1139
- - root menu also shows tmux bridge status
1140
- - session menu uses:
1075
+ - `/menu` is the only top-level Telegram command for console navigation
1076
+ - root menu shows one console button per row
1077
+ - root menu reflects terminal bridge status for available consoles
1078
+ - console menu uses:
1141
1079
  - `Live | Content | Browser`
1142
- - `Local | Collab`
1143
- - `Inbox | Storage | Settings`
1080
+ - `Collab`
1081
+ - `Storage | Settings`
1144
1082
  - `Back`
1145
- - default logical session identity comes from `.mcpsession.json` in the workspace
1146
- - changing tmux session/window/pane does not change `session_id`
1083
+ - default logical console identity comes from `.mcpsession.json` in the workspace or explicit `-s`
1084
+ - terminal runtime metadata does not change `session_id`
1147
1085
  - `Browser -> Screenshots` lists screenshots created by `browser_screenshot`
1148
- - `Storage` browses `.mcp-xchange` for the active session and can send stored notes/files back into Telegram
1086
+ - `Storage` browses `.mcp-xchange` for the active console and can send stored notes/files back into Telegram
1149
1087
  - `Settings` contains `Info`, `Rename`, `Unpair`, `Back`
1150
- - `Link` creates a mutual partner relationship between two sessions visible to the same Telegram identity
1151
- - `Local` is the Telegram UI wrapper over same-bot partner collaboration
1088
+ - project/collab work is the only supported user-facing collaboration path in Telegram UI
1152
1089
  - `Collab` is the project-based multi-machine collaboration flow
1153
1090
  - inside `Collab -> Project -> Member`, action semantics differ:
1154
1091
  - first row is `Ask | Share`
1155
1092
  - second row is `Live`
1156
- - `Ask` sends a task to the selected member session
1157
- - expected reply route is `member -> current session`
1158
- - `Share` creates a task for the current session
1159
- - expected send route is `current session -> member`
1160
- - `Live` first sends an approval request to the selected member session
1093
+ - `Ask` sends a task to the selected member console
1094
+ - expected reply route is `member -> current console`
1095
+ - `Share` creates a task for the current console
1096
+ - expected send route is `current console -> member`
1097
+ - `Live` first sends an approval request to the selected member console
1161
1098
  - after approval, the requester receives a fresh `Open Live View` button in Telegram
1162
1099
  - partner-note prompt format is:
1163
1100
  - first line = summary
@@ -1165,8 +1102,8 @@ Telegram UI summary:
1165
1102
  - remaining text = full message body
1166
1103
  - if an old project-member menu message becomes stale, clicking it deletes that outdated Telegram message
1167
1104
  - partner-note wake-up means:
1168
- - read `.mcp-xchange/SHARED_INDEX.md`
1169
- - then read the newest partner note
1105
+ - call `list_xchange_records`
1106
+ - then call `get_xchange_record`
1170
1107
  - not `get_telegram_inbox`
1171
1108
 
1172
1109
  Distributed mode scaffold:
@@ -1183,7 +1120,7 @@ Distributed mode scaffold:
1183
1120
  - gateway compares them with canonical gateway `TOOLS.md`
1184
1121
  - mismatch produces `tools_event`
1185
1122
  - client also self-checks after `hello_ack`
1186
- - once linked, agents should use `.mcp-xchange/SHARED_INDEX.md` plus separate files in `.mcp-xchange/shares/` for collaboration
1123
+ - agents should use `list_xchange_records` / `get_xchange_record` plus separate files in `.mcp-xchange/shares/` for collaboration
1187
1124
  - recommended collaboration note kinds are:
1188
1125
  - `share`
1189
1126
  - `question`
@@ -1196,9 +1133,9 @@ Distributed mode scaffold:
1196
1133
  - `Broadcast`
1197
1134
  - `History`
1198
1135
  - `Delete`
1199
- - `History` sends a markdown export of the last 5 Collab events for the current active session
1136
+ - `History` sends a markdown export of the last 5 Collab events for the current active console
1200
1137
 
1201
- Current remaining operational gaps are tracked in [docs/TODO.md](/home/code4bones/Devs/coding/mcp/telegram_mcp/docs/TODO.md).
1138
+ Current remaining operational gaps are tracked in [docs/TODO.md](./docs/TODO.md).
1202
1139
 
1203
1140
  ## `ask_user_telegram`
1204
1141
 
@@ -1228,60 +1165,40 @@ Output:
1228
1165
  - `received_at?`
1229
1166
  - `fallback_used?`
1230
1167
 
1231
- ## Telegram inbox protocol
1168
+ ## Telegram human-message protocol
1232
1169
 
1233
- The inbox may contain new user instructions sent from Telegram.
1170
+ Human Telegram messages are now stored as structured `telegram_message` records in `.mcp-xchange`.
1234
1171
 
1235
- If a paired session has a configured `tmux_target`, the preferred path is event-driven: Telegram stores the message, the service nudges tmux, and the agent then fetches `get_telegram_inbox`.
1172
+ Preferred behavior is event-driven:
1236
1173
 
1237
- If no tmux nudge path exists, use passive inbox checks with `get_telegram_inbox_count`.
1174
+ 1. The human sends a message through the gateway bot.
1175
+ 2. The gateway routes the message to the active console as a `telegram_message` record.
1176
+ 3. The running agent checks `.mcp-xchange` through MCP tools.
1177
+ 4. Read actual content through `list_xchange_records` and `get_xchange_record`.
1238
1178
 
1239
- ## Telegram transition protocol
1179
+ ## Telegram console switching
1240
1180
 
1241
- When the user says they are leaving the workstation and wants to continue through Telegram:
1242
-
1243
- 1. If running inside tmux, obtain full tmux attributes:
1244
-
1245
- ```bash
1246
- tmux display-message -p '#{session_name} #{window_name} #{window_index} #{pane_id} #{pane_index}'
1247
- ```
1248
-
1249
- 2. Call `create_session_pair_code` with these attributes so the session identity is derived distinctly for this agent.
1250
- 3. Complete pairing in Telegram.
1251
- 4. If needed, call `set_tmux_target` only to override or refresh the stored target later.
1252
- 5. Continue work normally.
1253
- 6. If the long-running service nudges the tmux pane with `проверь inbox`, treat that as the signal to fetch the next inbox batch.
1254
- 7. Read actual inbox content only through MCP tools.
1255
-
1256
- The service does not inject Telegram message text into tmux. It only sends the wake-up phrase. Telegram messages remain stored in Redis inbox until the agent explicitly reads and deletes them. Multiple close-together Telegram messages are debounced into a single tmux wake-up.
1257
-
1258
- ## Telegram session switching
1259
-
1260
- The Telegram side supports an active-session context per Telegram identity.
1181
+ The Telegram side supports an active-console context per Telegram identity.
1261
1182
 
1262
1183
  Rules:
1263
1184
 
1264
- - ordinary Telegram messages are stored in the inbox of the currently active session
1265
- - `/menu` opens a menu with all sessions linked to the current Telegram identity
1266
- - selecting a session makes it the new active session
1267
- - the main menu also provides a session-switch entry point
1268
- - the list contains every distinct `session_id` paired to this Telegram identity, so multi-agent setups depend on deriving different session ids during pairing
1269
-
1270
- If tmux nudging is configured, the preferred behavior is event-driven:
1185
+ - ordinary Telegram messages are stored as `telegram_message` records for the currently active console
1186
+ - `/menu` opens a menu with all consoles visible to the current Telegram identity inside the current gateway scope
1187
+ - selecting a console makes it the new active console
1188
+ - the main menu also provides a console-switch entry point
1189
+ - the list reflects currently available gateway-known consoles, not a local pairing catalog
1271
1190
 
1272
- 1. Wait for the tmux nudge.
1273
- 2. Call `get_telegram_inbox`.
1274
- 3. Process the returned batch one message at a time.
1275
- 4. Move to the next message only if the current message did not create a blocker, follow-up question, or execution error.
1276
- 5. If the current message requires clarification or cannot be completed safely, stop batch progression, enter the `ask_user_telegram` branch, and leave the remaining inbox items pending.
1277
- 6. Call `delete_telegram_inbox_message` only for messages that were actually handled.
1278
- 7. If `has_more = true` and the current batch finished cleanly, call `get_telegram_inbox` again for the next batch.
1191
+ 1. Wait for the wake-up or decide to poll explicitly.
1192
+ 2. Call `list_xchange_records`.
1193
+ 3. Select the newest relevant `telegram_message` record with `status = new`.
1194
+ 4. Call `get_xchange_record`.
1195
+ 5. Process the returned record.
1196
+ 6. If the message was handled, call `mark_xchange_record_read`.
1279
1197
 
1280
1198
  Do not add extra diagnostic calls in that path:
1281
1199
 
1282
- - do not call `get_tmux_target` before `get_telegram_inbox`
1283
- - do not call `get_session_context` before `get_telegram_inbox`
1284
- - do not call `get_telegram_inbox_count` before `get_telegram_inbox` when the wake-up already came from tmux
1200
+ - do not call `get_session_context` before `list_xchange_records`
1201
+ - do not invent a separate inbox polling pass when the wake-up already arrived
1285
1202
 
1286
1203
  ## Presence model
1287
1204
 
@@ -1289,19 +1206,19 @@ Current truth:
1289
1206
 
1290
1207
  - gateway can know whether a client node is online through active `ws`
1291
1208
  - gateway also stores `gateway_clients.last_seen_at`
1292
- - this is not the same thing as a live coding-agent heartbeat inside each session
1209
+ - this is not the same thing as a live coding-agent heartbeat inside each console
1293
1210
 
1294
1211
  Rule:
1295
1212
 
1296
- - do not claim that a session agent is definitely `offline` unless a dedicated agent heartbeat exists
1213
+ - do not claim that a console agent is definitely `offline` unless a dedicated agent heartbeat exists
1297
1214
  - today the honest distinction is:
1298
1215
  - client node `online/offline`
1299
- - session bound/unbound
1300
- - tmux target configured/not configured
1216
+ - console visible/not visible
1217
+ - current console context present/absent
1301
1218
 
1302
- If no tmux target is configured, use passive inbox checks:
1219
+ If no wake-up has arrived, use passive record checks:
1303
1220
 
1304
- 1. Call `get_telegram_inbox_count`.
1305
- 2. If `total > 0`, call `get_telegram_inbox`.
1306
- 3. Process messages.
1307
- 4. Call `delete_telegram_inbox_message` for handled items.
1221
+ 1. Call `list_xchange_records`.
1222
+ 2. If there is a new `telegram_message` record, call `get_xchange_record`.
1223
+ 3. Process the message.
1224
+ 4. Call `mark_xchange_record_read` for handled items.