@deadragdoll/tellymcp 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) 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 +226 -376
  5. package/README.md +213 -1184
  6. package/TOOLS.md +320 -377
  7. package/VERSION.md +13 -13
  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 +907 -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 +120 -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/browserOpenTool.js +1 -1
  42. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  43. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +306 -26
  44. package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
  45. package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
  46. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
  47. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
  48. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
  49. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
  50. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
  51. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
  52. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +697 -75
  53. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
  54. package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
  55. package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
  56. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
  57. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
  58. package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
  59. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
  60. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
  61. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
  62. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
  63. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
  64. package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
  65. package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
  66. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
  67. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
  68. package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
  69. package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
  70. package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
  72. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
  73. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +143 -42
  74. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +139 -38
  75. package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
  76. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
  77. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +69 -70
  78. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
  79. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +444 -7093
  80. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
  81. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
  82. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +149 -0
  83. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +642 -0
  84. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
  85. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
  86. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
  87. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
  88. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
  89. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
  90. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
  91. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
  92. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
  93. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
  94. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
  95. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
  96. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
  97. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
  98. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +65 -0
  99. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
  100. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
  101. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
  102. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
  103. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
  104. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +108 -0
  105. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +665 -0
  114. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +226 -0
  115. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
  116. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
  117. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
  118. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
  119. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
  120. package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
  121. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
  122. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
  123. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
  124. package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
  125. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +409 -0
  126. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
  127. package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
  128. package/dist/services/features/telegram-mcp/standalone-http.service.js +12 -0
  129. package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
  130. package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
  131. package/dist/services/features/telegram-mcp/tools-sync.service.js +15 -1
  132. package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
  133. package/docs/STANDALONE-ru.md +172 -0
  134. package/docs/STANDALONE.md +172 -0
  135. package/package.json +10 -5
  136. package/scripts/build-package-artifact.sh +27 -0
  137. package/scripts/deploy-gateway.sh +64 -0
  138. package/scripts/deploy-onebot-branch.sh +27 -0
  139. package/scripts/postinstall.js +11 -36
  140. package/STANDALONE-ru.md +0 -274
  141. package/STANDALONE.md +0 -274
  142. package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
  143. package/dist/services/features/telegram-mcp/pair.service.js +0 -33
  144. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
  145. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
  146. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
  147. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
  148. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
  149. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
  150. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
  151. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
  152. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
  153. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
  154. 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
 
@@ -38,8 +38,27 @@ Browser runtime rule:
38
38
  - If browser tools fail because the Playwright browser runtime is missing, install it with `tellymcp browser install`.
39
39
  - Do not stop at the installation error itself. Install the browser runtime first, then retry the browser tool.
40
40
 
41
+ Terminal prompt scan rules:
42
+
43
+ - gateway prompt scan is driven by live client lifecycle, not by manual menu entry
44
+ - the scanner works on the tail of the captured terminal buffer
45
+ - the main blocker signal is:
46
+ - a contiguous numbered choice block like `1.`, `2.`, `3.`
47
+ - nearby action-hint language such as `press`, `input`, `choose`, `enter`, `esc`, `yes`, `no`
48
+ - exact footer text is helpful but not required
49
+ - when a blocker notice contains inline buttons, those buttons intentionally send only:
50
+ - a digit `1..N`
51
+ - `Enter`
52
+ - `Esc`
53
+ - do not assume marker navigation
54
+ - do not reinterpret those buttons as alternate hotkeys like `(y)` or `(p)`
55
+
41
56
  Collaboration tools:
42
57
 
58
+ - `list_gateway_sessions`
59
+ - `list_xchange_records`
60
+ - `get_xchange_record`
61
+ - `mark_xchange_record_read`
43
62
  - `send_partner_note`
44
63
  - `send_partner_file`
45
64
 
@@ -47,131 +66,42 @@ Utility tools:
47
66
 
