@deadragdoll/tellymcp 0.0.11 → 0.0.13

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 (62) hide show
  1. package/README-ru.md +48 -0
  2. package/README.md +47 -0
  3. package/TOOLS.md +232 -3
  4. package/VERSION.md +2 -2
  5. package/dist/cli.js +109 -1
  6. package/dist/services/features/telegram-mcp/browser.service.js +38 -1
  7. package/dist/services/features/telegram-mcp/gateway-socket.service.js +10 -0
  8. package/dist/services/features/telegram-mcp/mcp-server.service.js +12 -0
  9. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +14 -0
  10. package/dist/services/features/telegram-mcp/src/app/config/env.js +13 -0
  11. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +151 -2
  12. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +1 -1
  13. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +1 -1
  14. package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +1 -1
  15. package/dist/services/features/telegram-mcp/src/features/browser/model/browserInjectScriptTool.js +28 -0
  16. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListAttachedInstancesTool.js +33 -0
  17. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListTabsTool.js +33 -0
  18. package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +1 -1
  19. package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +1 -1
  20. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStartTool.js +28 -0
  21. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStatusTool.js +28 -0
  22. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStopTool.js +28 -0
  23. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  24. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +543 -9
  25. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/browserRecordingBundle.js +502 -0
  26. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachRegistry.js +79 -0
  27. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachServer.js +559 -0
  28. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/types.js +2 -0
  29. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +48 -0
  30. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +5 -1
  31. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +5 -1
  32. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +56 -0
  33. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +37 -0
  34. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +13 -7
  35. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +9 -0
  36. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +3 -0
  37. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +7 -0
  38. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +231 -34
  39. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +61 -6
  40. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +200 -28
  41. package/docs/STANDALONE-ru.md +42 -6
  42. package/docs/STANDALONE.md +42 -6
  43. package/package.json +6 -3
  44. package/packages/chrome-attach-extension/dist/background.js +1326 -0
  45. package/packages/chrome-attach-extension/dist/icon.svg +6 -0
  46. package/packages/chrome-attach-extension/dist/manifest.json +36 -0
  47. package/packages/chrome-attach-extension/dist/options.html +312 -0
  48. package/packages/chrome-attach-extension/dist/options.js +593 -0
  49. package/packages/chrome-attach-extension/dist/popup.html +93 -0
  50. package/packages/chrome-attach-extension/dist/popup.js +79 -0
  51. package/packages/chrome-attach-extension/dist/recorder-content.js +83 -0
  52. package/packages/chrome-attach-extension/dist/recorder-page.js +266 -0
  53. package/packages/firefox-attach-extension/README.md +13 -0
  54. package/packages/firefox-attach-extension/dist/background.js +1242 -0
  55. package/packages/firefox-attach-extension/dist/icon.svg +6 -0
  56. package/packages/firefox-attach-extension/dist/manifest.json +56 -0
  57. package/packages/firefox-attach-extension/dist/options.html +312 -0
  58. package/packages/firefox-attach-extension/dist/options.js +527 -0
  59. package/packages/firefox-attach-extension/dist/popup.html +93 -0
  60. package/packages/firefox-attach-extension/dist/popup.js +64 -0
  61. package/packages/firefox-attach-extension/dist/recorder-content.js +77 -0
  62. package/packages/firefox-attach-extension/dist/recorder-page.js +302 -0
@@ -21,6 +21,36 @@ const TelegramMcpBrowserService = {
21
21
  return this.getBrowserService().getConsole(ctx.params);
22
22
  },
23
23
  },
