@deadragdoll/tellymcp 0.0.13 → 0.0.14

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 (64) hide show
  1. package/.env.example.client +5 -1
  2. package/.env.example.gateway +16 -1
  3. package/CHANGELOG.md +30 -0
  4. package/README-ru.md +14 -0
  5. package/README.md +14 -0
  6. package/TOOLS.md +182 -10
  7. package/config/templates/env.both.template +15 -2
  8. package/config/templates/env.client.template +5 -2
  9. package/config/templates/env.gateway.template +15 -2
  10. package/dist/cli.js +28 -1
  11. package/dist/services/features/telegram-mcp/browser.service.js +18 -0
  12. package/dist/services/features/telegram-mcp/file-content.service.js +94 -0
  13. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +5 -1
  14. package/dist/services/features/telegram-mcp/gateway-socket.service.js +43 -11
  15. package/dist/services/features/telegram-mcp/mcp-http.service.js +1 -0
  16. package/dist/services/features/telegram-mcp/mcp-server.service.js +18 -0
  17. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +9 -1
  18. package/dist/services/features/telegram-mcp/src/app/config/env.js +119 -2
  19. package/dist/services/features/telegram-mcp/src/app/http.js +139 -99
  20. package/dist/services/features/telegram-mcp/src/app/oauthFacade.js +642 -0
  21. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +151 -170
  22. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +96 -99
  23. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +62 -19
  24. package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachActiveTabTool.js +28 -0
  25. package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachTabTool.js +28 -0
  26. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDetachTabTool.js +28 -0
  27. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListAttachedInstancesTool.js +1 -1
  28. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListTabsTool.js +1 -1
  29. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +410 -27
  30. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/browserRecordingBundle.js +37 -3
  31. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachRegistry.js +7 -6
  32. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachServer.js +214 -37
  33. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/types.js +186 -0
  34. package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +2 -0
  35. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +6 -3
  36. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +4 -1
  37. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +33 -35
  38. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileListTool.js +33 -0
  39. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileService.js +327 -0
  40. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileTool.js +81 -0
  41. package/dist/services/features/telegram-mcp/src/features/file-content/model/temporaryFileLinkStore.js +307 -0
  42. package/dist/services/features/telegram-mcp/src/features/file-content/model/workspaceFilePolicy.js +115 -0
  43. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +5 -1
  44. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +3 -0
  45. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +6 -3
  46. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +29 -6
  47. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +100 -2
  48. package/dist/services/features/telegram-mcp/src/shared/lib/bodyLimits.js +63 -0
  49. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayAuth.js +13 -0
  50. package/dist/services/features/telegram-mcp/src/shared/lib/time/localTimestamp.js +21 -0
  51. package/docs/CHAT_CONNECTOR.md +134 -0
  52. package/docs/STANDALONE-ru.md +13 -0
  53. package/docs/STANDALONE.md +13 -0
  54. package/package.json +5 -3
  55. package/packages/chrome-attach-extension/dist/background.js +572 -163
  56. package/packages/chrome-attach-extension/dist/manifest.json +2 -1
  57. package/packages/chrome-attach-extension/dist/options.js +15 -2
  58. package/packages/chrome-attach-extension/dist/recorder-content.js +14 -1
  59. package/packages/chrome-attach-extension/dist/recorder-page.js +34 -18
  60. package/packages/firefox-attach-extension/dist/background.js +413 -33
  61. package/packages/firefox-attach-extension/dist/manifest.json +0 -12
  62. package/packages/firefox-attach-extension/dist/options.js +14 -1
  63. package/packages/firefox-attach-extension/dist/recorder-content.js +14 -1
  64. package/packages/firefox-attach-extension/dist/recorder-page.js +34 -18
@@ -124,27 +124,42 @@ function normalizeTelegramWebAppInitData(rawInitData) {
124
124
  }
125
125
  return normalized.trim();
126
126
  }