48
67
  - `refresh_tools_markdown`
49
68
 
50
- ## `create_session_pair_code`
51
-
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:
75
-
76
- - `session_id`
77
- - `code`
78
- - `expires_at`
79
- - `status`
80
- - `status_message`
81
- - `telegram_link_hint?`
69
+ ## Console model
82
70
 
83
- Behavior:
71
+ Gateway-first runtime model:
84
72
 
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
73
+ - agents register themselves on the gateway automatically through `GATEWAY_TOKEN`
74
+ - Telegram no longer links sessions with pair codes
75
+ - `/menu` in the gateway bot shows available remote consoles directly
76
+ - one running agent console is one logical session/console target
93
77
 
94
78
  Required agent practice:
95
79
 
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`
80
+ - when the user asks to contact another agent, inspect consoles through `list_gateway_sessions`
81
+ - when the user asks to work with Telegram-linked human interaction, use the current console `session_id` explicitly
82
+ - in gateway mode, `session_id` means the live console id from `-s`
83
+ - do not use workspace-derived ids like `project-abc12345` for gateway routing
84
+ - do not use `cwd` to route to a console through the gateway
85
+ - 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
86
+ - do not ask the user for the live console id when it can be resolved from `list_gateway_sessions`
87
+ - assume gateway is the only user-facing control plane
88
+ - do not mention pair codes, `/link`, admin menus, or session pairing unless the user is explicitly asking about legacy behavior
89
+
90
+ Preferred order for cross-console work:
91
+
92
+ 1. Call `list_gateway_sessions`.
93
+ 2. Choose the correct target by `session_label`, `node_id`, `client_label`, or canonical `session_id`.
94
+ 3. Use:
95
+ - `send_partner_note`
96
+ - `send_partner_file`
97
+ - browser tools
98
+ with explicit `session_id` for the current console or explicit target routing fields for another console.
169
99
 
170
100
  ## `set_session_context`
171
101
 
172
102
  Purpose:
173
103
 
174
- - Save compact reusable session context in Redis.
104
+ - Save compact reusable console context.
175
105
 
176
106
  Input:
177
107
 
@@ -189,18 +119,19 @@ Output:
189
119
  - `session_id`
190
120
  - `updated_at`
191
121
  - `has_binding`
122
+ Legacy field name. Read it as: whether this console currently has an active Telegram route through the gateway.
192
123
 
193
124
  ## `rename_session`
194
125
 
195
126
  Purpose:
196
127
 
197
- - Rename the session title/label only.
128
+ - Rename only the human-readable console title/label.
198
129
 
199
130
  Rules:
200
131
 
201
132
  - this changes only the human-readable title
202
133
  - it does not change `session_id`
203
- - it does not change pairing, tmux target, inbox, or saved context
134
+ - it does not change routing or saved context
204
135
 
205
136
  Input:
206
137
 
@@ -214,57 +145,76 @@ Output:
214
145
  - `session_label`
215
146
  - `updated_at`
216
147
 
217
- ## `set_tmux_target`
148
+ ## `get_session_context`
218
149
 
219
150
  Purpose:
220
151
 
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.
152
+ - Read saved console context and routing status.
222
153
 
223
154
  Recommended use:
224
155
 
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
- ```
156
+ - setup/debug only
157
+ - use this while diagnosing state or inspecting saved metadata
158
+ - do not call this in the normal processing path unless you are diagnosing state
235
159
 
236
160
  Input:
237
161
 