24
+ listAttachedInstancesRemote: {
25
+ params: { $$strict: false },
26
+ async handler(ctx) {
27
+ return this.getBrowserService().listAttachedInstances(ctx.params);
28
+ },
29
+ },
30
+ listTabsRemote: {
31
+ params: { $$strict: false },
32
+ async handler(ctx) {
33
+ return this.getBrowserService().listTabs(ctx.params);
34
+ },
35
+ },
36
+ startRecordingRemote: {
37
+ params: { $$strict: false },
38
+ async handler(ctx) {
39
+ return this.getBrowserService().startRecording(ctx.params);
40
+ },
41
+ },
42
+ stopRecordingRemote: {
43
+ params: { $$strict: false },
44
+ async handler(ctx) {
45
+ return this.getBrowserService().stopRecording(ctx.params);
46
+ },
47
+ },
48
+ getRecordingStatusRemote: {
49
+ params: { $$strict: false },
50
+ async handler(ctx) {
51
+ return this.getBrowserService().getRecordingStatus(ctx.params);
52
+ },
53
+ },
24
54
  clickRemote: {
25
55
  params: { $$strict: false },
26
56
  async handler(ctx) {
@@ -33,6 +63,12 @@ const TelegramMcpBrowserService = {
33
63
  return this.getBrowserService().fill(ctx.params);
34
64
  },
35
65
  },
66
+ injectScriptRemote: {
67
+ params: { $$strict: false },
68
+ async handler(ctx) {
69
+ return this.getBrowserService().injectScript(ctx.params);
70
+ },
71
+ },
36
72
  pressRemote: {
37
73
  params: { $$strict: false },
38
74
  async handler(ctx) {
@@ -119,7 +155,8 @@ const TelegramMcpBrowserService = {
119
155
  }
120
156
  const runtime = await runtimeService.waitUntilReady();
121
157
  this.logger.info("Starting telegram_mcp browser service");
122
- this.browserService = new browserService_1.BrowserService(runtime.config, runtime.sessionStore, runtime.maintenanceStore, runtime.stateStore, runtime.stateStore, runtime.objectStore, runtime.telegramTransport, runtime.logger, runtime.projectIdentityResolver, new remoteConsoleActionClient_1.RemoteConsoleActionClient((actionName, params) => this.broker.call(actionName, params, { meta: { internal_call: true } })));
158
+ const firefoxAttachServer = runtime.firefoxAttachServer;
159
+ this.browserService = new browserService_1.BrowserService(runtime.config, runtime.sessionStore, runtime.maintenanceStore, runtime.stateStore, runtime.stateStore, runtime.objectStore, runtime.telegramTransport, runtime.logger, runtime.projectIdentityResolver, new remoteConsoleActionClient_1.RemoteConsoleActionClient((actionName, params) => this.broker.call(actionName, params, { meta: { internal_call: true } })), firefoxAttachServer);
123
160
  this.logger.info("telegram_mcp browser service is ready");
124
161
  },
125
162
  async stopped() {
@@ -1226,6 +1226,13 @@ const TelegramMcpGatewaySocketService = {
1226
1226
  }))
1227
1227
  : [],
1228
1228
  }, { meta: { internal_call: true } });
1229
+ await runtime.telegramTransport.hydrateGatewayClientOwnerRoute({
1230
+ clientUuid: hello.client_uuid,
1231
+ ...(hello.gateway_user_uuid
1232
+ ? { gatewayUserUuid: hello.gateway_user_uuid }
1233
+ : {}),
1234
+ });
1235
+ runtime.telegramTransport.ensurePromptScanRunning();
1229
1236
  }
1230
1237
  const localVersionInfo = this.getLocalVersionInfo?.() ?? {
1231
1238
  packageVersion: "0.0.0-unknown",
@@ -2002,6 +2009,9 @@ const TelegramMcpGatewaySocketService = {
2002
2009
  }
2003
2010
  }
2004
2011
  }
2012
+ if ((this.connectedClientsByUuid?.size ?? 0) === 0) {
2013
+ runtime.telegramTransport.pausePromptScan();
2014
+ }
2005
2015
  this.connectedClientToolsAlerts?.delete(socket);
2006
2016
  this.connectedClients?.delete(socket);
