agent-browser-bridge 2.0.0 → 2.2.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.
@@ -0,0 +1,186 @@
1
+ // Agent Bridge MCP - Tab, Window & Profile Tools (ES Module)
2
+ import { z } from "zod";
3
+ import { activeProfiles, jsonResult } from "../core/state.js";
4
+ import { ensureMasterOrRelay, callProfileExtension } from "../core/bridge.js";
5
+
6
+ export function registerTabTools(server) {
7
+ server.registerTool(
8
+ "browser_list_profiles",
9
+ {
10
+ description: "List all currently connected browser profiles (e.g. Work, Personal, Brave, Edge), their IDs, names, and active status.",
11
+ },
12
+ async () => {
13
+ await ensureMasterOrRelay();
14
+ const profiles = Array.from(activeProfiles.values()).map((p) => ({
15
+ id: p.id,
16
+ name: p.name,
17
+ browser: p.browser,
18
+ connectedAt: new Date(p.connectedAt).toISOString(),
19
+ lastActive: new Date(p.lastActive).toISOString(),
20
+ }));
21
+ return jsonResult({ count: profiles.length, profiles });
22
+ }
23
+ );
24
+
25
+ server.registerTool(
26
+ "browser_list_tabs",
27
+ {
28
+ description: "List all open tabs in a browser profile with their IDs, titles, URLs, active state, and debugger attachment status.",
29
+ inputSchema: {
30
+ profile: z.string().optional().describe("Target browser profile name or ID (defaults to active/most recent)"),
31
+ },
32
+ },
33
+ async ({ profile }) => {
34
+ const tabs = await callProfileExtension(profile, "list_tabs");
35
+ return jsonResult(tabs);
36
+ }
37
+ );
38
+
39
+ server.registerTool(
40
+ "browser_switch_tab",
41
+ {
42
+ description: "Switch to and focus a specific tab by tabId, bringing its browser window to the foreground.",
43
+ inputSchema: {
44
+ profile: z.string().optional().describe("Target browser profile"),
45
+ tabId: z.number().describe("The ID of the tab to focus"),
46
+ },
47
+ },
48
+ async ({ profile, tabId }) => {
49
+ const res = await callProfileExtension(profile, "switch_tab", { tabId });
50
+ return jsonResult(res);
51
+ }
52
+ );
53
+
54
+ server.registerTool(
55
+ "browser_new_tab",
56
+ {
57
+ description: "Open a new tab with an optional URL in the browser profile.",
58
+ inputSchema: {
59
+ profile: z.string().optional().describe("Target browser profile"),
60
+ url: z.string().optional().describe("URL to open (defaults to about:blank)"),
61
+ active: z.boolean().optional().describe("Whether to immediately focus the tab (default true)"),
62
+ },
63
+ },
64
+ async ({ profile, url, active }) => {
65
+ const res = await callProfileExtension(profile, "new_tab", { url, active });
66
+ return jsonResult(res);
67
+ }
68
+ );
69
+
70
+ server.registerTool(
71
+ "browser_close_tab",
72
+ {
73
+ description: "Close an open tab by tabId.",
74
+ inputSchema: {
75
+ profile: z.string().optional().describe("Target browser profile"),
76
+ tabId: z.number().describe("The ID of the tab to close"),
77
+ },
78
+ },
79
+ async ({ profile, tabId }) => {
80
+ const res = await callProfileExtension(profile, "close_tab", { tabId });
81
+ return jsonResult(res);
82
+ }
83
+ );
84
+
85
+ server.registerTool(
86
+ "browser_duplicate_tab",
87
+ {
88
+ description: "Duplicate an existing browser tab with all its history and loaded state.",
89
+ inputSchema: {
90
+ profile: z.string().optional().describe("Target browser profile"),
91
+ tabId: z.number().describe("The ID of the tab to duplicate"),
92
+ },
93
+ },
94
+ async ({ profile, tabId }) => {
95
+ const res = await callProfileExtension(profile, "duplicate_tab", { tabId });
96
+ return jsonResult(res);
97
+ }
98
+ );
99
+
100
+ server.registerTool(
101
+ "browser_pin_tab",
102
+ {
103
+ description: "Pin or unpin a tab to dock it in the browser's persistent tab strip.",
104
+ inputSchema: {
105
+ profile: z.string().optional().describe("Target browser profile"),
106
+ tabId: z.number().describe("The ID of the tab to pin/unpin"),
107
+ pinned: z.boolean().describe("Whether the tab should be pinned (true) or unpinned (false)"),
108
+ },
109
+ },
110
+ async ({ profile, tabId, pinned }) => {
111
+ const res = await callProfileExtension(profile, "pin_tab", { tabId, pinned });
112
+ return jsonResult(res);
113
+ }
114
+ );
115
+
116
+ server.registerTool(
117
+ "browser_set_zoom",
118
+ {
119
+ description: "Get or set the zoom level factor for a browser tab (e.g. 1.0 for 100%, 1.25 for 125%, 0.8 for 80%).",
120
+ inputSchema: {
121
+ profile: z.string().optional().describe("Target browser profile"),
122
+ tabId: z.number().describe("The ID of the tab to adjust zoom for"),
123
+ zoomFactor: z.number().optional().describe("Zoom factor (e.g. 1.0, 1.25, 1.5). Omit to read current zoom factor."),
124
+ },
125
+ },
126
+ async ({ profile, tabId, zoomFactor }) => {
127
+ const res = await callProfileExtension(profile, "set_zoom", { tabId, zoomFactor });
128
+ return jsonResult(res);
129
+ }
130
+ );
131
+
132
+ server.registerTool(
133
+ "browser_scroll",
134
+ {
135
+ description: "Scroll the page or a scrollable container in any direction (up, down, left, right, top, bottom) or scroll a specific ref/selector into view.",
136
+ inputSchema: {
137
+ profile: z.string().optional().describe("Target browser profile"),
138
+ tabId: z.number().describe("Target tabId"),
139
+ direction: z.enum(["up", "down", "left", "right", "top", "bottom"]).optional().describe("Scroll direction (default 'down')"),
140
+ distance: z.number().optional().describe("Scroll distance in pixels (default 500)"),
141
+ target: z.string().optional().describe("Target element data-agent-ref (e.g. 'ref_1') or CSS selector to scroll into view or scroll inside"),
142
+ smooth: z.boolean().optional().describe("Whether to animate scrolling smoothly (default false)"),
143
+ x: z.number().optional().describe("Direct absolute X coordinate to scroll to"),
144
+ y: z.number().optional().describe("Direct absolute Y coordinate to scroll to"),
145
+ },
146
+ },
147
+ async ({ profile, tabId, direction, distance, target, smooth, x, y }) => {
148
+ const res = await callProfileExtension(profile, "scroll", { tabId, direction, distance, target, smooth, x, y });
149
+ return jsonResult(res);
150
+ }
151
+ );
152
+
153
+ server.registerTool(
154
+ "browser_read_all_tabs",
155
+ {
156
+ description: "Extract readable text content and titles from all open tabs in a single batch call. Fast multi-tab triage.",
157
+ inputSchema: {
158
+ profile: z.string().optional().describe("Target browser profile"),
159
+ maxLength: z.number().optional().describe("Max text characters per tab (default 4000)"),
160
+ },
161
+ },
162
+ async ({ profile, maxLength }) => {
163
+ const res = await callProfileExtension(profile, "read_all_tabs", { maxLength });
164
+ return jsonResult(res);
165
+ }
166
+ );
167
+
168
+ server.registerTool(
169
+ "browser_manage_tab_group",
170
+ {
171
+ description: "Organize tabs into Chrome tab groups, colorize them, collapse/expand, or ungroup.",
172
+ inputSchema: {
173
+ profile: z.string().optional().describe("Target browser profile"),
174
+ action: z.enum(["group", "ungroup", "collapse", "expand"]).optional().describe("Action to perform (default 'group')"),
175
+ tabIds: z.array(z.number()).describe("Array of tab IDs to group or ungroup"),
176
+ title: z.string().optional().describe("Title for the tab group (e.g. 'Mercor Research')"),
177
+ color: z.enum(["grey", "blue", "red", "yellow", "green", "pink", "purple", "cyan", "orange"]).optional().describe("Color for the tab group"),
178
+ },
179
+ },
180
+ async ({ profile, action, tabIds, title, color }) => {
181
+ const res = await callProfileExtension(profile, "manage_tab_group", { action, tabIds, title, color });
182
+ return jsonResult(res);
183
+ }
184
+ );
185
+ }
186
+