browser-use 0.2.0 → 0.4.0

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 (259) hide show
  1. package/README.md +295 -686
  2. package/dist/actor/element.d.ts +19 -0
  3. package/dist/actor/element.js +46 -0
  4. package/dist/actor/index.d.ts +4 -0
  5. package/dist/actor/index.js +4 -0
  6. package/dist/actor/mouse.d.ts +19 -0
  7. package/dist/actor/mouse.js +39 -0
  8. package/dist/actor/page.d.ts +29 -0
  9. package/dist/actor/page.js +88 -0
  10. package/dist/actor/utils.d.ts +4 -0
  11. package/dist/actor/utils.js +35 -0
  12. package/dist/agent/cloud-events.d.ts +18 -0
  13. package/dist/agent/cloud-events.js +65 -2
  14. package/dist/agent/gif.d.ts +1 -0
  15. package/dist/agent/gif.js +24 -2
  16. package/dist/agent/judge.d.ts +17 -0
  17. package/dist/agent/judge.js +197 -0
  18. package/dist/agent/message-manager/service.d.ts +12 -4
  19. package/dist/agent/message-manager/service.js +205 -39
  20. package/dist/agent/message-manager/utils.js +0 -1
  21. package/dist/agent/message-manager/views.d.ts +4 -0
  22. package/dist/agent/message-manager/views.js +11 -7
  23. package/dist/agent/prompts.d.ts +24 -3
  24. package/dist/agent/prompts.js +274 -59
  25. package/dist/agent/service.d.ts +103 -41
  26. package/dist/agent/service.js +2336 -472
  27. package/dist/agent/variable-detector.d.ts +12 -0
  28. package/dist/agent/variable-detector.js +211 -0
  29. package/dist/agent/views.d.ts +237 -18
  30. package/dist/agent/views.js +446 -33
  31. package/dist/browser/cloud/cloud.d.ts +20 -0
  32. package/dist/browser/cloud/cloud.js +129 -0
  33. package/dist/browser/cloud/index.d.ts +2 -0
  34. package/dist/browser/cloud/index.js +2 -0
  35. package/dist/browser/cloud/views.d.ts +41 -0
  36. package/dist/browser/cloud/views.js +35 -0
  37. package/dist/browser/events.d.ts +345 -0
  38. package/dist/browser/events.js +566 -0
  39. package/dist/browser/extensions.js +17 -17
  40. package/dist/browser/index.d.ts +4 -0
  41. package/dist/browser/index.js +4 -0
  42. package/dist/browser/profile.d.ts +10 -4
  43. package/dist/browser/profile.js +79 -12
  44. package/dist/browser/session-manager.d.ts +85 -0
  45. package/dist/browser/session-manager.js +208 -0
  46. package/dist/browser/session.d.ts +105 -9
  47. package/dist/browser/session.js +1166 -95
  48. package/dist/browser/types.d.ts +153 -156
  49. package/dist/browser/views.d.ts +39 -0
  50. package/dist/browser/views.js +32 -0
  51. package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
  52. package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
  53. package/dist/browser/watchdogs/base.d.ts +21 -0
  54. package/dist/browser/watchdogs/base.js +81 -0
  55. package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
  56. package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
  57. package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
  58. package/dist/browser/watchdogs/crash-watchdog.js +296 -0
  59. package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
  60. package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
  61. package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
  62. package/dist/browser/watchdogs/dom-watchdog.js +31 -0
  63. package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
  64. package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
  65. package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
  66. package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
  67. package/dist/browser/watchdogs/index.d.ts +15 -0
  68. package/dist/browser/watchdogs/index.js +15 -0
  69. package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
  70. package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
  71. package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
  72. package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
  73. package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
  74. package/dist/browser/watchdogs/popups-watchdog.js +77 -0
  75. package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
  76. package/dist/browser/watchdogs/recording-watchdog.js +249 -0
  77. package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
  78. package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
  79. package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
  80. package/dist/browser/watchdogs/security-watchdog.js +84 -0
  81. package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
  82. package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
  83. package/dist/cli.d.ts +7 -2
  84. package/dist/cli.js +182 -25
  85. package/dist/code-use/formatting.d.ts +3 -0
  86. package/dist/code-use/formatting.js +18 -0
  87. package/dist/code-use/index.d.ts +6 -0
  88. package/dist/code-use/index.js +6 -0
  89. package/dist/code-use/namespace.d.ts +5 -0
  90. package/dist/code-use/namespace.js +81 -0
  91. package/dist/code-use/notebook-export.d.ts +3 -0
  92. package/dist/code-use/notebook-export.js +56 -0
  93. package/dist/code-use/service.d.ts +24 -0
  94. package/dist/code-use/service.js +104 -0
  95. package/dist/code-use/utils.d.ts +4 -0
  96. package/dist/code-use/utils.js +98 -0
  97. package/dist/code-use/views.d.ts +108 -0
  98. package/dist/code-use/views.js +165 -0
  99. package/dist/config.d.ts +15 -0
  100. package/dist/config.js +109 -7
  101. package/dist/controller/registry/service.d.ts +10 -1
  102. package/dist/controller/registry/service.js +266 -10
  103. package/dist/controller/registry/views.d.ts +4 -1
  104. package/dist/controller/registry/views.js +25 -2
  105. package/dist/controller/service.d.ts +10 -1
  106. package/dist/controller/service.js +1814 -268
  107. package/dist/controller/views.d.ts +78 -155
  108. package/dist/controller/views.js +61 -12
  109. package/dist/dom/history-tree-processor/service.d.ts +5 -0
  110. package/dist/dom/history-tree-processor/service.js +169 -14
  111. package/dist/dom/history-tree-processor/view.d.ts +7 -1
  112. package/dist/dom/history-tree-processor/view.js +10 -1
  113. package/dist/dom/markdown-extractor.d.ts +37 -0
  114. package/dist/dom/markdown-extractor.js +345 -0
  115. package/dist/dom/service.d.ts +3 -1
  116. package/dist/dom/service.js +76 -0
  117. package/dist/dom/views.d.ts +1 -0
  118. package/dist/dom/views.js +45 -0
  119. package/dist/event-bus.d.ts +107 -7
  120. package/dist/event-bus.js +313 -10
  121. package/dist/exceptions.d.ts +0 -3
  122. package/dist/exceptions.js +0 -7
  123. package/dist/filesystem/file-system.d.ts +18 -0
  124. package/dist/filesystem/file-system.js +503 -42
  125. package/dist/index.d.ts +7 -0
  126. package/dist/index.js +6 -0
  127. package/dist/integrations/gmail/actions.d.ts +3 -3
  128. package/dist/integrations/gmail/actions.js +4 -4
  129. package/dist/llm/anthropic/chat.d.ts +18 -1
  130. package/dist/llm/anthropic/chat.js +123 -55
  131. package/dist/llm/anthropic/serializer.d.ts +2 -0
  132. package/dist/llm/anthropic/serializer.js +81 -9
  133. package/dist/llm/aws/chat-anthropic.d.ts +17 -0
  134. package/dist/llm/aws/chat-anthropic.js +126 -26
  135. package/dist/llm/aws/chat-bedrock.d.ts +28 -1
  136. package/dist/llm/aws/chat-bedrock.js +161 -34
  137. package/dist/llm/aws/serializer.d.ts +13 -1
  138. package/dist/llm/aws/serializer.js +56 -17
  139. package/dist/llm/azure/chat.d.ts +53 -2
  140. package/dist/llm/azure/chat.js +366 -54
  141. package/dist/llm/base.d.ts +2 -0
  142. package/dist/llm/browser-use/chat.d.ts +40 -0
  143. package/dist/llm/browser-use/chat.js +305 -0
  144. package/dist/llm/browser-use/index.d.ts +1 -0
  145. package/dist/llm/browser-use/index.js +1 -0
  146. package/dist/llm/cerebras/chat.d.ts +39 -0
  147. package/dist/llm/cerebras/chat.js +178 -0
  148. package/dist/llm/cerebras/index.d.ts +2 -0
  149. package/dist/llm/cerebras/index.js +2 -0
  150. package/dist/llm/cerebras/serializer.d.ts +7 -0
  151. package/dist/llm/cerebras/serializer.js +82 -0
  152. package/dist/llm/deepseek/chat.d.ts +19 -2
  153. package/dist/llm/deepseek/chat.js +138 -25
  154. package/dist/llm/google/chat.d.ts +46 -2
  155. package/dist/llm/google/chat.js +267 -64
  156. package/dist/llm/google/serializer.d.ts +9 -1
  157. package/dist/llm/google/serializer.js +141 -34
  158. package/dist/llm/groq/chat.d.ts +21 -2
  159. package/dist/llm/groq/chat.js +125 -26
  160. package/dist/llm/groq/parser.js +3 -1
  161. package/dist/llm/mistral/chat.d.ts +43 -0
  162. package/dist/llm/mistral/chat.js +154 -0
  163. package/dist/llm/mistral/index.d.ts +2 -0
  164. package/dist/llm/mistral/index.js +2 -0
  165. package/dist/llm/mistral/schema.d.ts +8 -0
  166. package/dist/llm/mistral/schema.js +27 -0
  167. package/dist/llm/models.d.ts +2 -0
  168. package/dist/llm/models.js +317 -0
  169. package/dist/llm/ollama/chat.d.ts +13 -1
  170. package/dist/llm/ollama/chat.js +110 -19
  171. package/dist/llm/ollama/serializer.d.ts +1 -0
  172. package/dist/llm/ollama/serializer.js +34 -12
  173. package/dist/llm/openai/chat.d.ts +16 -0
  174. package/dist/llm/openai/chat.js +94 -44
  175. package/dist/llm/openai/like.d.ts +5 -3
  176. package/dist/llm/openai/like.js +7 -3
  177. package/dist/llm/openai/responses-serializer.d.ts +18 -0
  178. package/dist/llm/openai/responses-serializer.js +72 -0
  179. package/dist/llm/openrouter/chat.d.ts +28 -2
  180. package/dist/llm/openrouter/chat.js +115 -29
  181. package/dist/llm/schema.d.ts +11 -1
  182. package/dist/llm/schema.js +109 -4
  183. package/dist/llm/vercel/chat.d.ts +50 -0
  184. package/dist/llm/vercel/chat.js +276 -0
  185. package/dist/llm/vercel/index.d.ts +1 -0
  186. package/dist/llm/vercel/index.js +1 -0
  187. package/dist/llm/vercel/serializer.d.ts +5 -0
  188. package/dist/llm/vercel/serializer.js +7 -0
  189. package/dist/llm/views.d.ts +2 -1
  190. package/dist/llm/views.js +3 -1
  191. package/dist/logging-config.d.ts +2 -0
  192. package/dist/logging-config.js +82 -29
  193. package/dist/mcp/client.d.ts +10 -5
  194. package/dist/mcp/client.js +14 -9
  195. package/dist/mcp/controller.d.ts +42 -3
  196. package/dist/mcp/controller.js +56 -31
  197. package/dist/mcp/server.d.ts +15 -0
  198. package/dist/mcp/server.js +261 -52
  199. package/dist/observability.js +10 -4
  200. package/dist/sandbox/index.d.ts +2 -0
  201. package/dist/sandbox/index.js +2 -0
  202. package/dist/sandbox/sandbox.d.ts +19 -0
  203. package/dist/sandbox/sandbox.js +140 -0
  204. package/dist/sandbox/views.d.ts +67 -0
  205. package/dist/sandbox/views.js +121 -0
  206. package/dist/skill-cli/index.d.ts +3 -0
  207. package/dist/skill-cli/index.js +3 -0
  208. package/dist/skill-cli/protocol.d.ts +30 -0
  209. package/dist/skill-cli/protocol.js +48 -0
  210. package/dist/skill-cli/server.d.ts +11 -0
  211. package/dist/skill-cli/server.js +85 -0
  212. package/dist/skill-cli/sessions.d.ts +24 -0
  213. package/dist/skill-cli/sessions.js +47 -0
  214. package/dist/skills/index.d.ts +3 -0
  215. package/dist/skills/index.js +3 -0
  216. package/dist/skills/service.d.ts +27 -0
  217. package/dist/skills/service.js +266 -0
  218. package/dist/skills/utils.d.ts +6 -0
  219. package/dist/skills/utils.js +53 -0
  220. package/dist/skills/views.d.ts +40 -0
  221. package/dist/skills/views.js +10 -0
  222. package/dist/sync/auth.js +8 -3
  223. package/dist/sync/service.d.ts +6 -6
  224. package/dist/sync/service.js +54 -89
  225. package/dist/telemetry/views.d.ts +20 -6
  226. package/dist/telemetry/views.js +23 -5
  227. package/dist/tokens/custom-pricing.d.ts +2 -0
  228. package/dist/tokens/custom-pricing.js +22 -0
  229. package/dist/tokens/index.d.ts +2 -0
  230. package/dist/tokens/index.js +2 -0
  231. package/dist/tokens/mappings.d.ts +1 -0
  232. package/dist/tokens/mappings.js +3 -0
  233. package/dist/tokens/service.js +27 -8
  234. package/dist/tools/extraction/index.d.ts +2 -0
  235. package/dist/tools/extraction/index.js +2 -0
  236. package/dist/tools/extraction/schema-utils.d.ts +6 -0
  237. package/dist/tools/extraction/schema-utils.js +237 -0
  238. package/dist/tools/extraction/views.d.ts +7 -0
  239. package/dist/tools/index.d.ts +5 -0
  240. package/dist/tools/index.js +5 -0
  241. package/dist/tools/registry/index.d.ts +2 -0
  242. package/dist/tools/registry/index.js +2 -0
  243. package/dist/tools/registry/service.d.ts +1 -0
  244. package/dist/tools/registry/service.js +1 -0
  245. package/dist/tools/registry/views.d.ts +1 -0
  246. package/dist/tools/registry/views.js +1 -0
  247. package/dist/tools/service.d.ts +2 -0
  248. package/dist/tools/service.js +1 -0
  249. package/dist/tools/utils.d.ts +2 -0
  250. package/dist/tools/utils.js +57 -0
  251. package/dist/tools/views.d.ts +1 -0
  252. package/dist/tools/views.js +1 -0
  253. package/dist/utils.d.ts +10 -1
  254. package/dist/utils.js +70 -3
  255. package/package.json +116 -49
  256. package/dist/dom/playground/process-dom.js +0 -5
  257. package/dist/dom/playground/test-accessibility.d.ts +0 -44
  258. package/dist/dom/playground/test-accessibility.js +0 -111
  259. /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