238
162
  - `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
163
 
246
164
  Output:
247
165
 
248
166
  - `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?`
167
+ - `exists`
168
+ - `has_binding`
169
+ Legacy field name. Read it as: whether this console is currently reachable from Telegram through the gateway.
255
170
  - `status_message`
171
+ - `context?`
172
+ - `binding?`
173
+ Legacy field name. If present, this is the current Telegram route metadata for the console.
174
+ - `terminal?`
175
+ Terminal runtime metadata for the console.
256
176
 
257
- ## `get_tmux_target`
177
+ ## `refresh_tools_markdown`
258
178
 
259
179
  Purpose:
260
180
 
261
- - Check whether a tmux target is configured for the current session and when it was last nudged.
181
+ - Download the canonical `TOOLS.md` from the configured gateway.
182
+ - Return the canonical instructions in a hash-based form so the agent can refresh without mandatory local file writes.
183
+
184
+ Input:
262
185
 
263
- Recommended use:
186
+ - `session_id`
187
+ - `known_hash?`
264
188
 
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
189
+ Output:
190
+
191
+ - `source`
192
+ - `session_id?`
193
+ - `current_hash`
194
+ - `changed`
195
+ - `content?`
196
+ - `bytes`
197
+
198
+ Behavior:
199
+
200
+ - if `GATEWAY_PUBLIC_URL` is configured, the tool fetches `GET /api/gateway/tools-md`
201
+ - if no gateway is configured, the tool falls back to the installed package copy
202
+ - the canonical source is the installed gateway package copy, not an arbitrary current working directory
203
+ - in gateway mode, routing to the target console is done only by explicit canonical `session_id = client_uuid:local_session_id`
204
+ - `cwd` is workspace metadata for the target console after routing succeeds; it is not a routing key
205
+ - if the live console id is not already known, call `list_gateway_sessions` first and use `session_id`
206
+ - prefer hash-based refresh:
207
+ - pass `known_hash` from the last applied TOOLS state
208
+ - if `changed=false`, keep current instructions
209
+ - if `changed=true`, read and apply returned `content`
210
+ - there is no local file-save mode in the normal flow
211
+ - do not create or rely on workspace `TOOLS.md` copies
212
+
213
+ ## `clear_session_context`
214
+
215
+ Purpose:
216
+
217
+ - Remove saved session context and related per-session state for the console.
268
218
 
269
219
  Input:
270
220
 
@@ -272,79 +222,162 @@ Input:
272
222
 
273
223
  Output:
274
224
 
225
+ - `cleared`
275
226
  - `session_id`
276
- - `configured`
277
- - `tmux_target?`
278
- - `tmux_session_name?`
279
- - `last_nudge_at?`
280
- - `status_message`
227
+ - `cleared_pairing`
228
+ Compatibility field name. Treat it as legacy cleanup metadata, not as an instruction to use pairing.
281
229
 
282
- ## `get_session_context`
230
+ ## `send_partner_note`
231
+
232
+ ## `list_gateway_sessions`
283
233
 
284
234
  Purpose:
285
235
 
286
- - Read saved session context and Telegram binding status.
236
+ - List all consoles currently known to the configured gateway.
237
+ - Merge:
238
+ - connected consoles from gateway WS presence
239
+ - registered project consoles from the gateway database
240
+ - Use this before direct cross-console communication outside one collab project.
241
+ - Use this to resolve the authoritative live console id for other gateway-routed tools.
287
242
 
288
- Recommended use:
243
+ Input:
289
244
 
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
245
+ - `client_uuid?`
246
+ - `connected_only?`
247
+
248
+ Output:
249
+
250
+ - `total`
251
+ - `sessions[]`
252
+ - `session_id`
253
+ - `local_session_id`
254
+ - `client_uuid`
255
+ - `local_session_id`
256
+ - `session_label?`
257
+ - `client_label?`
258
+ - `telegram_username?`
259
+ - `telegram_display_name?`
260
+ - `bot_username?`
261
+ - `node_id?`
262
+ - `package_version?`
263
+ - `project_uuids?`
264
+ - `project_names?`
265
+ - `connected`
266
+ - `registered`
267
+
268
+ Rules:
269
+
270
+ - 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
271
+ - for direct gateway-wide routing, resolve the target from this list and then call:
272
+ - `send_partner_note`
273
+ - or `send_partner_file`
274
+ - in that direct mode, pass:
275
+ - `target_client_uuid`
276
+ - `target_local_session_id`
277
+ - do not invent `target_session_id` for direct gateway-wide routing
278
+ - prefer connected sessions for direct gateway-wide messaging
279
+ - if a session is not connected, do not assume direct delivery will succeed
280
+
281
+ ## `list_xchange_records`
282
+
283
+ Purpose:
284
+
285
+ - List structured `.mcp-xchange` records from the local sqlite store for the current session.
286
+ - Use this as the first lookup path for partner notes, local handoffs, unread collaboration items, and follow-up work.
293
287
 
294
288
  Input:
295
289
 
296
290
  - `session_id?`
291
+ - `status?`
292
+ - `new`
293
+ - `read`
294
+ - `archived`
295
+ - `category?`
296
+ - `partner_note`
297
+ - `local_handoff`
298
+ - `direction?`
299
+ - `incoming`
300
+ - `outgoing`
301
+ - `local`
302
+ - `limit?`
297
303
 
298
304
  Output:
299
305
 
300
306
  - `session_id`
301
- - `exists`
302
- - `has_binding`
303
- - `status_message`
304
- - `context?`
305
- - `binding?`
306
- - `tmux?`
307
+ - `total`
308
+ - `records`
307
309
 
308
- ## `refresh_tools_markdown`
310
+ Each record includes:
311
+
312
+ - `record_id`
313
+ - `category`
314
+ - `direction`
315
+ - `status`
316
+ - `kind?`
317
+ - `summary`
318
+ - `action_desc`
319
+ - `tools`
320
+ - `attachments`
321
+ - `source_*` and `target_*` routing fields when available
322
+ - `project_uuid?`
323
+ - `project_name?`
324
+ - `requires_reply?`
325
+ - `expected_reply?`
326
+ - `in_reply_to?`
327
+ - `created_at`
328
+ - `updated_at`
329
+ - `read_at?`
330
+
331
+ Rules:
332
+
333
+ - use this first when the session is nudged for partner collaboration or local handoff work
334
+ - prefer `status = "new"` for fresh work
335
+ - after selecting the relevant record, call `get_xchange_record`
336
+
337
+ ## `get_xchange_record`
309
338
 
310
339
  Purpose:
311
340
 
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.
341
+ - Read one structured `.mcp-xchange` record in full.
342
+ - This gives the canonical `body_text`, `action_desc`, `tools`, attachments, and routing metadata for the next step.
314
343
 
315
344
  Input:
316
345
 
317
- - `save_locally?`
346
+ - `session_id?`
347
+ - `record_id`
318
348
 
319
349
  Output:
320
350
 
321
- - `source`
322
- - `saved`
323
- - `bytes`
324
- - `path?`
351
+ - `session_id`
352
+ - `record`
325
353
 
326
- Behavior:
354
+ Rules:
327
355
 
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
356
+ - after `list_xchange_records`, call this on the chosen `record_id`
357
+ - trust `action_desc` and `tools` over old markdown-index habits
358
+ - use `body_text` as the structured note content; only open the note file directly if you need the raw markdown artifact
332
359
 
333
- ## `clear_session_context`
360
+ ## `mark_xchange_record_read`
334
361
 
335
362
  Purpose:
336
363
 
337
- - Remove saved session context and Telegram pairing for the session.
364
+ - Mark a structured `.mcp-xchange` record as read after consuming it.
338
365
 
339
366
  Input:
340
367
 
341
368
  - `session_id?`
369
+ - `record_id`
342
370
 
343
371
  Output:
344
372
 
345
- - `cleared`
346
373
  - `session_id`
347
- - `cleared_pairing`
374
+ - `record_id`
375
+ - `updated`
376
+
377
+ Rules:
378
+
379
+ - do this after you have consumed `body_text`, attachments, and next-step instructions
380
+ - do not mark a record read before you have actually processed it
348
381
 
349
382
  ## `send_partner_note`
350
383
 
@@ -352,14 +385,16 @@ Purpose:
352
385
 
353
386
  - Send a structured collaboration note to another session.
354
387
  - Write a note file into the partner workspace under `.mcp-xchange/shares/`.
355
- - Append a line to the partner `.mcp-xchange/SHARED_INDEX.md`.
388
+ - Create a structured xchange record in the partner sqlite store.
356
389
  - 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.
390
+ - Create a structured xchange wake-up for the partner agent through the normal gateway delivery path.
358
391
 
359
392
  Input:
360
393
 
361
394
  - `session_id?`
362
395
  - `target_session_id?`
396
+ - `target_client_uuid?`
397
+ - `target_local_session_id?`
363
398
  - `project_uuid?`
364
399
  - `kind`
365
400
  - `share`
@@ -381,9 +416,10 @@ Output:
381
416
  - `kind`
382
417
  - `share_id`
383
418
  - `note_path`
384
- - `share_index_path`
419
+ - `xchange_record_id`
385
420
  - `copied_artifacts`
386
421
  - `inbox_message_id`
422
+ Legacy compatibility field name for delivery bookkeeping.
387
423
  - `requires_reply`
388
424
 
389
425
  Required agent practice:
@@ -400,15 +436,22 @@ Required agent practice:
400
436
  How to find the partner correctly:
401
437
 
402
438
  - never guess the target session from labels, menu text, or memory
403
- - there are two valid targeting modes:
439
+ - there are three valid targeting modes:
404
440
  - local linked mode:
405
441
  - call `get_session_context`
406
442
  - use `context.linked_session_id`
407
443
  - project / collab mode:
408
444
  - use the explicit `target_session_id` that came from the project note, Telegram prompt, or task context
409
445
  - if available, also pass `project_uuid`
446
+ - direct gateway-wide mode:
447
+ - call `list_gateway_sessions`
448
+ - resolve the exact target from the returned `client_uuid` + `local_session_id`
449
+ - pass them as:
450
+ - `target_client_uuid`
451
+ - `target_local_session_id`
410
452
  - for project replies, do not fall back to `linked_session_id`
411
453
  - if `target_session_id` is explicitly known, it has priority over any linked partner
454
+ - 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
455
  - if neither `target_session_id` nor `linked_session_id` is available:
413
456
  - do not retry blindly
414
457
  - tell the user the target session is unknown
@@ -419,6 +462,7 @@ Minimal safe sequence:
419
462
  1. Call `get_session_context`.
420
463
  2. Resolve the target:
421
464
  - prefer explicit `target_session_id` for project/collab work
465
+ - for gateway-wide direct work, use explicit `target_client_uuid` + `target_local_session_id`
422
466
  - otherwise use `linked_session_id` for local partner work
423
467
  3. Decide the correct note kind: `question`, `reply`, `share`, `request`, or `handoff`.
424
468
  4. Call `send_partner_note`.
@@ -445,11 +489,14 @@ Reply rule for project asks:
445
489
  - `Reply message_uuid: ...`
446
490
  - `Reply target_session_id: ...`
447
491
  - `Reply project_uuid: ...`
492
+ - `Reply target_client_uuid: ...`
493
+ - `Reply target_local_session_id: ...`
448
494
  or a `Reply Params` section with the same data
449
495
  - then reply with those exact values
450
496
  - if `in_reply_to` is available, prefer `Reply message_uuid`
451
497
  - if only the note `share_id` is available, gateway now also accepts that value in `in_reply_to`
452
498
  - do not use `linked_session_id` for that reply
499
+ - if direct reply params contain `target_client_uuid` + `target_local_session_id`, do not replace them with `target_session_id`
453
500
  - if the note contains an `Action Required` section, treat it as mandatory execution guidance, not as optional commentary
454
501
  - do not stop after local analysis when `Action Required` says to reply
455
502
  - when `Reply Params` are present, prefer an explicit `send_partner_note(...)` call with those exact values
@@ -489,6 +536,8 @@ Input:
489
536
 
490
537
  - `session_id?`
491
538
  - `target_session_id?`
539
+ - `target_client_uuid?`
540
+ - `target_local_session_id?`
492
541
  - `project_uuid?`
493
542
  - `cwd?`
494
543
  - `file_path`
@@ -515,10 +564,12 @@ Minimal file-delivery rule:
515
564
  Routing priority:
516
565
 
517
566
  1. explicit `Reply target_session_id`
518
- 2. explicit `target_session_id` from the current project/task context
519
- 3. local `linked_session_id`
567
+ 2. explicit `Reply target_client_uuid` + `Reply target_local_session_id`
568
+ 3. explicit `target_session_id` from the current project/task context
569
+ 4. explicit `target_client_uuid` + `target_local_session_id` from `list_gateway_sessions`
570
+ 5. local `linked_session_id`
520
571
 
521
- For project/collab traffic, step 3 is fallback only when no explicit target exists.
572
+ For project/collab traffic, step 5 is fallback only when no explicit target exists.
522
573
 
523
574
  Canonical example for a project reply:
524
575
 
@@ -536,19 +587,22 @@ Canonical example for a project reply:
536
587
 
537
588
  How the receiving agent must react:
538
589
 
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`
590
+ - wake-ups now point to the unified `.mcp-xchange` flow
591
+ - if the wake-up says things like:
592
+ - `проверь xchange records`
593
+ - `telegram_message`
594
+ - `partner_note`
595
+ then do not start with a legacy inbox-specific tool
545
596
  - 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