2007
2017
  runtime.logger.warn("Gateway WS client disconnected", {
@@ -18,9 +18,15 @@ const browserConsoleTool_1 = require("./src/features/browser/model/browserConsol
18
18
  const browserDomTool_1 = require("./src/features/browser/model/browserDomTool");
19
19
  const browserErrorsTool_1 = require("./src/features/browser/model/browserErrorsTool");
20
20
  const browserFillTool_1 = require("./src/features/browser/model/browserFillTool");
21
+ const browserInjectScriptTool_1 = require("./src/features/browser/model/browserInjectScriptTool");
22
+ const browserListAttachedInstancesTool_1 = require("./src/features/browser/model/browserListAttachedInstancesTool");
23
+ const browserListTabsTool_1 = require("./src/features/browser/model/browserListTabsTool");
21
24
  const browserNetworkFailuresTool_1 = require("./src/features/browser/model/browserNetworkFailuresTool");
22
25
  const browserOpenTool_1 = require("./src/features/browser/model/browserOpenTool");
23
26
  const browserPressTool_1 = require("./src/features/browser/model/browserPressTool");
27
+ const browserRecordingStartTool_1 = require("./src/features/browser/model/browserRecordingStartTool");
28
+ const browserRecordingStatusTool_1 = require("./src/features/browser/model/browserRecordingStatusTool");
29
+ const browserRecordingStopTool_1 = require("./src/features/browser/model/browserRecordingStopTool");
24
30
  const browserReloadTool_1 = require("./src/features/browser/model/browserReloadTool");
25
31
  const browserScreenshotTool_1 = require("./src/features/browser/model/browserScreenshotTool");
26
32
  const browserWaitForTool_1 = require("./src/features/browser/model/browserWaitForTool");
@@ -76,10 +82,16 @@ const TelegramMcpMcpServerService = {
76
82
  new notifyTelegramTool_1.NotifyTelegramTool(notifyService.getNotifyService()),
77
83
  new sendFileToTelegramTool_1.SendFileToTelegramTool(notifyService.getNotifyService()),
78
84
  new askUserTelegram_1.AskUserTelegramTool(approvalService.getApprovalOrchestrator()),
85
+ new browserListAttachedInstancesTool_1.BrowserListAttachedInstancesTool(browserService.getBrowserService()),
86
+ new browserListTabsTool_1.BrowserListTabsTool(browserService.getBrowserService()),
87
+ new browserRecordingStartTool_1.BrowserRecordingStartTool(browserService.getBrowserService()),
88
+ new browserRecordingStopTool_1.BrowserRecordingStopTool(browserService.getBrowserService()),
89
+ new browserRecordingStatusTool_1.BrowserRecordingStatusTool(browserService.getBrowserService()),
79
90
  new browserOpenTool_1.BrowserOpenTool(browserService.getBrowserService()),
80
91
  new browserReloadTool_1.BrowserReloadTool(browserService.getBrowserService()),
81
92
  new browserClickTool_1.BrowserClickTool(browserService.getBrowserService()),
82
93
  new browserFillTool_1.BrowserFillTool(browserService.getBrowserService()),
94
+ new browserInjectScriptTool_1.BrowserInjectScriptTool(browserService.getBrowserService()),
83
95
  new browserPressTool_1.BrowserPressTool(browserService.getBrowserService()),
84
96
  new browserWaitForTool_1.BrowserWaitForTool(browserService.getBrowserService()),
85
97
  new browserWaitForUrlTool_1.BrowserWaitForUrlTool(browserService.getBrowserService()),
@@ -12,6 +12,7 @@ const transport_1 = require("../../shared/integrations/telegram/transport");
12
12
  const minioExchangeStore_1 = require("../../shared/integrations/object-storage/minioExchangeStore");
13
13
  const gatewayHttpService_1 = require("../../features/distributed-gateway/model/gatewayHttpService");
14
14
  const gatewayClientAccess_1 = require("../../features/distributed-client/model/gatewayClientAccess");
15
+ const firefoxAttachServer_1 = require("../../features/browser-attach/model/firefoxAttachServer");
15
16
  const client_2 = require("../../shared/integrations/terminal/client");
16
17
  const ptyRegistry_1 = require("../../shared/integrations/terminal/ptyRegistry");
17
18
  async function createAppRuntime(input) {
@@ -63,6 +64,15 @@ async function createAppRuntime(input) {
63
64
  nudgeDebounceSeconds: config.terminal.nudgeDebounceSeconds,
64
65
  nudgeCooldownSeconds: config.terminal.nudgeCooldownSeconds,
65
66
  },
67
+ browser: {
68
+ enabled: config.browser.enabled,
69
+ headless: config.browser.headless,
70
+ devtools: config.browser.devtools,
71
+ attachEnabled: config.browser.attach.enabled,
72
+ attachHost: config.browser.attach.host,
73
+ attachPort: config.browser.attach.port,
74
+ attachPath: config.browser.attach.path,
75
+ },
66
76
  telegram: {
67
77
  webhookEnabled: config.telegram.webhook.enabled,
68
78
  webhookPath: config.telegram.webhook.path,
@@ -200,6 +210,8 @@ async function createAppRuntime(input) {
200
210
  await telegramTransport.sendStartupNotifications();
201
211
  logger.info("Startup Telegram notifications completed");
202
212
  const gatewayHttpService = new gatewayHttpService_1.GatewayHttpService(config, input.callBroker);
213
+ const firefoxAttachServer = new firefoxAttachServer_1.FirefoxAttachServer(config, logger, stateStore, stateStore);
214
+ await firefoxAttachServer.start();
203
215
  return {
204
216
  callBroker: input.callBroker,
205
217
  config,
@@ -217,8 +229,10 @@ async function createAppRuntime(input) {
217
229
  projectIdentityResolver,
218
230
  webAppLaunchRegistry,
219
231
  gatewayHttpService,
232
+ firefoxAttachServer,
220
233
  shutdown: async () => {
221
234
  logger.info("Shutdown started");
235
+ await firefoxAttachServer.stop();
222
236
  await telegramTransport.stop();
223
237
  (0, ptyRegistry_1.stopAllPtyTargets)();
224
238
  redis.disconnect();
@@ -211,6 +211,13 @@ const envSchema = z.object({
211
211
  BROWSER_EXECUTABLE_PATH: optionalNonEmptyString,
212
212
  BROWSER_CHANNEL: z.preprocess(emptyStringToUndefined, z.enum(["chrome", "chromium", "msedge"]).optional()),
213
213
  BROWSER_SLOW_MO_MS: z.coerce.number().int().nonnegative().default(0),
214
+ BROWSER_ATTACH_ENABLED: z
215
+ .string()
216
+ .optional()
217
+ .transform((value) => value === "true"),
218
+ BROWSER_ATTACH_WS_HOST: z.string().min(1).default("127.0.0.1"),
219
+ BROWSER_ATTACH_WS_PORT: z.coerce.number().int().positive().default(9999),
220
+ BROWSER_ATTACH_WS_PATH: z.string().min(1).default("/browser-attach/ws"),
214
221
  PROXY_USE: z.preprocess(emptyStringToUndefined, z.enum(["http", "socks5"]).optional()),
215
222
  HTTP_PROXY: optionalNonEmptyString,
216
223
  SOCKS5_PROXY: optionalNonEmptyString,
@@ -417,6 +424,12 @@ function loadConfig() {
417
424
  : {}),
418
425
  ...(parsed.BROWSER_CHANNEL ? { channel: parsed.BROWSER_CHANNEL } : {}),
419
426
  slowMoMs: parsed.BROWSER_SLOW_MO_MS,
427
+ attach: {
428
+ enabled: parsed.BROWSER_ATTACH_ENABLED,
429
+ host: parsed.BROWSER_ATTACH_WS_HOST,
430
+ port: parsed.BROWSER_ATTACH_WS_PORT,
431
+ path: parsed.BROWSER_ATTACH_WS_PATH,
432
+ },
420
433
  },
421
434
  project: {
422
435
  ...(parsed.PROJECT_NAME ? { name: parsed.PROJECT_NAME } : {}),
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- 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 = exports.browserWaitForInputSchema = exports.browserPressOutputSchema = exports.browserPressInputSchema = exports.browserFillOutputSchema = exports.browserFillInputSchema = exports.browserClickOutputSchema = exports.browserClickInputSchema = exports.browserReloadOutputSchema = exports.browserReloadInputSchema = 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 = void 0;
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;
38
38
  const z = __importStar(require("zod/v4"));
39
39
  const partnerNoteKindSchema = z.enum([
40
40
  "share",
@@ -194,6 +194,8 @@ exports.clearSessionContextOutputSchema = z.object({
194
194
  exports.browserOpenInputSchema = z.object({
195
195
  session_id: z.string().trim().min(1).optional(),
196
196
  url: z.string().trim().min(1),
197
+ width: z.number().int().positive().max(10000).optional(),
198
+ height: z.number().int().positive().max(10000).optional(),
197
199
  wait_until: z
198
200
  .enum(["load", "domcontentloaded", "networkidle", "commit"])
199
201
  .optional(),
@@ -205,6 +207,133 @@ exports.browserOpenOutputSchema = z.object({
205
207
  created_context: z.boolean(),
206
208
  url: z.string().url(),
207
209
  title: z.string().optional(),
210
+ viewport_width: z.number().int().positive().optional(),
211
+ viewport_height: z.number().int().positive().optional(),
212
+ });
213
+ exports.browserListAttachedInstancesInputSchema = z.object({
214
+ session_id: z.string().trim().min(1).optional(),
215
+ });
216
+ exports.browserListAttachedInstancesOutputSchema = z.object({
217
+ session_id: z.string().trim().min(1).optional(),
218
+ total: z.number().int().nonnegative(),
219
+ instances: z.array(z.object({
220
+ instance_id: z.string().trim().min(1),
221
+ browser: z.literal("firefox"),
222
+ extension_version: z.string().trim().min(1),
223
+ profile_name: z.string().trim().min(1).optional(),
224
+ connected_at: z.string().trim().min(1),
225
+ last_seen_at: z.string().trim().min(1),
226
+ capabilities: z.array(z.string().trim().min(1)),
227
+ tab_count: z.number().int().nonnegative(),
228
+ active_tab: z
229
+ .object({
230
+ tab_id: z.number().int().nonnegative(),
231
+ window_id: z.number().int().nonnegative().optional(),
232
+ active: z.boolean(),
233
+ title: z.string(),
234
+ url: z.string(),
235
+ status: z.string().optional(),
236
+ })
237
+ .optional(),
238
+ })),
239
+ });
240
+ exports.browserListTabsInputSchema = z.object({
241
+ session_id: z.string().trim().min(1).optional(),
242
+ instance_id: z.string().trim().min(1).optional(),
243
+ });
244
+ exports.browserListTabsOutputSchema = z.object({
245
+ session_id: z.string().trim().min(1).optional(),
246
+ instance_id: z.string().trim().min(1),
247
+ total: z.number().int().nonnegative(),
248
+ tabs: z.array(z.object({
249
+ tab_id: z.number().int().nonnegative(),
250
+ window_id: z.number().int().nonnegative().optional(),
251
+ active: z.boolean(),
252
+ selected: z.boolean().optional(),
253
+ title: z.string(),
254
+ url: z.string(),
255
+ status: z.string().optional(),
256
+ })),
257
+ });
258
+ exports.browserAttachActiveTabInputSchema = z.object({
259
+ session_id: z.string().trim().min(1).optional(),
260
+ instance_id: z.string().trim().min(1).optional(),
261
+ });
262
+ exports.browserAttachTabInputSchema = z.object({
263
+ session_id: z.string().trim().min(1).optional(),
264
+ instance_id: z.string().trim().min(1).optional(),
265
+ tab_id: z.number().int().nonnegative(),
266
+ });
267
+ exports.browserAttachTabOutputSchema = z.object({
268
+ session_id: z.string().trim().min(1),
269
+ backend: z.literal("firefox-attached"),
270
+ instance_id: z.string().trim().min(1),
271
+ tab_id: z.number().int().nonnegative(),
272
+ attached_at: z.string().trim().min(1),
273
+ title: z.string().optional(),
274
+ url: z.string().optional(),
275
+ });
276
+ exports.browserDetachTabInputSchema = z.object({
277
+ session_id: z.string().trim().min(1).optional(),
278
+ });
279
+ exports.browserDetachTabOutputSchema = z.object({
280
+ session_id: z.string().trim().min(1),
281
+ detached: z.boolean(),
282
+ });
283
+ exports.browserRecordingStartInputSchema = z.object({
284
+ session_id: z.string().trim().min(1).optional(),
285
+ instance_id: z.string().trim().min(1).optional(),
286
+ });
287
+ exports.browserRecordingStartOutputSchema = z.object({
288
+ session_id: z.string().trim().min(1),
289
+ backend: z.literal("firefox-attached"),
290
+ started: z.boolean(),
291
+ recording_id: z.string().trim().min(1),
292
+ instance_id: z.string().trim().min(1),
293
+ tab_id: z.number().int().nonnegative(),
294
+ tab_title: z.string().optional(),
295
+ tab_url: z.string().optional(),
296
+ bundle_dir_name: z.string().trim().min(1),
297
+ bundle_relative_path: z.string().trim().min(1),
298
+ bundle_path: z.string().trim().min(1),
299
+ started_at: z.string().trim().min(1),
300
+ });
301
+ exports.browserRecordingStopInputSchema = z.object({
302
+ session_id: z.string().trim().min(1).optional(),
303
+ });
304
+ exports.browserRecordingStopOutputSchema = z.object({
305
+ session_id: z.string().trim().min(1),
306
+ stopped: z.boolean(),
307
+ recording_id: z.string().trim().min(1).optional(),
308
+ bundle_dir_name: z.string().trim().min(1).optional(),
309
+ bundle_relative_path: z.string().trim().min(1).optional(),
310
+ bundle_path: z.string().trim().min(1).optional(),
311
+ stopped_at: z.string().trim().min(1).optional(),
312
+ });
313
+ exports.browserRecordingStatusInputSchema = z.object({
314
+ session_id: z.string().trim().min(1).optional(),
315
+ });
316
+ exports.browserRecordingStatusOutputSchema = z.object({
317
+ session_id: z.string().trim().min(1),
318
+ active: z.boolean(),
319
+ recording: z
320
+ .object({
321
+ backend: z.literal("firefox-attached"),
322
+ recording_id: z.string().trim().min(1),
323
+ instance_id: z.string().trim().min(1),
324
+ tab_id: z.number().int().nonnegative(),
325
+ tab_title: z.string().optional(),
326
+ tab_url: z.string().optional(),
327
+ bundle_dir_name: z.string().trim().min(1),
328
+ bundle_relative_path: z.string().trim().min(1),
329
+ bundle_path: z.string().trim().min(1),
330
+ started_at: z.string().trim().min(1),
331
+ stopped_at: z.string().trim().min(1).optional(),
332
+ status: z.enum(["recording", "stopped"]),
333
+ event_count: z.number().int().nonnegative(),
334
+ last_event_at: z.string().trim().min(1).optional(),
335
+ })
336
+ .optional(),
208
337
  });
209
338
  exports.browserReloadInputSchema = z.object({
210
339
  session_id: z.string().trim().min(1).optional(),
@@ -274,6 +403,26 @@ exports.browserPressOutputSchema = z.object({
274
403
  url: z.string().url(),
275
404
  title: z.string().optional(),
276
405
  });
406
+ exports.browserInjectScriptInputSchema = z
407
+ .object({
408
+ session_id: z.string().trim().min(1).optional(),
409
+ source: z.string().optional(),
410
+ file_path: z.string().trim().min(1).optional(),
411
+ namespace: z.string().trim().min(1).optional(),
412
+ })
413
+ .refine((input) => Boolean(input.source?.trim() || input.file_path?.trim()), {
414
+ message: "Provide source or file_path.",
415
+ path: ["source"],
416
+ });
417
+ exports.browserInjectScriptOutputSchema = z.object({
418
+ session_id: z.string(),
419
+ injected: z.boolean(),
420
+ namespace: z.string(),
421
+ source_type: z.enum(["inline", "file"]),
422
+ bytes: z.number().int().nonnegative(),
423
+ url: z.string().url(),
424
+ title: z.string().optional(),
425
+ });
277
426
  exports.browserWaitForInputSchema = z
278
427
  .object({
279
428
  ...browserLocatorInputShape,
@@ -13,7 +13,7 @@ class BrowserClickTool {
13
13
  register(server) {
14
14
  server.registerTool("browser_click", {
15
15
  title: "Browser Click",
16
- description: "Click an element in the session browser page by CSS selector or visible text.",
16
+ description: "Click an element in the current session browser target by CSS selector or visible text. If the session has a selected attached Firefox tab, click there; otherwise use the isolated Playwright page.",
17
17
  inputSchema: schema_1.browserClickInputSchema,
18
18
  outputSchema: schema_1.browserClickOutputSchema,
19
19
  }, async (args) => {
@@ -13,7 +13,7 @@ class BrowserDomTool {
13
13
  register(server) {
14
14
  server.registerTool("browser_dom", {
15
15
  title: "Browser DOM",
16
- description: "Inspect a DOM element in the Playwright tab for the current session and return text, HTML, attributes, and visibility.",
16
+ description: "Inspect a DOM element in the current session browser target and return text, HTML, attributes, and visibility. If the session has a selected attached Firefox tab, inspect that tab; otherwise use the isolated Playwright page.",
17
17
  inputSchema: schema_1.browserDomInputSchema,
18
18
  outputSchema: schema_1.browserDomOutputSchema,
19
19
  }, async (args) => {
@@ -13,7 +13,7 @@ class BrowserFillTool {
13
13
  register(server) {
14
14
  server.registerTool("browser_fill", {
15
15
  title: "Browser Fill",
16
- description: "Fill an input or textarea in the session browser page by CSS selector or visible text.",
16
+ description: "Fill an input or textarea in the current session browser target by CSS selector or visible text. If the session has a selected attached Firefox tab, fill there; otherwise use the isolated Playwright page.",
17
17
  inputSchema: schema_1.browserFillInputSchema,
18
18
  outputSchema: schema_1.browserFillOutputSchema,
19
19
  }, async (args) => {
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserInjectScriptTool = 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 BrowserInjectScriptTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_inject_script", {
15
+ title: "Browser Inject Script",
16
+ description: "Inject JavaScript into the current session browser target. If the session has a selected attached browser tab, inject into that real tab; otherwise inject into the isolated Playwright page. The script is wrapped so window[namespace] exists, with namespace defaulting to TELLY.",
17
+ inputSchema: schema_1.browserInjectScriptInputSchema,
18
+ outputSchema: schema_1.browserInjectScriptOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.injectScript(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserInjectScriptTool = BrowserInjectScriptTool;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserListAttachedInstancesTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [
7
+ {
8
+ type: "text",
9
+ text: JSON.stringify(output, null, 2),
10
+ },
11
+ ];
12
+ }
13
+ class BrowserListAttachedInstancesTool {
14
+ browserService;
15
+ constructor(browserService) {
16
+ this.browserService = browserService;
17
+ }
18
+ register(server) {
19
+ server.registerTool("browser_list_attached_instances", {
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.",
22
+ inputSchema: schema_1.browserListAttachedInstancesInputSchema,
23
+ outputSchema: schema_1.browserListAttachedInstancesOutputSchema,
24
+ }, async (args) => {
25
+ const output = await this.browserService.listAttachedInstances(args);
26
+ return {
27
+ content: createContent(output),
28
+ structuredContent: output,
29
+ };
30
+ });
31
+ }
32
+ }
33
+ exports.BrowserListAttachedInstancesTool = BrowserListAttachedInstancesTool;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserListTabsTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [
7
+ {
8
+ type: "text",
9
+ text: JSON.stringify(output, null, 2),
10
+ },
11
+ ];
12
+ }
13
+ class BrowserListTabsTool {
14
+ browserService;
15
+ constructor(browserService) {
16
+ this.browserService = browserService;
17
+ }
18
+ register(server) {
19
+ server.registerTool("browser_list_tabs", {
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.",
22
+ inputSchema: schema_1.browserListTabsInputSchema,
23
+ outputSchema: schema_1.browserListTabsOutputSchema,
24
+ }, async (args) => {
25
+ const output = await this.browserService.listTabs(args);
26
+ return {
27
+ content: createContent(output),
28
+ structuredContent: output,
29
+ };
30
+ });
31
+ }
32
+ }
33
+ exports.BrowserListTabsTool = BrowserListTabsTool;
@@ -18,7 +18,7 @@ class BrowserOpenTool {
18
18
  register(server) {
19
19
  server.registerTool("browser_open", {
20
20
  title: "Browser Open",
21
- description: "Open a URL in the isolated Playwright browser context for the current session. Reuse the existing tab unless reset_context=true.",
21
+ description: "Open a URL in the isolated Playwright browser context for the current session. Reuse the existing tab unless reset_context=true. Optionally pass width and height to control the viewport.",
22
22
  inputSchema: schema_1.browserOpenInputSchema,
23
23
  outputSchema: schema_1.browserOpenOutputSchema,
24
24
  }, async (args) => {
@@ -13,7 +13,7 @@ class BrowserPressTool {
13
13
  register(server) {
14
14
  server.registerTool("browser_press", {
15
15
  title: "Browser Press",
16
- description: "Send a key press to the session browser page or to a targeted element.",
16
+ description: "Send a key press to the current session browser target or to a targeted element. If the session has a selected attached Firefox tab, press there; otherwise use the isolated Playwright page.",
17
17
  inputSchema: schema_1.browserPressInputSchema,
18
18
  outputSchema: schema_1.browserPressOutputSchema,
19
19
  }, async (args) => {
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserRecordingStartTool = 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 BrowserRecordingStartTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_recording_start", {
15
+ title: "Browser Recording Start",
16
+ description: "Start a structured browser recording bundle for the Firefox tab selected for this MCP session through the local browser-attach extension. The recording is written under .mcp-xchange/web/{tab-title-slug}-{timestamp}/ with session.json, timeline.ndjson, pages/, network/, and console/ artifacts.",
17
+ inputSchema: schema_1.browserRecordingStartInputSchema,
18
+ outputSchema: schema_1.browserRecordingStartOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.startRecording(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserRecordingStartTool = BrowserRecordingStartTool;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserRecordingStatusTool = 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 BrowserRecordingStatusTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_recording_status", {
15
+ title: "Browser Recording Status",
16
+ description: "Report whether a structured browser recording is active for the current MCP session, and return the current bundle path and metadata if it exists.",
17
+ inputSchema: schema_1.browserRecordingStatusInputSchema,
18
+ outputSchema: schema_1.browserRecordingStatusOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.getRecordingStatus(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserRecordingStatusTool = BrowserRecordingStatusTool;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserRecordingStopTool = 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 BrowserRecordingStopTool {
9
+ browserService;
10
+ constructor(browserService) {
11
+ this.browserService = browserService;
12
+ }
13
+ register(server) {
14
+ server.registerTool("browser_recording_stop", {
15
+ title: "Browser Recording Stop",
16
+ description: "Stop the active structured browser recording for the current session. The bundle remains in .mcp-xchange/web/... for later analysis by the agent.",
17
+ inputSchema: schema_1.browserRecordingStopInputSchema,
18
+ outputSchema: schema_1.browserRecordingStopOutputSchema,
19
+ }, async (args) => {
20
+ const output = await this.browserService.stopRecording(args);
21
+ return {
22
+ content: createContent(output),
23
+ structuredContent: output,
24
+ };
25
+ });
26
+ }
27
+ }
28
+ exports.BrowserRecordingStopTool = BrowserRecordingStopTool;
@@ -13,7 +13,7 @@ class BrowserScreenshotTool {
13
13
  register(server) {
14
14
  server.registerTool("browser_screenshot", {
15
15
  title: "Browser Screenshot",
16
- description: "Capture a screenshot from the Playwright tab for the current session. By default it is saved into .mcp-xchange. If the user wants the screenshot sent back to the human in Telegram, set send_to_telegram=true so the PNG is delivered through the gateway route instead of forcing a separate file-delivery workaround.",
16
+ description: "Capture a screenshot from the current session browser target. If the session has a selected attached Firefox tab, capture that real browser tab; otherwise use the isolated Playwright page. By default it is saved into .mcp-xchange. If the user wants the screenshot sent back to the human in Telegram, set send_to_telegram=true so the PNG is delivered through the gateway route instead of forcing a separate file-delivery workaround.",
17
17
  inputSchema: schema_1.browserScreenshotInputSchema,
18
18
  outputSchema: schema_1.browserScreenshotOutputSchema,
19
19
  }, async (args) => {