@@ -1,3 +1,5 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  const LEVEL_PRIORITY = {
2
4
  debug: 10,
3
5
  info: 20,
@@ -6,8 +8,17 @@ const LEVEL_PRIORITY = {
6
8
  error: 40,
7
9
  };
8
10
  let configured = false;
9
- let globalLevel = process.env.BROWSER_USE_LOGGING_LEVEL || 'info';
10
- let outputStream = process.stderr;
11
+ let consoleLevel = process.env.BROWSER_USE_LOGGING_LEVEL || 'info';
12
+ let consoleStream = process.stderr;
13
+ let debugLogStream = null;
14
+ let infoLogStream = null;
15
+ const normalizeLogLevel = (candidate, fallback) => {
16
+ if (!candidate) {
17
+ return fallback;
18
+ }
19
+ const normalized = candidate.toLowerCase();
20
+ return normalized in LEVEL_PRIORITY ? normalized : fallback;
21
+ };
11
22
  const formatMessage = (level, name, message) => {
12
23
  if (level === 'result') {
13
24
  return message;
@@ -15,39 +26,66 @@ const formatMessage = (level, name, message) => {
15
26
  const paddedLevel = level.toUpperCase().padEnd(7, ' ');
16
27
  return `${paddedLevel} [${name}] ${message}`;
17
28
  };
29
+ const formatFileMessage = (level, name, message) => `${new Date().toISOString()} ${formatMessage(level, name, message)}`;
30
+ const writePayload = (stream, level, payload) => {
31
+ if ('write' in stream) {
32
+ stream.write(`${payload}\n`);
33
+ return;
34
+ }
35
+ switch (level) {
36
+ case 'error':
37
+ console.error(payload);
38
+ break;
39
+ case 'warning':
40
+ console.warn(payload);
41
+ break;
42
+ default:
43
+ console.log(payload);
44
+ break;
45
+ }
46
+ };
47
+ const ensureFilePathReady = (filePath) => {
48
+ fs.mkdirSync(path.dirname(path.resolve(filePath)), { recursive: true });
49
+ };
50
+ const closeFileStreams = () => {
51
+ if (debugLogStream) {
52
+ debugLogStream.end();
53
+ debugLogStream = null;
54
+ }
55
+ if (infoLogStream) {
56
+ infoLogStream.end();
57
+ infoLogStream = null;
58
+ }
59
+ };
18
60
  export class Logger {
19
61
  name;
20
62
  constructor(name) {
21
63
  this.name = name;
22
64
  }
23
- shouldLog(level) {
24
- return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[globalLevel];
65
+ shouldLog(level, threshold) {
66
+ return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[threshold];
25
67
  }
26
68
  get level() {
27
- return globalLevel;
69
+ return consoleLevel;
28
70
  }
29
71
  emit(level, message, ...args) {
30
- if (!this.shouldLog(level)) {
31
- return;
32
- }
72
+ const argsPayload = args.length
73
+ ? args
74
+ .map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg)))
75
+ .join(' ')
76
+ : '';
33
77
  const formatted = formatMessage(level, this.name, message);
34
- const payload = args.length
35
- ? `${formatted} ${args.map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg))).join(' ')}`
36
- : formatted;
37
- if ('write' in outputStream) {
38
- outputStream.write(`${payload}\n`);
78
+ const payload = argsPayload ? `${formatted} ${argsPayload}` : formatted;
79
+ if (this.shouldLog(level, consoleLevel)) {
80
+ writePayload(consoleStream, level, payload);
39
81
  }
40
- else {
41
- switch (level) {
42
- case 'error':
43
- console.error(payload);
44
- break;
45
- case 'warning':
46
- console.warn(payload);
47
- break;
48
- default:
49
- console.log(payload);
50
- }
82
+ if (debugLogStream && this.shouldLog(level, 'debug')) {
83
+ const filePayload = formatFileMessage(level, this.name, message);
84
+ debugLogStream.write(`${argsPayload ? `${filePayload} ${argsPayload}` : filePayload}\n`);
85
+ }
86
+ if (infoLogStream && this.shouldLog(level, 'info')) {
87
+ const filePayload = formatFileMessage(level, this.name, message);
88
+ infoLogStream.write(`${argsPayload ? `${filePayload} ${argsPayload}` : filePayload}\n`);
51
89
  }
52
90
  }
53
91
  debug(message, ...args) {
@@ -78,12 +116,27 @@ export const setupLogging = (options = {}) => {
78
116
  if (configured && !options.forceSetup) {
79
117
  return createLogger('browser_use');
80
118
  }
81
- globalLevel =
82
- options.logLevel ||
83
- process.env.BROWSER_USE_LOGGING_LEVEL ||
84
- 'info';
85
- outputStream = options.stream || process.stderr;
119
+ closeFileStreams();
120
+ consoleLevel = normalizeLogLevel(options.logLevel ?? process.env.BROWSER_USE_LOGGING_LEVEL, 'info');
121
+ consoleStream = options.stream || process.stderr;
122
+ const debugLogFile = options.debugLogFile ?? process.env.BROWSER_USE_DEBUG_LOG_FILE ?? null;
123
+ if (debugLogFile && debugLogFile.trim().length > 0) {
124
+ ensureFilePathReady(debugLogFile);
125
+ debugLogStream = fs.createWriteStream(path.resolve(debugLogFile), {
126
+ flags: 'a',
127
+ encoding: 'utf-8',
128
+ });
129
+ }
130
+ const infoLogFile = options.infoLogFile ?? process.env.BROWSER_USE_INFO_LOG_FILE ?? null;
131
+ if (infoLogFile && infoLogFile.trim().length > 0) {
132
+ ensureFilePathReady(infoLogFile);
133
+ infoLogStream = fs.createWriteStream(path.resolve(infoLogFile), {
134
+ flags: 'a',
135
+ encoding: 'utf-8',
136
+ });
137
+ }
86
138
  configured = true;
87
139
  return createLogger('browser_use');
88
140
  };
141
+ setupLogging();
89
142
  export const logger = createLogger('browser_use');
@@ -5,10 +5,10 @@
5
5
  * MCP tools are dynamically discovered and registered as browser-use actions.
6
6
  *
7
7
  * Example usage:
8
- * import { Controller } from './controller/service.js';
8
+ * import { Tools } from './tools/service.js';
9
9
  * import { MCPClient } from './mcp/client.js';
10
10
  *
11
- * const controller = new Controller();
11
+ * const tools = new Tools();
12
12
  *
13
13
  * // Connect to an MCP server
14
14
  * const mcpClient = new MCPClient(
@@ -18,12 +18,13 @@
18
18
  * );
19
19
  *
20
20
  * // Register all MCP tools as browser-use actions
21
- * await mcpClient.registerToController(controller);
21
+ * await mcpClient.registerToTools(tools);
22
22
  *
23
23
  * // Now use with Agent as normal - MCP tools are available as actions
24
24
  */
25
25
  import { type Tool, type Prompt } from '@modelcontextprotocol/sdk/types.js';
26
26
  import type { Controller } from '../controller/service.js';
27
+ import type { Tools } from '../tools/service.js';
27
28
  export interface MCPClientOptions {
28
29
  /** Maximum number of connection retry attempts (default: 3) */
29
30
  maxRetries?: number;
@@ -76,12 +77,16 @@ export declare class MCPClient {
76
77
  */
77
78
  callTool(name: string, args: any): Promise<any>;
78
79
  /**
79
- * Register MCP tools as actions in the browser-use controller
80
+ * Register MCP tools as actions in browser-use tools.
80
81
  *
81
- * @param controller - Browser-use controller to register actions to
82
+ * @param tools - Browser-use tools to register actions to
82
83
  * @param toolFilter - Optional list of tool names to register (undefined = all tools)
83
84
  * @param prefix - Optional prefix to add to action names (e.g., "playwright_")
84
85
  */
86
+ registerToTools(tools: Pick<Tools, 'registry'>, toolFilter?: string[], prefix?: string): Promise<void>;
87
+ /**
88
+ * @deprecated Use `registerToTools` instead.
89
+ */
85
90
  registerToController(controller: Controller<any>, toolFilter?: string[], prefix?: string): Promise<void>;
86
91
  private _registerToolAsAction;
87
92
  private _convertToolSchemaToParamModel;
@@ -5,10 +5,10 @@
5
5
  * MCP tools are dynamically discovered and registered as browser-use actions.
6
6
  *
7
7
  * Example usage:
8
- * import { Controller } from './controller/service.js';
8
+ * import { Tools } from './tools/service.js';
9
9
  * import { MCPClient } from './mcp/client.js';
10
10
  *
11
- * const controller = new Controller();
11
+ * const tools = new Tools();
12
12
  *
13
13
  * // Connect to an MCP server
14
14
  * const mcpClient = new MCPClient(
@@ -18,7 +18,7 @@
18
18
  * );
19
19
  *
20
20
  * // Register all MCP tools as browser-use actions
21
- * await mcpClient.registerToController(controller);
21
+ * await mcpClient.registerToTools(tools);
22
22
  *
23
23
  * // Now use with Agent as normal - MCP tools are available as actions
24
24
  */
@@ -250,17 +250,17 @@ export class MCPClient {
250
250
  }
251
251
  }
252
252
  /**
253
- * Register MCP tools as actions in the browser-use controller
253
+ * Register MCP tools as actions in browser-use tools.
254
254
  *
255
- * @param controller - Browser-use controller to register actions to
255
+ * @param tools - Browser-use tools to register actions to
256
256
  * @param toolFilter - Optional list of tool names to register (undefined = all tools)
257
257
  * @param prefix - Optional prefix to add to action names (e.g., "playwright_")
258
258
  */
259
- async registerToController(controller, toolFilter, prefix) {
259
+ async registerToTools(tools, toolFilter, prefix) {
260
260
  if (!this._connected) {
261
261
  await this.connect();
262
262
  }
263
- const registry = controller.registry;
263
+ const registry = tools.registry;
264
264
  for (const [toolName, tool] of this._tools.entries()) {
265
265
  // Skip if not in filter
266
266
  if (toolFilter && !toolFilter.includes(toolName)) {
@@ -278,6 +278,12 @@ export class MCPClient {
278
278
  }
279
279
  logger.info(`✅ Registered ${this._registeredActions.size} MCP tools from '${this.serverName}' as browser-use actions`);
280
280
  }
281
+ /**
282
+ * @deprecated Use `registerToTools` instead.
283
+ */
284
+ async registerToController(controller, toolFilter, prefix) {
285
+ await this.registerToTools(controller, toolFilter, prefix);
286
+ }
281
287
  _registerToolAsAction(registry, actionName, tool) {
282
288
  /**
283
289
  * Register a single MCP tool as a browser-use action
@@ -291,7 +297,6 @@ export class MCPClient {
291
297
  });
292
298
  }
293
299
  const startTime = Date.now() / 1000;
294
- let errorMsg = null;
295
300
  try {
296
301
  // Call the MCP tool
297
302
  const result = await this.callTool(tool.name, params || {});
@@ -303,7 +308,7 @@ export class MCPClient {
303
308
  });
304
309
  }
305
310
  catch (error) {
306
- errorMsg = error instanceof Error ? error.message : String(error);
311
+ const errorMsg = error instanceof Error ? error.message : String(error);
307
312
  logger.error(`MCP tool '${tool.name}' failed: ${errorMsg}`);
308
313
  return new ActionResult({
309
314
  error: `MCP tool '${tool.name}' failed: ${errorMsg}`,
@@ -1,6 +1,45 @@
1
+ import type { Registry } from '../tools/registry/service.js';
2
+ import type { Tools } from '../tools/service.js';
3
+ import { MCPClient, type MCPClientOptions } from './client.js';
4
+ export interface MCPToolWrapperOptions {
5
+ serverName?: string;
6
+ env?: Record<string, string>;
7
+ clientOptions?: MCPClientOptions;
8
+ }
9
+ export declare class MCPToolWrapper {
10
+ private registry;
11
+ private client;
12
+ constructor(registry: Registry, mcpCommand: string, mcpArgs?: string[], options?: MCPToolWrapperOptions);
13
+ connect(toolFilter?: string[], prefix?: string, tools?: Pick<Tools, 'registry'>): Promise<void>;
14
+ disconnect(): Promise<void>;
15
+ getClient(): MCPClient;
16
+ getStats(): {
17
+ serverName: string;
18
+ connected: boolean;
19
+ toolsDiscovered: number;
20
+ promptsDiscovered: number;
21
+ toolCallCount: number;
22
+ errorCount: number;
23
+ successRate: number;
24
+ uptime?: number;
25
+ lastHealthCheck?: number;
26
+ };
27
+ }
28
+ export declare function registerMcpTools(registry: Registry, mcpCommand: string, mcpArgs?: string[], options?: MCPToolWrapperOptions): Promise<MCPToolWrapper>;
29
+ export interface AddMCPServerOptions {
30
+ serverName?: string;
31
+ env?: Record<string, string>;
32
+ clientOptions?: MCPClientOptions;
33
+ toolFilter?: string[];
34
+ prefix?: string;
35
+ tools?: Pick<Tools, 'registry'>;
36
+ }
1
37
  export declare class MCPController {
2
38
  private clients;
3
- constructor();
4
- addServer(command: string, args: string[]): Promise<void>;
5
- private registerTools;
39
+ private tools;
40
+ constructor(tools?: Pick<Tools, 'registry'> | null);
41
+ setTools(tools: Pick<Tools, 'registry'>): void;
42
+ addServer(command: string, args?: string[], options?: AddMCPServerOptions): Promise<MCPClient>;
43
+ getClients(): MCPClient[];
44
+ disconnectAll(): Promise<void>;
6
45
  }
@@ -1,38 +1,63 @@
1
+ import { createLogger } from '../logging-config.js';
1
2
  import { MCPClient } from './client.js';
2
- import { z } from 'zod';
3
- // This controller integrates MCP tools into the browser-use registry
3
+ const logger = createLogger('browser_use.mcp.controller');
4
+ export class MCPToolWrapper {
5
+ registry;
6
+ client;
7
+ constructor(registry, mcpCommand, mcpArgs = [], options = {}) {
8
+ this.registry = registry;
9
+ this.client = new MCPClient(options.serverName ?? 'browser-use-mcp-tools', mcpCommand, mcpArgs, options.env, options.clientOptions);
10
+ }
11
+ async connect(toolFilter, prefix, tools) {
12
+ if (!this.client.isConnected()) {
13
+ await this.client.connect();
14
+ }
15
+ const targetTools = tools ?? { registry: this.registry };
16
+ await this.client.registerToTools(targetTools, toolFilter, prefix);
17
+ }
18
+ async disconnect() {
19
+ await this.client.disconnect();
20
+ }
21
+ getClient() {
22
+ return this.client;
23
+ }
24
+ getStats() {
25
+ return this.client.getStats();
26
+ }
27
+ }
28
+ export async function registerMcpTools(registry, mcpCommand, mcpArgs = [], options = {}) {
29
+ const wrapper = new MCPToolWrapper(registry, mcpCommand, mcpArgs, options);
30
+ await wrapper.connect();
31
+ return wrapper;
32
+ }
33
+ // Backward-compatible helper that can manage multiple MCP clients.
4
34
  export class MCPController {
5
35
  clients = [];
6
- constructor() { }
7
- async addServer(command, args) {
8
- const client = new MCPClient('browser-use-client', command, args);
36
+ tools;
37
+ constructor(tools = null) {
38
+ this.tools = tools;
39
+ }
40
+ setTools(tools) {
41
+ this.tools = tools;
42
+ }
43
+ async addServer(command, args = [], options = {}) {
44
+ const client = new MCPClient(options.serverName ?? `browser-use-client-${this.clients.length + 1}`, command, args, options.env, options.clientOptions);
9
45
  await client.connect();
10
- this.clients.push(client);
11
- await this.registerTools(client);
12
- }
13
- async registerTools(client) {
14
- const tools = await client.listTools();
15
- for (const tool of tools) {
16
- // We need to convert JSON schema to Zod schema dynamically if we want to validate
17
- // For now, we might just use a generic schema or skip validation at the registry level
18
- // and let the MCP server validate.
19
- // However, the Registry expects a Zod schema.
20
- // We can create a dynamic Zod schema that accepts anything if we can't easily convert.
21
- // Or we can try to convert using json-schema-to-zod (if we had it) or just use z.any()
22
- const paramModel = z.any().describe(tool.description || '');
23
- // Register the action
24
- // Note: We need to access the singleton registry or pass it in.
25
- // Assuming we can use the decorator or manual registration.
26
- // Since we are registering dynamically, we might need a method on Registry to register actions at runtime.
27
- // Let's assume Registry has a static method or we can access the instance.
28
- // In the migration plan, Registry is a class.
29
- // We might need to modify Registry to support runtime registration if it doesn't already.
30
- // But wait, the Registry in `src/controller/registry/service.ts` has an `action` method which is a decorator.
31
- // It also has a `registry` property which holds the actions.
32
- // We'll assume we can access the global registry or pass it to this controller.
33
- // For now, I'll just log it as a placeholder for actual registration logic which might require
34
- // more complex integration with the Controller class.
35
- console.log(`Discovered MCP tool: ${tool.name}`);
46
+ const targetTools = options.tools ?? this.tools;
47
+ if (targetTools) {
48
+ await client.registerToTools(targetTools, options.toolFilter, options.prefix);
49
+ }
50
+ else {
51
+ logger.warning('MCPController.addServer connected but skipped tool registration because no Tools instance was provided');
36
52
  }
53
+ this.clients.push(client);
54
+ return client;
55
+ }
56
+ getClients() {
57
+ return [...this.clients];
58
+ }
59
+ async disconnectAll() {
60
+ await Promise.all(this.clients.map((client) => client.disconnect()));
61
+ this.clients = [];
37
62
  }
38
63
  }
@@ -50,16 +50,31 @@ export declare class MCPServer {
50
50
  private toolExecutionCount;
51
51
  private errorCount;
52
52
  private abortController;
53
+ private activeSessions;
54
+ private sessionTimeoutMinutes;
55
+ private sessionCleanupInterval;
53
56
  constructor(name: string, version: string);
54
57
  private resolvePath;
55
58
  private getDefaultProfileConfig;
56
59
  private getDefaultLlmConfig;
60
+ private isPlaceholderOpenAiApiKey;
61
+ private seedOpenAiApiKeyFromConfig;
62
+ private createLlmFromModelName;
57
63
  private sanitizeProfileConfig;
58
64
  private buildDirectSessionProfile;
59
65
  private buildRetryProfile;
60
66
  private initializeLlmForDirectTools;
61
67
  private initializeFileSystem;
62
68
  private formatRetryResult;
69
+ private trackSession;
70
+ private updateSessionActivity;
71
+ private serializeTrackedSessions;
72
+ private shutdownSession;
73
+ private closeSessionById;
74
+ private closeAllTrackedSessions;
75
+ private cleanupExpiredSessions;
76
+ private startSessionCleanupLoop;
77
+ private stopSessionCleanupLoop;
63
78
  private setupHandlers;
64
79
  private ensureController;
65
80
  private ensureBrowserSession;