597
+ 1. call `list_xchange_records`
598
+ 2. identify the newest relevant record by category:
599
+ - `telegram_message` if the sender is a human from Telegram
600
+ - `partner_note` if the sender is another agent
601
+ 3. call `get_xchange_record`
602
+ 4. read `body_text`, `action_desc`, `tools`, and any attachments
603
+ - reply according to the record category:
604
+ - `telegram_message` -> answer with `notify_telegram`
605
+ - `partner_note` -> answer with `send_partner_note`
552
606
 
553
607
  What to do after reading the note:
554
608
 
@@ -603,8 +657,8 @@ Note contract:
603
657
 
604
658
  - the service writes one note per message to:
605
659
  - `.mcp-xchange/shares/<share_id>.md`
606
- - the partner index is append-only:
607
- - `.mcp-xchange/SHARED_INDEX.md`
660
+ - the structured source of truth is the local sqlite xchange store:
661
+ - `.mcp-xchange/xchange.sqlite3`
608
662
  - artifacts are copied into:
609
663
  - `.mcp-xchange/shares/files/<share_id>/...`
610
664
 
@@ -675,107 +729,6 @@ Output:
675
729
  - `sent`
676
730
  - `message_id?`
677
731
 
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
732
  ## `browser_open`
780
733
 