127
- function normalizeUnsafeUser(user) {
128
- if (!user || typeof user !== "object" || typeof user.id !== "number") {
127
+ function normalizeTelegramWebAppUser(user) {
128
+ if (!user || typeof user !== "object") {
129
+ return null;
130
+ }
131
+ const record = user;
132
+ if (typeof record.id !== "number" ||
133
+ !Number.isSafeInteger(record.id) ||
134
+ record.id <= 0) {
129
135
  return null;
130
136
  }
131
137
  return {
132
- id: user.id,
133
- ...(typeof user.first_name === "string" ? { first_name: user.first_name } : {}),
134
- ...(typeof user.last_name === "string" ? { last_name: user.last_name } : {}),
135
- ...(typeof user.username === "string" ? { username: user.username } : {}),
136
- ...(typeof user.language_code === "string"
137
- ? { language_code: user.language_code }
138
+ id: record.id,
139
+ ...(typeof record.first_name === "string"
140
+ ? { first_name: record.first_name }
141
+ : {}),
142
+ ...(typeof record.last_name === "string"
143
+ ? { last_name: record.last_name }
144
+ : {}),
145
+ ...(typeof record.username === "string"
146
+ ? { username: record.username }
147
+ : {}),
148
+ ...(typeof record.language_code === "string"
149
+ ? { language_code: record.language_code }
150
+ : {}),
151
+ ...(typeof record.photo_url === "string"
152
+ ? { photo_url: record.photo_url }
138
153
  : {}),
139
- ...(typeof user.photo_url === "string" ? { photo_url: user.photo_url } : {}),
140
154
  };
141
155
  }
142
- function buildOfficialRawValidation(rawInitData, botToken) {
156
+ function validateOfficialRawHash(rawInitData, botToken) {
143
157
  const params = new URLSearchParams(rawInitData);
144
- const receivedHash = params.get("hash");
145
- if (!receivedHash) {
146
- return null;
158
+ const receivedHashes = params.getAll("hash");
159
+ if (receivedHashes.length !== 1 || !receivedHashes[0]) {
160
+ throw new Error("Telegram WebApp initData hash validation failed.");
147
161
  }
162
+ const receivedHash = receivedHashes[0];
148
163
  const checkString = [...params.entries()]
149
164
  .filter(([key, value]) => key !== "hash" && value !== undefined)
150
165
  .sort((left, right) => left[0].localeCompare(right[0]))
@@ -158,83 +173,86 @@ function buildOfficialRawValidation(rawInitData, botToken) {
158
173
  .digest("hex");
159
174
  const matches = computed.length === receivedHash.length &&
160
175
  (0, node_crypto_1.timingSafeEqual)(Buffer.from(computed, "utf8"), Buffer.from(receivedHash, "utf8"));
161
- return {
162
- checkString,
163
- computedHash: computed,
164
- providedHash: receivedHash,
165
- matches,
166
- };
176
+ if (!matches) {
177
+ throw new Error("Telegram WebApp initData hash validation failed.");
178
+ }
179
+ return params;
167
180
  }
168
- function buildUserFieldsValidation(unsafe, botToken) {
169
- if (!unsafe) {
170
- return null;
181
+ function readSignedParam(params, key, required) {
182
+ const values = params.getAll(key);
183
+ if (values.length > 1) {
184
+ throw new Error(`Telegram WebApp initData contains duplicate ${key}.`);
171
185
  }
172
- const user = normalizeUnsafeUser(unsafe.user);
173
- const authDateValue = typeof unsafe.auth_date === "number" || typeof unsafe.auth_date === "string"
174
- ? unsafe.auth_date
175
- : undefined;
176
- const receivedHash = typeof unsafe.hash === "string" && unsafe.hash.length > 0
177
- ? unsafe.hash
186
+ const value = values[0];
187
+ if (required && (value === undefined || value.length === 0)) {
188
+ throw new Error(`Telegram WebApp initData is missing ${key}.`);
189
+ }
190
+ return value;
191
+ }
192
+ function parseSignedUser(value) {
193
+ let parsed;
194
+ try {
195
+ parsed = JSON.parse(value);
196
+ }
197
+ catch {
198
+ throw new Error("Telegram WebApp signed user is malformed.");
199
+ }
200
+ const user = normalizeTelegramWebAppUser(parsed);
201
+ if (!user) {
202
+ throw new Error("Telegram WebApp signed user is invalid.");
203
+ }
204
+ return user;
205
+ }
206
+ function assertUnsafeDataMatchesSigned(unsafe, signed) {
207
+ const unsafeUser = normalizeTelegramWebAppUser(unsafe.user);
208
+ if (!unsafeUser ||
209
+ JSON.stringify(unsafeUser) !== JSON.stringify(signed.user)) {
210
+ throw new Error("Telegram WebApp unsafe user does not match signed initData.");
211
+ }
212
+ const unsafeAuthDate = typeof unsafe.auth_date === "number" || typeof unsafe.auth_date === "string"
213
+ ? String(unsafe.auth_date)
178
214
  : undefined;
179
- if (!user || authDateValue === undefined || !receivedHash) {
180
- return null;
215
+ if (unsafeAuthDate !== String(signed.authDate)) {
216
+ throw new Error("Telegram WebApp unsafe auth_date does not match signed initData.");
217
+ }
218
+ if (unsafe.query_id !== signed.queryId) {
219
+ throw new Error("Telegram WebApp unsafe query_id does not match signed initData.");
220
+ }
221
+ if (unsafe.start_param !== signed.startParam) {
222
+ throw new Error("Telegram WebApp unsafe start_param does not match signed initData.");
223
+ }
224
+ if (unsafe.hash !== undefined && unsafe.hash !== signed.hash) {
225
+ throw new Error("Telegram WebApp unsafe hash does not match signed initData.");
181
226
  }
182
- const params = {
183
- id: user.id,
184
- first_name: user.first_name,
185
- last_name: user.last_name,
186
- username: user.username,
187
- photo_url: user.photo_url,
188
- auth_date: authDateValue,
189
- };
190
- const checkString = Object.keys(params)
191
- .sort()
192
- .filter((key) => params[key] !== undefined)
193
- .map((key) => `${key}=${params[key]}`)
194
- .join("\n");
195
- const secretKey = (0, node_crypto_1.createHash)("sha256")
196
- .update(botToken.trim())
197
- .digest();
198
- const computed = (0, node_crypto_1.createHmac)("sha256", secretKey)
199
- .update(checkString)
200
- .digest("hex");
201
- const matches = computed.length === receivedHash.length &&
202
- (0, node_crypto_1.timingSafeEqual)(Buffer.from(computed, "utf8"), Buffer.from(receivedHash, "utf8"));
203
- return {
204
- checkString,
205
- computedHash: computed,
206
- providedHash: receivedHash,
207
- matches,
208
- };
209
227
  }
210
228
  function validateTelegramWebAppInitData(rawInitData, unsafeInitData, botToken, maxAgeSeconds) {
211
229
  const normalizedRaw = rawInitData
212
230
  ? normalizeTelegramWebAppInitData(rawInitData)
213
231
  : "";
214
- const normalizedUnsafe = unsafeInitData ?? null;
215
- if (!normalizedRaw && !normalizedUnsafe) {
232
+ if (!normalizedRaw) {
216
233
  throw new Error("Telegram WebApp initData is empty.");
217
234
  }
218
- const officialRawValidation = buildOfficialRawValidation(normalizedRaw, botToken);
219
- const userFieldsValidation = buildUserFieldsValidation(normalizedUnsafe, botToken);
220
- if (!officialRawValidation?.matches && !userFieldsValidation?.matches) {
221
- throw new Error("Telegram WebApp initData hash validation failed.");
222
- }
223
- if (!normalizedUnsafe) {
224
- throw new Error("Telegram WebApp unsafe init data is missing.");
225
- }
226
- const user = normalizeUnsafeUser(normalizedUnsafe.user);
227
- const authDateRaw = typeof normalizedUnsafe.auth_date === "number" ||
228
- typeof normalizedUnsafe.auth_date === "string"
229
- ? String(normalizedUnsafe.auth_date)
230
- : null;
231
- if (!authDateRaw || !user) {
232
- throw new Error("Telegram WebApp initData is missing auth_date or user.");
235
+ const signedParams = validateOfficialRawHash(normalizedRaw, botToken);
236
+ const user = parseSignedUser(readSignedParam(signedParams, "user", true));
237
+ const authDateRaw = readSignedParam(signedParams, "auth_date", true);
238
+ if (!/^\d+$/.test(authDateRaw)) {
239
+ throw new Error("Telegram WebApp auth_date is invalid.");
233
240
  }
234
- const authDate = Number.parseInt(authDateRaw, 10);
235
- if (!Number.isFinite(authDate) || authDate <= 0) {
241
+ const authDate = Number(authDateRaw);
242
+ if (!Number.isSafeInteger(authDate) || authDate <= 0) {
236
243
  throw new Error("Telegram WebApp auth_date is invalid.");
237
244
  }
245
+ const queryId = readSignedParam(signedParams, "query_id", false);
246
+ const startParam = readSignedParam(signedParams, "start_param", false);
247
+ if (unsafeInitData) {
248
+ assertUnsafeDataMatchesSigned(unsafeInitData, {
249
+ user,
250
+ authDate,
251
+ ...(queryId !== undefined ? { queryId } : {}),
252
+ ...(startParam !== undefined ? { startParam } : {}),
253
+ hash: readSignedParam(signedParams, "hash", true),
254
+ });
255
+ }
238
256
  const nowSeconds = Math.floor(Date.now() / 1000);
239
257
  if (nowSeconds - authDate > maxAgeSeconds) {
240
258
  throw new Error("Telegram WebApp initData is expired.");
@@ -243,28 +261,7 @@ function validateTelegramWebAppInitData(rawInitData, unsafeInitData, botToken, m
243
261
  user,
244
262
  authDate,
245
263
  rawInitData: normalizedRaw,
246
- ...(typeof normalizedUnsafe.query_id === "string"
247
- ? { queryId: normalizedUnsafe.query_id }
248
- : {}),
249
- ...(typeof normalizedUnsafe.start_param === "string"
250
- ? { startParam: normalizedUnsafe.start_param }
251
- : {}),
252
- validationDebug: {
253
- providedHash: officialRawValidation?.providedHash ??
254
- userFieldsValidation?.providedHash ??
255
- "",
256
- officialRaw: {
257
- checkString: officialRawValidation?.checkString ?? "",
258
- computedHash: officialRawValidation?.computedHash ?? "",
259
- matches: officialRawValidation?.matches ?? false,
260
- },
261
- userFields: userFieldsValidation
262
- ? {
263
- checkString: userFieldsValidation.checkString,
264
- computedHash: userFieldsValidation.computedHash,
265
- matches: userFieldsValidation.matches,
266
- }
267
- : null,
268
- },
264
+ ...(queryId !== undefined ? { queryId } : {}),
265
+ ...(startParam !== undefined ? { startParam } : {}),
269
266
  };
270
267
  }
@@ -33,9 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.browserConsoleInputSchema = exports.browserWaitForUrlOutputSchema = exports.browserWaitForUrlInputSchema = exports.browserWaitForOutputSchema = exports.browserWaitForInputSchema = exports.browserInjectScriptOutputSchema = exports.browserInjectScriptInputSchema = exports.browserPressOutputSchema = exports.browserPressInputSchema = exports.browserFillOutputSchema = exports.browserFillInputSchema = exports.browserClickOutputSchema = exports.browserClickInputSchema = exports.browserReloadOutputSchema = exports.browserReloadInputSchema = exports.browserRecordingStatusOutputSchema = exports.browserRecordingStatusInputSchema = exports.browserRecordingStopOutputSchema = exports.browserRecordingStopInputSchema = exports.browserRecordingStartOutputSchema = exports.browserRecordingStartInputSchema = exports.browserDetachTabOutputSchema = exports.browserDetachTabInputSchema = exports.browserAttachTabOutputSchema = exports.browserAttachTabInputSchema = exports.browserAttachActiveTabInputSchema = exports.browserListTabsOutputSchema = exports.browserListTabsInputSchema = exports.browserListAttachedInstancesOutputSchema = exports.browserListAttachedInstancesInputSchema = exports.browserOpenOutputSchema = exports.browserOpenInputSchema = exports.clearSessionContextOutputSchema = exports.clearSessionContextInputSchema = exports.getSessionContextOutputSchema = exports.getSessionContextInputSchema = exports.setSessionContextOutputSchema = exports.renameSessionOutputSchema = exports.renameSessionInputSchema = exports.setSessionContextInputSchema = exports.refreshToolsMarkdownOutputSchema = exports.refreshToolsMarkdownInputSchema = exports.listGatewaySessionsOutputSchema = exports.listGatewaySessionsInputSchema = exports.sendFileToTelegramOutputSchema = exports.sendFileToTelegramInputSchema = exports.notifyTelegramOutputSchema = exports.notifyTelegramInputSchema = exports.askUserTelegramOutputSchema = exports.askUserTelegramInputSchema = void 0;
37
- exports.markXchangeRecordReadOutputSchema = exports.markXchangeRecordReadInputSchema = exports.getXchangeRecordOutputSchema = exports.getXchangeRecordInputSchema = exports.listXchangeRecordsOutputSchema = exports.listXchangeRecordsInputSchema = exports.sendPartnerNoteOutputSchema = exports.sendPartnerFileInputSchema = exports.sendPartnerNoteInputSchema = exports.browserCloseOutputSchema = exports.browserCloseInputSchema = exports.browserScreenshotOutputSchema = exports.browserScreenshotInputSchema = exports.browserComputedStyleOutputSchema = exports.browserComputedStyleInputSchema = exports.browserDomOutputSchema = exports.browserDomInputSchema = exports.browserClearLogsOutputSchema = exports.browserClearLogsInputSchema = exports.browserNetworkFailuresOutputSchema = exports.browserNetworkFailuresInputSchema = exports.browserErrorsOutputSchema = exports.browserErrorsInputSchema = exports.browserConsoleOutputSchema = void 0;
36
+ exports.browserWaitForInputSchema = exports.browserInjectScriptOutputSchema = exports.browserInjectScriptInputSchema = exports.browserPressOutputSchema = exports.browserPressInputSchema = exports.browserFillOutputSchema = exports.browserFillInputSchema = exports.browserClickOutputSchema = exports.browserClickInputSchema = exports.browserReloadOutputSchema = exports.browserReloadInputSchema = exports.browserRecordingStatusOutputSchema = exports.browserRecordingStatusInputSchema = exports.browserRecordingStopOutputSchema = exports.browserRecordingStopInputSchema = exports.browserRecordingStartOutputSchema = exports.browserRecordingStartInputSchema = exports.browserDetachTabOutputSchema = exports.browserDetachTabInputSchema = exports.browserAttachTabOutputSchema = exports.browserAttachTabInputSchema = exports.browserAttachActiveTabInputSchema = exports.browserListTabsOutputSchema = exports.browserListTabsInputSchema = exports.browserListAttachedInstancesOutputSchema = exports.browserListAttachedInstancesInputSchema = exports.browserOpenOutputSchema = exports.browserOpenInputSchema = exports.clearSessionContextOutputSchema = exports.clearSessionContextInputSchema = exports.getSessionContextOutputSchema = exports.getSessionContextInputSchema = exports.setSessionContextOutputSchema = exports.renameSessionOutputSchema = exports.renameSessionInputSchema = exports.setSessionContextInputSchema = exports.refreshToolsMarkdownOutputSchema = exports.refreshToolsMarkdownInputSchema = exports.listGatewaySessionsOutputSchema = exports.listGatewaySessionsInputSchema = exports.getFileListOutputSchema = exports.getFileListInputSchema = exports.getFileOutputSchema = exports.getFileInputSchema = exports.sendFileToTelegramOutputSchema = exports.sendFileToTelegramInputSchema = exports.notifyTelegramOutputSchema = exports.notifyTelegramInputSchema = exports.askUserTelegramOutputSchema = exports.askUserTelegramInputSchema = void 0;
37
+ exports.markXchangeRecordReadOutputSchema = exports.markXchangeRecordReadInputSchema = exports.getXchangeRecordOutputSchema = exports.getXchangeRecordInputSchema = exports.listXchangeRecordsOutputSchema = exports.listXchangeRecordsInputSchema = exports.sendPartnerNoteOutputSchema = exports.sendPartnerFileInputSchema = exports.sendPartnerNoteInputSchema = exports.browserCloseOutputSchema = exports.browserCloseInputSchema = exports.browserScreenshotOutputSchema = exports.browserScreenshotInputSchema = exports.browserComputedStyleOutputSchema = exports.browserComputedStyleInputSchema = exports.browserDomOutputSchema = exports.browserDomInputSchema = exports.browserClearLogsOutputSchema = exports.browserClearLogsInputSchema = exports.browserNetworkFailuresOutputSchema = exports.browserNetworkFailuresInputSchema = exports.browserErrorsOutputSchema = exports.browserErrorsInputSchema = exports.browserConsoleOutputSchema = exports.browserConsoleInputSchema = exports.browserWaitForUrlOutputSchema = exports.browserWaitForUrlInputSchema = exports.browserWaitForOutputSchema = void 0;
38
38
  const z = __importStar(require("zod/v4"));
39
+ const bodyLimits_1 = require("../../../shared/lib/bodyLimits");
40
+ const bodyStringSchema = z.string().max(bodyLimits_1.MAX_BODY_SIZE_BYTES);
39
41
  const partnerNoteKindSchema = z.enum([
40
42
  "share",
41
43
  "question",
@@ -87,6 +89,45 @@ exports.sendFileToTelegramOutputSchema = z.object({
87
89
  sent: z.boolean(),
88
90
  message_id: z.number().int().positive().optional(),
89
91
  });
92
+ exports.getFileInputSchema = z
93
+ .object({
94
+ session_id: z.string().trim().min(1).optional(),
95
+ file_path: z.string().trim().min(1).optional(),
96
+ selector: z.enum(["latest_screenshot"]).optional(),
97
+ type: z.enum(["url", "image", "text", "base64"]).optional(),
98
+ })
99
+ .refine((input) => Boolean(input.file_path) !== Boolean(input.selector), {
100
+ message: "Provide exactly one of file_path or selector.",
101
+ });
102
+ exports.getFileOutputSchema = z.object({
103
+ type: z.enum(["url", "image", "text", "base64"]),
104
+ data: bodyStringSchema,
105
+ mimetype: z.string().trim().min(1),
106
+ filename: z.string().trim().min(1),
107
+ size_bytes: z.number().int().nonnegative(),
108
+ expires_at: z.string().trim().min(1).optional(),
109
+ });
110
+ const getFileListSourceSchema = z.enum([
111
+ "telegram-upload",
112
+ "browser-screenshot",
113
+ "partner-artifact",
114
+ ]);
115
+ exports.getFileListInputSchema = z.object({
116
+ session_id: z.string().trim().min(1).optional(),
117
+ source: getFileListSourceSchema.optional(),
118
+ limit: z.number().int().positive().max(200).optional(),
119
+ });
120
+ exports.getFileListOutputSchema = z.object({
121
+ total: z.number().int().nonnegative(),
122
+ files: z.array(z.object({
123
+ file_path: z.string().trim().min(1),
124
+ filename: z.string().trim().min(1),
125
+ mimetype: z.string().trim().min(1),
126
+ source: getFileListSourceSchema,
127
+ size_bytes: z.number().int().nonnegative().optional(),
128
+ created_at: z.string().trim().min(1),
129
+ })),
130
+ });
90
131
  exports.listGatewaySessionsInputSchema = z.object({
91
132
  client_uuid: z.string().trim().min(1).optional(),
92
133
  connected_only: z.boolean().optional(),
@@ -218,7 +259,7 @@ exports.browserListAttachedInstancesOutputSchema = z.object({
218
259
  total: z.number().int().nonnegative(),
219
260
  instances: z.array(z.object({
220
261
  instance_id: z.string().trim().min(1),
221
- browser: z.literal("firefox"),
262
+ browser: z.enum(["firefox", "chrome"]),
222
263
  extension_version: z.string().trim().min(1),
223
264
  profile_name: z.string().trim().min(1).optional(),
224
265
  connected_at: z.string().trim().min(1),
@@ -344,7 +385,7 @@ exports.browserReloadInputSchema = z.object({
344
385
  exports.browserReloadOutputSchema = z.object({
345
386
  session_id: z.string(),
346
387
  reloaded: z.boolean(),
347
- url: z.string().url(),
388
+ url: z.string(),
348
389
  title: z.string().optional(),
349
390
  });
350
391
  const browserLocatorInputShape = {
@@ -367,7 +408,7 @@ exports.browserClickOutputSchema = z.object({
367
408
  ai_tag: z.string().optional(),
368
409
  selector: z.string().optional(),
369
410
  text: z.string().optional(),
370
- url: z.string().url(),
411
+ url: z.string(),
371
412
  title: z.string().optional(),
372
413
  });
373
414
  exports.browserFillInputSchema = z
@@ -386,7 +427,7 @@ exports.browserFillOutputSchema = z.object({
386
427
  selector: z.string().optional(),
387
428
  text: z.string().optional(),
388
429
  value_length: z.number().int().nonnegative(),
389
- url: z.string().url(),
430
+ url: z.string(),
390
431
  title: z.string().optional(),
391
432
  });
392
433
  exports.browserPressInputSchema = z.object({
@@ -400,7 +441,7 @@ exports.browserPressOutputSchema = z.object({
400
441
  ai_tag: z.string().optional(),
401
442
  selector: z.string().optional(),
402
443
  text: z.string().optional(),
403
- url: z.string().url(),
444
+ url: z.string(),
404
445
  title: z.string().optional(),
405
446
  });
406
447
  exports.browserInjectScriptInputSchema = z
@@ -420,7 +461,7 @@ exports.browserInjectScriptOutputSchema = z.object({
420
461
  namespace: z.string(),
421
462
  source_type: z.enum(["inline", "file"]),
422
463
  bytes: z.number().int().nonnegative(),
423
- url: z.string().url(),
464
+ url: z.string(),
424
465
  title: z.string().optional(),
425
466
  });
426
467
  exports.browserWaitForInputSchema = z
@@ -439,7 +480,7 @@ exports.browserWaitForOutputSchema = z.object({
439
480
  ai_tag: z.string().optional(),
440
481
  selector: z.string().optional(),
441
482
  text: z.string().optional(),
442
- url: z.string().url(),
483
+ url: z.string(),
443
484
  title: z.string().optional(),
444
485
  });
445
486
  exports.browserWaitForUrlInputSchema = z
@@ -459,7 +500,7 @@ exports.browserWaitForUrlOutputSchema = z.object({
459
500
  matched: z.enum(["url", "url_contains"]),
460
501
  url: z.string().optional(),
461
502
  url_contains: z.string().optional(),
462
- current_url: z.string().url(),
503
+ current_url: z.string(),
463
504
  title: z.string().optional(),
464
505
  });
465
506
  exports.browserConsoleInputSchema = z.object({
@@ -497,7 +538,7 @@ exports.browserNetworkFailuresOutputSchema = z.object({
497
538
  session_id: z.string(),
498
539
  total: z.number().int().nonnegative(),
499
540
  failures: z.array(z.object({
500
- url: z.string().url(),
541
+ url: z.string(),
501
542
  method: z.string(),
502
543
  status: z.number().int().optional(),
503
544
  error_text: z.string().optional(),
@@ -585,9 +626,9 @@ exports.sendPartnerNoteInputSchema = z.object({
585
626
  target_local_session_id: z.string().trim().min(1).optional(),
586
627
  project_uuid: z.string().trim().min(1).optional(),
587
628
  kind: partnerNoteKindSchema,
588
- summary: z.string().trim().min(1),
589
- message: z.string().trim().min(1),
590
- expected_reply: z.string().trim().min(1).optional(),
629
+ summary: bodyStringSchema.trim().min(1),
630
+ message: bodyStringSchema.trim().min(1),
631
+ expected_reply: bodyStringSchema.trim().min(1).optional(),
591
632
  requires_reply: z.boolean().optional(),
592
633
  in_reply_to: z.string().trim().min(1).optional(),
593
634
  artifacts: z.array(z.string().trim().min(1)).optional(),
@@ -599,7 +640,7 @@ exports.sendPartnerNoteInputSchema = z.object({
599
640
  mime_type: z.string().trim().min(1).optional(),
600
641
  size_bytes: z.number().int().nonnegative().optional(),
601
642
  storage_ref: z.string().trim().min(1).optional(),
602
- content_base64: z.string().trim().min(1).optional(),
643
+ content_base64: bodyStringSchema.trim().min(1).optional(),
603
644
  }))
604
645
  .optional(),
605
646
  });
@@ -612,9 +653,9 @@ exports.sendPartnerFileInputSchema = z.object({
612
653
  cwd: z.string().trim().min(1).optional(),
613
654
  file_path: z.string().trim().min(1),
614
655
  kind: partnerNoteKindSchema.optional(),
615
- summary: z.string().trim().min(1).optional(),
616
- message: z.string().trim().min(1).optional(),
617
- expected_reply: z.string().trim().min(1).optional(),
656
+ summary: bodyStringSchema.trim().min(1).optional(),
657
+ message: bodyStringSchema.trim().min(1).optional(),
658
+ expected_reply: bodyStringSchema.trim().min(1).optional(),
618
659
  requires_reply: z.boolean().optional(),
619
660
  in_reply_to: z.string().trim().min(1).optional(),
620
661
  });
@@ -678,7 +719,9 @@ const xchangeRecordSchema = z.object({
678
719
  exports.listXchangeRecordsInputSchema = z.object({
679
720
  session_id: z.string().trim().min(1).optional(),
680
721
  status: z.enum(["new", "read", "archived"]).optional(),
681
- category: z.enum(["partner_note", "local_handoff", "telegram_message"]).optional(),
722
+ category: z
723
+ .enum(["partner_note", "local_handoff", "telegram_message"])
724
+ .optional(),
682
725
  direction: z.enum(["incoming", "outgoing", "local"]).optional(),
683
726
  limit: z.number().int().positive().max(200).optional(),
684
727
  });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserAttachActiveTabTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [{ type: "text", text: JSON.stringify(output, null, 2) }];
7
+ }
8
+ class BrowserAttachActiveTabTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_attach_active_tab", {
15
+ title: "Browser Attach Active Tab",
16
+ description: "Attach the current MCP session to the active tab of a connected attached browser instance. If only one instance is connected, instance_id can be omitted.",
17
+ inputSchema: schema_1.browserAttachActiveTabInputSchema,
18
+ outputSchema: schema_1.browserAttachTabOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.attachActiveTab(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserAttachActiveTabTool = BrowserAttachActiveTabTool;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserAttachTabTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [{ type: "text", text: JSON.stringify(output, null, 2) }];
7
+ }
8
+ class BrowserAttachTabTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_attach_tab", {
15
+ title: "Browser Attach Tab",
16
+ description: "Attach the current MCP session to a specific tab in a connected attached browser instance by tab_id.",
17
+ inputSchema: schema_1.browserAttachTabInputSchema,
18
+ outputSchema: schema_1.browserAttachTabOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.attachTab(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserAttachTabTool = BrowserAttachTabTool;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserDetachTabTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [{ type: "text", text: JSON.stringify(output, null, 2) }];
7
+ }
8
+ class BrowserDetachTabTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_detach_tab", {
15
+ title: "Browser Detach Tab",
16
+ description: "Detach the current MCP session from the currently selected attached browser tab.",
17
+ inputSchema: schema_1.browserDetachTabInputSchema,
18
+ outputSchema: schema_1.browserDetachTabOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.detachTab(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserDetachTabTool = BrowserDetachTabTool;
@@ -18,7 +18,7 @@ class BrowserListAttachedInstancesTool {
18
18
  register(server) {
19
19
  server.registerTool("browser_list_attached_instances", {
20
20
  title: "Browser List Attached Instances",
21
- description: "List Firefox browser instances currently attached through the local browser-attach extension bridge for the current console.",
21
+ description: "List browser instances currently attached through the local browser-attach extension bridge for the current console.",
22
22
  inputSchema: schema_1.browserListAttachedInstancesInputSchema,
23
23
  outputSchema: schema_1.browserListAttachedInstancesOutputSchema,
24
24
  }, async (args) => {
@@ -18,7 +18,7 @@ class BrowserListTabsTool {
18
18
  register(server) {
19
19
  server.registerTool("browser_list_tabs", {
20
20
  title: "Browser List Tabs",
21
- description: "List tabs from a Firefox browser instance attached through the local browser-attach extension bridge. If only one instance is connected, instance_id can be omitted. Note: active=true is per Firefox window; for the tab selected for the current MCP session, use selected=true.",
21
+ description: "List tabs from an attached browser instance connected through the local browser-attach extension bridge. If only one instance is connected, instance_id can be omitted. Note: active=true is per browser window; for the tab selected for the current MCP session, use selected=true.",
22
22
  inputSchema: schema_1.browserListTabsInputSchema,
23
23
  outputSchema: schema_1.browserListTabsOutputSchema,
24
24
  }, async (args) => {