ultimate-playwright-mcp 0.1.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.
- package/LICENSE +26 -0
- package/README.md +286 -0
- package/dist/browser/cdp.d.ts +37 -0
- package/dist/browser/cdp.d.ts.map +1 -0
- package/dist/browser/cdp.helpers.d.ts +13 -0
- package/dist/browser/cdp.helpers.d.ts.map +1 -0
- package/dist/browser/cdp.helpers.js +38 -0
- package/dist/browser/cdp.helpers.js.map +1 -0
- package/dist/browser/cdp.js +77 -0
- package/dist/browser/cdp.js.map +1 -0
- package/dist/browser/chrome-tab-groups.d.ts +93 -0
- package/dist/browser/chrome-tab-groups.d.ts.map +1 -0
- package/dist/browser/chrome-tab-groups.js +458 -0
- package/dist/browser/chrome-tab-groups.js.map +1 -0
- package/dist/browser/chrome.d.ts +11 -0
- package/dist/browser/chrome.d.ts.map +1 -0
- package/dist/browser/chrome.js +74 -0
- package/dist/browser/chrome.js.map +1 -0
- package/dist/browser/pw-role-snapshot.d.ts +41 -0
- package/dist/browser/pw-role-snapshot.d.ts.map +1 -0
- package/dist/browser/pw-role-snapshot.js +346 -0
- package/dist/browser/pw-role-snapshot.js.map +1 -0
- package/dist/browser/pw-session.d.ts +145 -0
- package/dist/browser/pw-session.d.ts.map +1 -0
- package/dist/browser/pw-session.js +468 -0
- package/dist/browser/pw-session.js.map +1 -0
- package/dist/browser/pw-tools-activity.d.ts +27 -0
- package/dist/browser/pw-tools-activity.d.ts.map +1 -0
- package/dist/browser/pw-tools-activity.js +52 -0
- package/dist/browser/pw-tools-activity.js.map +1 -0
- package/dist/browser/pw-tools-downloads.d.ts +40 -0
- package/dist/browser/pw-tools-downloads.d.ts.map +1 -0
- package/dist/browser/pw-tools-downloads.js +191 -0
- package/dist/browser/pw-tools-downloads.js.map +1 -0
- package/dist/browser/pw-tools-interactions.d.ts +122 -0
- package/dist/browser/pw-tools-interactions.d.ts.map +1 -0
- package/dist/browser/pw-tools-interactions.js +434 -0
- package/dist/browser/pw-tools-interactions.js.map +1 -0
- package/dist/browser/pw-tools-responses.d.ts +19 -0
- package/dist/browser/pw-tools-responses.d.ts.map +1 -0
- package/dist/browser/pw-tools-responses.js +98 -0
- package/dist/browser/pw-tools-responses.js.map +1 -0
- package/dist/browser/pw-tools-shared.d.ts +12 -0
- package/dist/browser/pw-tools-shared.d.ts.map +1 -0
- package/dist/browser/pw-tools-shared.js +55 -0
- package/dist/browser/pw-tools-shared.js.map +1 -0
- package/dist/browser/pw-tools-snapshot.d.ts +70 -0
- package/dist/browser/pw-tools-snapshot.d.ts.map +1 -0
- package/dist/browser/pw-tools-snapshot.js +151 -0
- package/dist/browser/pw-tools-snapshot.js.map +1 -0
- package/dist/browser/pw-tools-state.d.ts +52 -0
- package/dist/browser/pw-tools-state.d.ts.map +1 -0
- package/dist/browser/pw-tools-state.js +159 -0
- package/dist/browser/pw-tools-state.js.map +1 -0
- package/dist/browser/pw-tools-storage.d.ts +53 -0
- package/dist/browser/pw-tools-storage.d.ts.map +1 -0
- package/dist/browser/pw-tools-storage.js +81 -0
- package/dist/browser/pw-tools-storage.js.map +1 -0
- package/dist/browser/pw-tools-trace.d.ts +18 -0
- package/dist/browser/pw-tools-trace.d.ts.map +1 -0
- package/dist/browser/pw-tools-trace.js +31 -0
- package/dist/browser/pw-tools-trace.js.map +1 -0
- package/dist/browser/tab-groups.d.ts +94 -0
- package/dist/browser/tab-groups.d.ts.map +1 -0
- package/dist/browser/tab-groups.js +303 -0
- package/dist/browser/tab-groups.js.map +1 -0
- package/dist/browser/target-id.d.ts +20 -0
- package/dist/browser/target-id.d.ts.map +1 -0
- package/dist/browser/target-id.js +29 -0
- package/dist/browser/target-id.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/chrome-daemon.d.ts +7 -0
- package/dist/daemon/chrome-daemon.d.ts.map +1 -0
- package/dist/daemon/chrome-daemon.js +264 -0
- package/dist/daemon/chrome-daemon.js.map +1 -0
- package/dist/daemon/cli.d.ts +6 -0
- package/dist/daemon/cli.d.ts.map +1 -0
- package/dist/daemon/cli.js +110 -0
- package/dist/daemon/cli.js.map +1 -0
- package/dist/daemon/manager.d.ts +22 -0
- package/dist/daemon/manager.d.ts.map +1 -0
- package/dist/daemon/manager.js +89 -0
- package/dist/daemon/manager.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +41 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +122 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/actions.d.ts +6 -0
- package/dist/mcp/tools/actions.d.ts.map +1 -0
- package/dist/mcp/tools/actions.js +214 -0
- package/dist/mcp/tools/actions.js.map +1 -0
- package/dist/mcp/tools/navigate.d.ts +6 -0
- package/dist/mcp/tools/navigate.d.ts.map +1 -0
- package/dist/mcp/tools/navigate.js +31 -0
- package/dist/mcp/tools/navigate.js.map +1 -0
- package/dist/mcp/tools/snapshot.d.ts +6 -0
- package/dist/mcp/tools/snapshot.d.ts.map +1 -0
- package/dist/mcp/tools/snapshot.js +26 -0
- package/dist/mcp/tools/snapshot.js.map +1 -0
- package/dist/mcp/tools/tab-group.d.ts +9 -0
- package/dist/mcp/tools/tab-group.d.ts.map +1 -0
- package/dist/mcp/tools/tab-group.js +173 -0
- package/dist/mcp/tools/tab-group.js.map +1 -0
- package/dist/mcp/tools/tabs.d.ts +6 -0
- package/dist/mcp/tools/tabs.d.ts.map +1 -0
- package/dist/mcp/tools/tabs.js +209 -0
- package/dist/mcp/tools/tabs.js.map +1 -0
- package/dist/utils/command-format.d.ts +6 -0
- package/dist/utils/command-format.d.ts.map +1 -0
- package/dist/utils/command-format.js +8 -0
- package/dist/utils/command-format.js.map +1 -0
- package/dist/utils/errors.d.ts +6 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +22 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/extension-installer.d.ts +16 -0
- package/dist/utils/extension-installer.d.ts.map +1 -0
- package/dist/utils/extension-installer.js +134 -0
- package/dist/utils/extension-installer.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-group.js","sourceRoot":"","sources":["../../../src/mcp/tools/tab-group.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* browser_tabs tool - manage browser tabs with targetId-based isolation and tab group support
|
|
3
|
+
*/
|
|
4
|
+
import type { ServerConfig } from "../../config.js";
|
|
5
|
+
export declare function registerBrowserTabsTool(register: (name: string, description: string, schema: any, handler: (args: any) => Promise<any>) => void, config: ServerConfig): void;
|
|
6
|
+
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/tabs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwBpD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EACxG,MAAM,EAAE,YAAY,QAgQrB"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* browser_tabs tool - manage browser tabs with targetId-based isolation and tab group support
|
|
3
|
+
*/
|
|
4
|
+
import { listPagesViaPlaywright, createPageViaPlaywright, closePageByTargetIdViaPlaywright, focusPageByTargetIdViaPlaywright, } from "../../browser/pw-session.js";
|
|
5
|
+
import { addTabToGroup, removeTabFromGroup, getTabsInGroup, getGroupForTab, getTabGroup, pruneStaleTargets, setChromeGroupId, getChromeTabId, } from "../../browser/tab-groups.js";
|
|
6
|
+
import { groupTabsVisually, isTabGrouperAvailable, createTabViaExtension, closeTabViaExtension, } from "../../browser/chrome-tab-groups.js";
|
|
7
|
+
export function registerBrowserTabsTool(register, config) {
|
|
8
|
+
register("browser_tabs", "Manage browser tabs. When using tab groups (recommended for multi-user), pass groupId to " +
|
|
9
|
+
"scope operations to your group's tabs only.\n\n" +
|
|
10
|
+
"Actions:\n" +
|
|
11
|
+
"- 'list': Show tabs. With groupId → only your group's tabs. Without → all tabs.\n" +
|
|
12
|
+
"- 'new': Create a tab. **Requires groupId** — tab is added to that group. Returns targetId.\n" +
|
|
13
|
+
"- 'close': Close a tab by index or targetId.\n" +
|
|
14
|
+
"- 'select': Focus a tab by index or targetId.\n\n" +
|
|
15
|
+
"⚡ IMPORTANT: Always create a tab group first with browser_tab_group, then use the groupId here.", {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
action: {
|
|
19
|
+
type: "string",
|
|
20
|
+
enum: ["list", "new", "close", "select"],
|
|
21
|
+
description: "Tab action to perform",
|
|
22
|
+
},
|
|
23
|
+
groupId: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "Tab group ID to scope this operation to (from browser_tab_group). " +
|
|
26
|
+
"Recommended for multi-user isolation.",
|
|
27
|
+
},
|
|
28
|
+
url: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "URL for 'new' action (defaults to about:blank)",
|
|
31
|
+
},
|
|
32
|
+
index: {
|
|
33
|
+
type: "number",
|
|
34
|
+
description: "Tab index for 'close' or 'select' actions (relative to group if groupId is set)",
|
|
35
|
+
},
|
|
36
|
+
targetId: {
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "Target ID for 'close' or 'select' actions (alternative to index)",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
required: ["action"],
|
|
42
|
+
}, async (args) => {
|
|
43
|
+
if (!config.cdpEndpoint) {
|
|
44
|
+
throw new Error("CDP endpoint not configured");
|
|
45
|
+
}
|
|
46
|
+
const { action, groupId, url, index, targetId } = args;
|
|
47
|
+
// Helper: get tabs scoped to group (or all tabs)
|
|
48
|
+
async function getScopedTabs() {
|
|
49
|
+
const allTabs = await listPagesViaPlaywright({ cdpUrl: config.cdpEndpoint });
|
|
50
|
+
// Prune stale entries from registry
|
|
51
|
+
const liveIds = new Set(allTabs.map((t) => t.targetId));
|
|
52
|
+
pruneStaleTargets(liveIds);
|
|
53
|
+
if (!groupId) {
|
|
54
|
+
return allTabs;
|
|
55
|
+
}
|
|
56
|
+
// Validate group exists
|
|
57
|
+
const group = getTabGroup(groupId);
|
|
58
|
+
if (!group) {
|
|
59
|
+
throw new Error(`Tab group not found: ${groupId}. Create one first with browser_tab_group.`);
|
|
60
|
+
}
|
|
61
|
+
const groupTargetIds = new Set(getTabsInGroup(groupId));
|
|
62
|
+
return allTabs.filter((t) => groupTargetIds.has(t.targetId));
|
|
63
|
+
}
|
|
64
|
+
// Helper: resolve target from index or targetId, respecting group scope
|
|
65
|
+
async function resolveTarget(scopedTabs) {
|
|
66
|
+
if (targetId) {
|
|
67
|
+
// If groupId set, verify this tab belongs to the group
|
|
68
|
+
if (groupId) {
|
|
69
|
+
const tabGroup = getGroupForTab(targetId);
|
|
70
|
+
if (tabGroup !== groupId) {
|
|
71
|
+
throw new Error(`Tab ${targetId} does not belong to group ${groupId}.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return targetId;
|
|
75
|
+
}
|
|
76
|
+
if (typeof index === "number") {
|
|
77
|
+
const tab = scopedTabs[index];
|
|
78
|
+
if (!tab) {
|
|
79
|
+
throw new Error(`No tab at index ${index}` +
|
|
80
|
+
(groupId ? ` in group ${groupId}` : ""));
|
|
81
|
+
}
|
|
82
|
+
return tab.targetId;
|
|
83
|
+
}
|
|
84
|
+
throw new Error("Either 'index' or 'targetId' is required");
|
|
85
|
+
}
|
|
86
|
+
switch (action) {
|
|
87
|
+
case "list": {
|
|
88
|
+
const tabs = await getScopedTabs();
|
|
89
|
+
if (tabs.length === 0) {
|
|
90
|
+
if (groupId) {
|
|
91
|
+
return `**No tabs in group ${groupId}.**\nCreate one with browser_tabs({ action: 'new', groupId: '${groupId}', url: '...' })`;
|
|
92
|
+
}
|
|
93
|
+
return "**No tabs open.**";
|
|
94
|
+
}
|
|
95
|
+
const output = tabs
|
|
96
|
+
.map((tab, i) => {
|
|
97
|
+
const groupLabel = !groupId ? (() => {
|
|
98
|
+
const g = getGroupForTab(tab.targetId);
|
|
99
|
+
const info = g ? getTabGroup(g) : null;
|
|
100
|
+
return info ? ` [${info.name}]` : " [ungrouped]";
|
|
101
|
+
})() : "";
|
|
102
|
+
return (`[${i}] **targetId: ${tab.targetId}**${groupLabel}\n` +
|
|
103
|
+
` ${tab.title || "(no title)"}\n` +
|
|
104
|
+
` ${tab.url}`);
|
|
105
|
+
})
|
|
106
|
+
.join("\n\n");
|
|
107
|
+
const label = groupId ? `in group ${groupId}` : "total";
|
|
108
|
+
return `**${tabs.length} tab(s)** ${label}\n\n${output}`;
|
|
109
|
+
}
|
|
110
|
+
case "new": {
|
|
111
|
+
// groupId is required for creating tabs
|
|
112
|
+
if (!groupId) {
|
|
113
|
+
throw new Error("groupId is required when creating new tabs. " +
|
|
114
|
+
"Create a tab group first with browser_tab_group, then pass the groupId here.");
|
|
115
|
+
}
|
|
116
|
+
const group = getTabGroup(groupId);
|
|
117
|
+
if (!group) {
|
|
118
|
+
throw new Error(`Tab group not found: ${groupId}. Create one first with browser_tab_group.`);
|
|
119
|
+
}
|
|
120
|
+
const tabUrl = url || "about:blank";
|
|
121
|
+
let resultTargetId;
|
|
122
|
+
let chromeTabId;
|
|
123
|
+
// Prefer creating via extension (gives us Chrome tab ID directly for reliable grouping)
|
|
124
|
+
const hasExtension = await isTabGrouperAvailable(config.cdpEndpoint);
|
|
125
|
+
if (hasExtension) {
|
|
126
|
+
try {
|
|
127
|
+
const extTab = await createTabViaExtension(config.cdpEndpoint, tabUrl);
|
|
128
|
+
resultTargetId = extTab.targetId;
|
|
129
|
+
chromeTabId = extTab.chromeTabId;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Fall back to Playwright
|
|
133
|
+
const pwTab = await createPageViaPlaywright({
|
|
134
|
+
cdpUrl: config.cdpEndpoint,
|
|
135
|
+
url: tabUrl,
|
|
136
|
+
});
|
|
137
|
+
resultTargetId = pwTab.targetId;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const pwTab = await createPageViaPlaywright({
|
|
142
|
+
cdpUrl: config.cdpEndpoint,
|
|
143
|
+
url: tabUrl,
|
|
144
|
+
});
|
|
145
|
+
resultTargetId = pwTab.targetId;
|
|
146
|
+
}
|
|
147
|
+
// Associate with group in registry (include Chrome tab ID if available)
|
|
148
|
+
addTabToGroup(resultTargetId, groupId, chromeTabId);
|
|
149
|
+
// Add to Chrome visual group
|
|
150
|
+
if (chromeTabId !== undefined) {
|
|
151
|
+
try {
|
|
152
|
+
const color = group.color || "grey";
|
|
153
|
+
const result = await groupTabsVisually(config.cdpEndpoint, [chromeTabId], group.name, color, group.chromeGroupId);
|
|
154
|
+
if (!group.chromeGroupId) {
|
|
155
|
+
setChromeGroupId(groupId, result.groupId);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Visual grouping is best-effort
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return (`**Tab created**\n` +
|
|
163
|
+
`**targetId: ${resultTargetId}** ← Use this with other browser tools\n` +
|
|
164
|
+
`Group: ${groupId}\n` +
|
|
165
|
+
`URL: ${tabUrl}`);
|
|
166
|
+
}
|
|
167
|
+
case "close": {
|
|
168
|
+
const tabs = await getScopedTabs();
|
|
169
|
+
const tid = await resolveTarget(tabs);
|
|
170
|
+
// Get stored Chrome tab ID for clean closure
|
|
171
|
+
const storedChromeTabId = getChromeTabId(tid);
|
|
172
|
+
// Close the tab — prefer extension if we have the Chrome tab ID
|
|
173
|
+
if (storedChromeTabId !== undefined) {
|
|
174
|
+
try {
|
|
175
|
+
await closeTabViaExtension(config.cdpEndpoint, storedChromeTabId);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Fall back to Playwright
|
|
179
|
+
await closePageByTargetIdViaPlaywright({
|
|
180
|
+
cdpUrl: config.cdpEndpoint,
|
|
181
|
+
targetId: tid,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
await closePageByTargetIdViaPlaywright({
|
|
187
|
+
cdpUrl: config.cdpEndpoint,
|
|
188
|
+
targetId: tid,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// Remove from registry
|
|
192
|
+
removeTabFromGroup(tid);
|
|
193
|
+
return `**Tab closed:** ${tid}`;
|
|
194
|
+
}
|
|
195
|
+
case "select": {
|
|
196
|
+
const tabs = await getScopedTabs();
|
|
197
|
+
const tid = await resolveTarget(tabs);
|
|
198
|
+
await focusPageByTargetIdViaPlaywright({
|
|
199
|
+
cdpUrl: config.cdpEndpoint,
|
|
200
|
+
targetId: tid,
|
|
201
|
+
});
|
|
202
|
+
return `**Tab focused:** ${tid}`;
|
|
203
|
+
}
|
|
204
|
+
default:
|
|
205
|
+
throw new Error(`Unknown action: ${action}`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/mcp/tools/tabs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-format.d.ts","sourceRoot":"","sources":["../../src/utils/command-format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified command formatting (stub from OpenClaw's cli/command-format.ts)
|
|
3
|
+
* For ultimate-playwright-mcp, we just return the command as-is
|
|
4
|
+
*/
|
|
5
|
+
export function formatCliCommand(command) {
|
|
6
|
+
return command;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=command-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-format.js","sourceRoot":"","sources":["../../src/utils/command-format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAevD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified error utilities extracted from OpenClaw
|
|
3
|
+
* Original: src/infra/errors.ts
|
|
4
|
+
*/
|
|
5
|
+
export function formatErrorMessage(err) {
|
|
6
|
+
if (err instanceof Error) {
|
|
7
|
+
return err.message || err.name || "Error";
|
|
8
|
+
}
|
|
9
|
+
if (typeof err === "string") {
|
|
10
|
+
return err;
|
|
11
|
+
}
|
|
12
|
+
if (typeof err === "number" || typeof err === "boolean" || typeof err === "bigint") {
|
|
13
|
+
return String(err);
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
return JSON.stringify(err);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return Object.prototype.toString.call(err);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chrome extension installer - Downloads and extracts extensions from Chrome Web Store
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if a string is a Chrome Web Store extension ID (32 lowercase letters)
|
|
6
|
+
*/
|
|
7
|
+
export declare function isChromeStoreId(str: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Get the local path for an extension (either downloaded or direct path)
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveExtensionPath(extensionIdOrPath: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve multiple extensions (mix of IDs and paths)
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveExtensions(extensionsIdOrPaths: string[]): Promise<string[]>;
|
|
16
|
+
//# sourceMappingURL=extension-installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-installer.d.ts","sourceRoot":"","sources":["../../src/utils/extension-installer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AA+BD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAerF;AA2ED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,mBAAmB,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAcxF"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chrome extension installer - Downloads and extracts extensions from Chrome Web Store
|
|
3
|
+
*/
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import { pipeline } from "node:stream/promises";
|
|
8
|
+
import { createWriteStream } from "node:fs";
|
|
9
|
+
import AdmZip from "adm-zip";
|
|
10
|
+
const EXTENSIONS_DIR = path.join(os.homedir(), ".ultimate-playwright-mcp", "extensions");
|
|
11
|
+
const CHROME_VERSION = "120.0.0.0"; // Hardcoded version that works for most extensions
|
|
12
|
+
/**
|
|
13
|
+
* Check if a string is a Chrome Web Store extension ID (32 lowercase letters)
|
|
14
|
+
*/
|
|
15
|
+
export function isChromeStoreId(str) {
|
|
16
|
+
return /^[a-z]{32}$/.test(str);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Strip CRX header from buffer to get the ZIP content
|
|
20
|
+
* CRX format: "Cr24" magic + version + header length + header + ZIP
|
|
21
|
+
*/
|
|
22
|
+
function stripCrxHeader(crxBuffer) {
|
|
23
|
+
// Check for CRX magic number "Cr24"
|
|
24
|
+
if (crxBuffer.toString("utf8", 0, 4) !== "Cr24") {
|
|
25
|
+
throw new Error("Invalid CRX file: missing magic number");
|
|
26
|
+
}
|
|
27
|
+
// Read version (4 bytes at offset 4)
|
|
28
|
+
const version = crxBuffer.readUInt32LE(4);
|
|
29
|
+
if (version === 2) {
|
|
30
|
+
// CRX2 format: magic(4) + version(4) + pubkey_len(4) + sig_len(4) + pubkey + sig + ZIP
|
|
31
|
+
const pubkeyLen = crxBuffer.readUInt32LE(8);
|
|
32
|
+
const sigLen = crxBuffer.readUInt32LE(12);
|
|
33
|
+
const headerSize = 16 + pubkeyLen + sigLen;
|
|
34
|
+
return crxBuffer.subarray(headerSize);
|
|
35
|
+
}
|
|
36
|
+
else if (version === 3) {
|
|
37
|
+
// CRX3 format: magic(4) + version(4) + header_len(4) + header + ZIP
|
|
38
|
+
const headerLen = crxBuffer.readUInt32LE(8);
|
|
39
|
+
const headerSize = 12 + headerLen;
|
|
40
|
+
return crxBuffer.subarray(headerSize);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error(`Unsupported CRX version: ${version}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the local path for an extension (either downloaded or direct path)
|
|
48
|
+
*/
|
|
49
|
+
export async function resolveExtensionPath(extensionIdOrPath) {
|
|
50
|
+
// If it's a local path that exists, use it directly
|
|
51
|
+
if (fs.existsSync(extensionIdOrPath)) {
|
|
52
|
+
return extensionIdOrPath;
|
|
53
|
+
}
|
|
54
|
+
// If it's a Chrome Web Store ID, download it
|
|
55
|
+
if (isChromeStoreId(extensionIdOrPath)) {
|
|
56
|
+
return await downloadExtension(extensionIdOrPath);
|
|
57
|
+
}
|
|
58
|
+
throw new Error(`Invalid extension: "${extensionIdOrPath}". ` +
|
|
59
|
+
`Must be either a valid file path or a 32-character Chrome Web Store ID.`);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Download and extract a Chrome extension from the Web Store
|
|
63
|
+
*/
|
|
64
|
+
async function downloadExtension(extensionId) {
|
|
65
|
+
// Ensure extensions directory exists
|
|
66
|
+
if (!fs.existsSync(EXTENSIONS_DIR)) {
|
|
67
|
+
fs.mkdirSync(EXTENSIONS_DIR, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
const extensionDir = path.join(EXTENSIONS_DIR, extensionId);
|
|
70
|
+
// If already downloaded, return the path
|
|
71
|
+
if (fs.existsSync(extensionDir)) {
|
|
72
|
+
console.error(`Extension ${extensionId} already downloaded`);
|
|
73
|
+
return extensionDir;
|
|
74
|
+
}
|
|
75
|
+
console.error(`Downloading extension ${extensionId} from Chrome Web Store...`);
|
|
76
|
+
// Build CRX download URL
|
|
77
|
+
const crxUrl = `https://clients2.google.com/service/update2/crx?` +
|
|
78
|
+
`response=redirect&prodversion=${CHROME_VERSION}&acceptformat=crx2,crx3&` +
|
|
79
|
+
`x=id%3D${extensionId}%26uc`;
|
|
80
|
+
try {
|
|
81
|
+
// Download CRX file
|
|
82
|
+
const response = await fetch(crxUrl);
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`Failed to download: HTTP ${response.status}`);
|
|
85
|
+
}
|
|
86
|
+
// Save to temporary file
|
|
87
|
+
const tempCrxPath = path.join(EXTENSIONS_DIR, `${extensionId}.crx`);
|
|
88
|
+
const fileStream = createWriteStream(tempCrxPath);
|
|
89
|
+
if (!response.body) {
|
|
90
|
+
throw new Error("No response body");
|
|
91
|
+
}
|
|
92
|
+
await pipeline(response.body, fileStream);
|
|
93
|
+
// Extract CRX file (remove CRX header first)
|
|
94
|
+
console.error(`Extracting extension ${extensionId}...`);
|
|
95
|
+
const crxBuffer = fs.readFileSync(tempCrxPath);
|
|
96
|
+
const zipBuffer = stripCrxHeader(crxBuffer);
|
|
97
|
+
// Write stripped ZIP to temp file
|
|
98
|
+
const tempZipPath = path.join(EXTENSIONS_DIR, `${extensionId}.zip`);
|
|
99
|
+
fs.writeFileSync(tempZipPath, zipBuffer);
|
|
100
|
+
// Extract ZIP
|
|
101
|
+
const zip = new AdmZip(tempZipPath);
|
|
102
|
+
zip.extractAllTo(extensionDir, true);
|
|
103
|
+
// Clean up temp files
|
|
104
|
+
fs.unlinkSync(tempCrxPath);
|
|
105
|
+
fs.unlinkSync(tempZipPath);
|
|
106
|
+
console.error(`✓ Extension ${extensionId} installed to ${extensionDir}`);
|
|
107
|
+
return extensionDir;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Clean up on failure
|
|
111
|
+
if (fs.existsSync(extensionDir)) {
|
|
112
|
+
fs.rmSync(extensionDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
throw new Error(`Failed to download extension ${extensionId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve multiple extensions (mix of IDs and paths)
|
|
119
|
+
*/
|
|
120
|
+
export async function resolveExtensions(extensionsIdOrPaths) {
|
|
121
|
+
const resolved = [];
|
|
122
|
+
for (const item of extensionsIdOrPaths) {
|
|
123
|
+
try {
|
|
124
|
+
const path = await resolveExtensionPath(item);
|
|
125
|
+
resolved.push(path);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(`Warning: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
|
+
// Continue with other extensions even if one fails
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return resolved;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=extension-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-installer.js","sourceRoot":"","sources":["../../src/utils/extension-installer.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ultimate-playwright-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Multi-agent Playwright MCP server with tab isolation via targetId",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"ultimate-playwright-mcp": "./dist/cli.js",
|
|
10
|
+
"upmcp": "./dist/cli.js",
|
|
11
|
+
"upmcp-daemon": "./dist/daemon/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"watch": "tsc --watch",
|
|
27
|
+
"lint": "eslint .",
|
|
28
|
+
"type-check": "tsc --noEmit",
|
|
29
|
+
"test": "playwright test",
|
|
30
|
+
"test:headed": "playwright test --headed",
|
|
31
|
+
"test:debug": "playwright test --debug",
|
|
32
|
+
"prepublishOnly": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"mcp",
|
|
36
|
+
"playwright",
|
|
37
|
+
"browser",
|
|
38
|
+
"automation",
|
|
39
|
+
"multi-agent",
|
|
40
|
+
"tab-isolation",
|
|
41
|
+
"cdp"
|
|
42
|
+
],
|
|
43
|
+
"author": "Patrick Menlove",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/pm990320/ultimate-playwright-mcp.git"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/pm990320/ultimate-playwright-mcp#readme",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/pm990320/ultimate-playwright-mcp/issues"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
55
|
+
"adm-zip": "^0.5.16",
|
|
56
|
+
"commander": "^12.1.0",
|
|
57
|
+
"glob": "^13.0.1",
|
|
58
|
+
"playwright-core": "^1.49.1",
|
|
59
|
+
"ws": "^8.19.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@playwright/test": "^1.49.1",
|
|
63
|
+
"@types/adm-zip": "^0.5.7",
|
|
64
|
+
"@types/node": "^22.10.2",
|
|
65
|
+
"@types/ws": "^8.18.1",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
|
67
|
+
"@typescript-eslint/parser": "^8.18.2",
|
|
68
|
+
"eslint": "^9.17.0",
|
|
69
|
+
"globals": "^17.3.0",
|
|
70
|
+
"typescript": "^5.7.2"
|
|
71
|
+
},
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=18.0.0"
|
|
74
|
+
}
|
|
75
|
+
}
|