781
734
  Purpose:
@@ -787,6 +740,8 @@ Input:
787
740
 
788
741
  - `session_id?`
789
742
  - `url`
743
+ - `width?`
744
+ - `height?`
790
745
  - `wait_until?`
791
746
  - `reset_context?`
792
747
 
@@ -797,12 +752,19 @@ Output:
797
752
  - `created_context`
798
753
  - `url`
799
754
  - `title?`
755
+ - `viewport_width?`
756
+ - `viewport_height?`
800
757
 
801
758
  Notes:
802
759
 
803
760
  - each session gets its own isolated browser context and page
804
761
  - call this first before reading console, DOM, styles, or screenshots
805
762
  - `url` may be an absolute URL, or a relative path when `BROWSER_ADDRESS` is configured
763
+ - in headed mode the browser window is started maximized by default
764
+ - in headed mode a fresh browser context is created without a fixed viewport unless you explicitly pass `width` and `height`
765
+ - if you want page content to grow and shrink together with the outer browser window, do not pass `width` and `height`
766
+ - if you pass viewport size, pass both `width` and `height` together
767
+ - use explicit `width` and `height` when the task depends on a specific responsive breakpoint or working area
806
768
 
807
769
  ## `browser_console`
808
770
 
@@ -1134,30 +1096,31 @@ Output:
1134
1096
 
1135
1097
  Telegram UI summary:
1136
1098
 
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:
1099
+ - `/menu` is the only top-level Telegram command for console navigation
1100
+ - root menu shows one console button per row
1101
+ - root menu reflects terminal bridge status for available consoles
1102
+ - console menu uses:
1141
1103
  - `Live | Content | Browser`
1142
- - `Local | Collab`
1143
- - `Inbox | Storage | Settings`
1104
+ - `Collab`
1105
+ - `Storage | Settings`
1144
1106
  - `Back`
1145
- - default logical session identity comes from `.mcpsession.json` in the workspace
1146
- - changing tmux session/window/pane does not change `session_id`
1107
+ - default logical console identity comes from `.mcpsession.json` in the workspace or explicit `-s`
1108
+ - terminal runtime metadata does not change `session_id`
1147
1109
  - `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
1110
+ - `Storage` and `Screenshots` are relay-aware on the gateway
1111
+ - for relay consoles they read file metadata through gateway routes, not through the gateway filesystem
1112
+ - `Storage` browses `.mcp-xchange` for the active console and can send stored notes/files back into Telegram
1149
1113
  - `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
1114
+ - project/collab work is the only supported user-facing collaboration path in Telegram UI
1152
1115
  - `Collab` is the project-based multi-machine collaboration flow
1153
1116
  - inside `Collab -> Project -> Member`, action semantics differ:
1154
1117
  - first row is `Ask | Share`
1155
1118
  - 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
1119
+ - `Ask` sends a task to the selected member console
1120
+ - expected reply route is `member -> current console`
1121
+ - `Share` creates a task for the current console
1122
+ - expected send route is `current console -> member`
1123
+ - `Live` first sends an approval request to the selected member console
1161
1124
  - after approval, the requester receives a fresh `Open Live View` button in Telegram
1162
1125
  - partner-note prompt format is:
1163
1126
  - first line = summary
@@ -1165,8 +1128,8 @@ Telegram UI summary:
1165
1128
  - remaining text = full message body
1166
1129
  - if an old project-member menu message becomes stale, clicking it deletes that outdated Telegram message
1167
1130
  - partner-note wake-up means:
1168
- - read `.mcp-xchange/SHARED_INDEX.md`
1169
- - then read the newest partner note
1131
+ - call `list_xchange_records`
1132
+ - then call `get_xchange_record`
1170
1133
  - not `get_telegram_inbox`
1171
1134
 
1172
1135
  Distributed mode scaffold:
@@ -1183,7 +1146,7 @@ Distributed mode scaffold:
1183
1146
  - gateway compares them with canonical gateway `TOOLS.md`
1184
1147
  - mismatch produces `tools_event`
1185
1148
  - 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
1149
+ - agents should use `list_xchange_records` / `get_xchange_record` plus separate files in `.mcp-xchange/shares/` for collaboration
1187
1150
  - recommended collaboration note kinds are:
1188
1151
  - `share`
1189
1152
  - `question`
@@ -1196,9 +1159,9 @@ Distributed mode scaffold:
1196
1159
  - `Broadcast`
1197
1160
  - `History`
1198
1161
  - `Delete`
1199
- - `History` sends a markdown export of the last 5 Collab events for the current active session
1162
+ - `History` sends a markdown export of the last 5 Collab events for the current active console
1200
1163
 
1201
- Current remaining operational gaps are tracked in [docs/TODO.md](/home/code4bones/Devs/coding/mcp/telegram_mcp/docs/TODO.md).
1164
+ Current remaining operational gaps are tracked in [docs/TODO.md](./docs/TODO.md).
1202
1165
 
1203
1166
  ## `ask_user_telegram`
1204
1167
 
@@ -1228,60 +1191,40 @@ Output:
1228
1191
  - `received_at?`
1229
1192
  - `fallback_used?`
1230
1193
 
1231
- ## Telegram inbox protocol
1194
+ ## Telegram human-message protocol
1232
1195
 
1233
- The inbox may contain new user instructions sent from Telegram.
1196
+ Human Telegram messages are now stored as structured `telegram_message` records in `.mcp-xchange`.
1234
1197
 
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`.
1198
+ Preferred behavior is event-driven:
1236
1199
 
1237
- If no tmux nudge path exists, use passive inbox checks with `get_telegram_inbox_count`.
1200
+ 1. The human sends a message through the gateway bot.
1201
+ 2. The gateway routes the message to the active console as a `telegram_message` record.
1202
+ 3. The running agent checks `.mcp-xchange` through MCP tools.
1203
+ 4. Read actual content through `list_xchange_records` and `get_xchange_record`.
1238
1204
 
1239
- ## Telegram transition protocol
1205
+ ## Telegram console switching
1240
1206
 
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.
1207
+ The Telegram side supports an active-console context per Telegram identity.
1261
1208
 
1262
1209
  Rules:
1263
1210
 
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:
1211
+ - ordinary Telegram messages are stored as `telegram_message` records for the currently active console
1212
+ - `/menu` opens a menu with all consoles visible to the current Telegram identity inside the current gateway scope
1213
+ - selecting a console makes it the new active console
1214
+ - the main menu also provides a console-switch entry point
1215
+ - the list reflects currently available gateway-known consoles, not a local pairing catalog
1271
1216
 
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.
1217
+ 1. Wait for the wake-up or decide to poll explicitly.
1218
+ 2. Call `list_xchange_records`.
1219
+ 3. Select the newest relevant `telegram_message` record with `status = new`.
1220
+ 4. Call `get_xchange_record`.
1221
+ 5. Process the returned record.
1222
+ 6. If the message was handled, call `mark_xchange_record_read`.
1279
1223
 
1280
1224
  Do not add extra diagnostic calls in that path:
1281
1225
 
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
1226
+ - do not call `get_session_context` before `list_xchange_records`
1227
+ - do not invent a separate inbox polling pass when the wake-up already arrived
1285
1228
 
1286
1229
  ## Presence model
1287
1230
 
@@ -1289,19 +1232,19 @@ Current truth:
1289
1232
 
1290
1233
  - gateway can know whether a client node is online through active `ws`
1291
1234
  - gateway also stores `gateway_clients.last_seen_at`
1292
- - this is not the same thing as a live coding-agent heartbeat inside each session
1235
+ - this is not the same thing as a live coding-agent heartbeat inside each console
1293
1236
 
1294
1237
  Rule:
1295
1238
 
1296
- - do not claim that a session agent is definitely `offline` unless a dedicated agent heartbeat exists
1239
+ - do not claim that a console agent is definitely `offline` unless a dedicated agent heartbeat exists
1297
1240
  - today the honest distinction is:
1298
1241
  - client node `online/offline`
1299
- - session bound/unbound
1300
- - tmux target configured/not configured
1242
+ - console visible/not visible
1243
+ - current console context present/absent
1301
1244
 
1302
- If no tmux target is configured, use passive inbox checks:
1245
+ If no wake-up has arrived, use passive record checks:
1303
1246
 
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.
1247
+ 1. Call `list_xchange_records`.
1248
+ 2. If there is a new `telegram_message` record, call `get_xchange_record`.
1249
+ 3. Process the message.
1250
+ 4. Call `mark_xchange_record_read` for handled items.