crawlio-browser 1.4.4 → 1.4.5
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/dist/mcp-server/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
WS_PORT,
|
|
8
8
|
WS_RECONNECT_GRACE,
|
|
9
9
|
WS_STALE_THRESHOLD
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3UA6NXNB.js";
|
|
11
11
|
|
|
12
12
|
// src/mcp-server/index.ts
|
|
13
13
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
@@ -4027,7 +4027,7 @@ function createCodeModeTools(bridge2, crawlio2) {
|
|
|
4027
4027
|
process.title = "Crawlio Agent";
|
|
4028
4028
|
var initMode = process.argv.includes("init") || process.argv.includes("--setup") || process.argv.includes("setup");
|
|
4029
4029
|
if (initMode) {
|
|
4030
|
-
const { runInit } = await import("./init-
|
|
4030
|
+
const { runInit } = await import("./init-AJOP2HY7.js");
|
|
4031
4031
|
await runInit(process.argv.slice(2));
|
|
4032
4032
|
process.exit(0);
|
|
4033
4033
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PKG_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3UA6NXNB.js";
|
|
4
4
|
|
|
5
5
|
// src/mcp-server/init.ts
|
|
6
6
|
import { execFileSync, spawn } from "child_process";
|
|
@@ -58,21 +58,220 @@ function parseFlags(argv) {
|
|
|
58
58
|
}
|
|
59
59
|
return opts;
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
61
|
+
var CLIENT_REGISTRY = [
|
|
62
|
+
{
|
|
63
|
+
name: "Claude Code",
|
|
64
|
+
configPath: join(HOME, ".claude.json"),
|
|
65
|
+
serverKey: "mcpServers",
|
|
66
|
+
format: "json",
|
|
67
|
+
detect: () => existsSync(join(HOME, ".claude"))
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "Claude Desktop",
|
|
71
|
+
configPath: join(HOME, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
72
|
+
serverKey: "mcpServers",
|
|
73
|
+
format: "json",
|
|
74
|
+
detect: () => existsSync(join(HOME, "Library", "Application Support", "Claude"))
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "VS Code",
|
|
78
|
+
configPath: join(HOME, "Library", "Application Support", "Code", "User", "mcp.json"),
|
|
79
|
+
serverKey: "servers",
|
|
80
|
+
format: "json",
|
|
81
|
+
detect: () => existsSync(join(HOME, ".vscode"))
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "Cursor",
|
|
85
|
+
configPath: join(HOME, ".cursor", "mcp.json"),
|
|
86
|
+
serverKey: "mcpServers",
|
|
87
|
+
format: "json",
|
|
88
|
+
detect: () => existsSync(join(HOME, ".cursor"))
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "Windsurf",
|
|
92
|
+
configPath: join(HOME, ".codeium", "windsurf", "mcp_config.json"),
|
|
93
|
+
serverKey: "mcpServers",
|
|
94
|
+
format: "json",
|
|
95
|
+
detect: () => existsSync(join(HOME, ".codeium", "windsurf"))
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "Cline (VS Code)",
|
|
99
|
+
configPath: join(HOME, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
|
|
100
|
+
serverKey: "mcpServers",
|
|
101
|
+
format: "json",
|
|
102
|
+
detect: () => existsSync(join(HOME, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings")),
|
|
103
|
+
transform: (entry) => ({ ...entry, disabled: false })
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "Cline CLI",
|
|
107
|
+
configPath: join(HOME, ".cline", "data", "settings", "cline_mcp_settings.json"),
|
|
108
|
+
serverKey: "mcpServers",
|
|
109
|
+
format: "json",
|
|
110
|
+
detect: () => existsSync(join(HOME, ".cline")),
|
|
111
|
+
transform: (entry) => ({ ...entry, disabled: false })
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "Copilot CLI",
|
|
115
|
+
configPath: join(HOME, ".copilot", "mcp-config.json"),
|
|
116
|
+
serverKey: "mcpServers",
|
|
117
|
+
format: "json",
|
|
118
|
+
detect: () => existsSync(join(HOME, ".copilot"))
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Gemini CLI",
|
|
122
|
+
configPath: join(HOME, ".gemini", "settings.json"),
|
|
123
|
+
serverKey: "mcpServers",
|
|
124
|
+
format: "json",
|
|
125
|
+
detect: () => existsSync(join(HOME, ".gemini"))
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "Codex CLI",
|
|
129
|
+
configPath: join(HOME, ".codex", "config.toml"),
|
|
130
|
+
serverKey: "mcp_servers",
|
|
131
|
+
format: "toml",
|
|
132
|
+
detect: () => existsSync(join(HOME, ".codex"))
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "Goose",
|
|
136
|
+
configPath: join(HOME, ".config", "goose", "config.yaml"),
|
|
137
|
+
serverKey: "extensions",
|
|
138
|
+
format: "yaml",
|
|
139
|
+
detect: () => existsSync(join(HOME, ".config", "goose"))
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "OpenCode",
|
|
143
|
+
configPath: join(HOME, ".config", "opencode", "opencode.json"),
|
|
144
|
+
serverKey: "mcp",
|
|
145
|
+
format: "json",
|
|
146
|
+
detect: () => existsSync(join(HOME, ".config", "opencode")),
|
|
147
|
+
transform: (entry) => {
|
|
148
|
+
const e = entry;
|
|
149
|
+
return { command: [e.command, ...e.args || []], env: entry.env };
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "Zed",
|
|
154
|
+
configPath: join(HOME, "Library", "Application Support", "Zed", "settings.json"),
|
|
155
|
+
serverKey: "context_servers",
|
|
156
|
+
format: "json",
|
|
157
|
+
detect: () => existsSync(join(HOME, "Library", "Application Support", "Zed")),
|
|
158
|
+
transform: (entry) => ({
|
|
159
|
+
settings: { source: "custom", command: entry }
|
|
160
|
+
})
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "Antigravity",
|
|
164
|
+
configPath: join(HOME, ".gemini", "antigravity", "mcp_config.json"),
|
|
165
|
+
serverKey: "mcpServers",
|
|
166
|
+
format: "json",
|
|
167
|
+
detect: () => existsSync(join(HOME, ".gemini", "antigravity"))
|
|
168
|
+
}
|
|
169
|
+
];
|
|
170
|
+
function configureClient(client, entry, dryRun) {
|
|
171
|
+
const finalEntry = client.transform ? client.transform(entry) : entry;
|
|
172
|
+
if (client.format === "json") {
|
|
173
|
+
let config = {};
|
|
174
|
+
if (existsSync(client.configPath)) {
|
|
175
|
+
try {
|
|
176
|
+
config = JSON.parse(readFileSync(client.configPath, "utf-8"));
|
|
177
|
+
} catch {
|
|
178
|
+
config = {};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const section = config[client.serverKey] || {};
|
|
182
|
+
if ("crawlio-browser" in section) return "skipped";
|
|
183
|
+
if (dryRun) return "configured";
|
|
184
|
+
section["crawlio-browser"] = finalEntry;
|
|
185
|
+
config[client.serverKey] = section;
|
|
186
|
+
mkdirSync(dirname(client.configPath), { recursive: true });
|
|
187
|
+
writeFileSync(client.configPath, JSON.stringify(config, null, 2) + "\n");
|
|
188
|
+
return "configured";
|
|
189
|
+
}
|
|
190
|
+
if (client.format === "toml") {
|
|
191
|
+
let content = "";
|
|
192
|
+
if (existsSync(client.configPath)) {
|
|
193
|
+
content = readFileSync(client.configPath, "utf-8");
|
|
194
|
+
}
|
|
195
|
+
if (content.includes("[mcp_servers.crawlio-browser]") || content.includes('[mcp_servers."crawlio-browser"]')) {
|
|
196
|
+
return "skipped";
|
|
197
|
+
}
|
|
198
|
+
if (dryRun) return "configured";
|
|
199
|
+
const e = entry;
|
|
200
|
+
const argsStr = (e.args || []).map((a) => `"${a}"`).join(", ");
|
|
201
|
+
const block = `
|
|
202
|
+
[mcp_servers.crawlio-browser]
|
|
203
|
+
command = "${e.command}"
|
|
204
|
+
args = [${argsStr}]
|
|
205
|
+
`;
|
|
206
|
+
mkdirSync(dirname(client.configPath), { recursive: true });
|
|
207
|
+
writeFileSync(client.configPath, content + block);
|
|
208
|
+
return "configured";
|
|
70
209
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
210
|
+
if (client.format === "yaml") {
|
|
211
|
+
let content = "";
|
|
212
|
+
if (existsSync(client.configPath)) {
|
|
213
|
+
content = readFileSync(client.configPath, "utf-8");
|
|
214
|
+
}
|
|
215
|
+
if (content.includes("crawlio-browser:")) {
|
|
216
|
+
return "skipped";
|
|
217
|
+
}
|
|
218
|
+
if (dryRun) return "configured";
|
|
219
|
+
const e = entry;
|
|
220
|
+
const argsYaml = (e.args || []).map((a) => ` - ${a}`).join("\n");
|
|
221
|
+
const block = `
|
|
222
|
+
crawlio-browser:
|
|
223
|
+
name: crawlio-browser
|
|
224
|
+
type: stdio
|
|
225
|
+
cmd: ${e.command}
|
|
226
|
+
args:
|
|
227
|
+
${argsYaml}
|
|
228
|
+
`;
|
|
229
|
+
if (!content.includes("extensions:")) {
|
|
230
|
+
content += "\nextensions:\n";
|
|
231
|
+
}
|
|
232
|
+
mkdirSync(dirname(client.configPath), { recursive: true });
|
|
233
|
+
writeFileSync(client.configPath, content + block);
|
|
234
|
+
return "configured";
|
|
74
235
|
}
|
|
75
|
-
return
|
|
236
|
+
return "error";
|
|
237
|
+
}
|
|
238
|
+
function configureAllClients(options) {
|
|
239
|
+
const entry = options.portal ? buildPortalEntry() : buildStdioEntry({ full: options.full });
|
|
240
|
+
const candidates = options.agents.length > 0 ? CLIENT_REGISTRY.filter((c) => options.agents.some((a) => c.name.toLowerCase().includes(a.toLowerCase()))) : CLIENT_REGISTRY.filter((c) => c.detect());
|
|
241
|
+
if (candidates.length === 0) {
|
|
242
|
+
console.log(` ${dim(" No MCP clients detected on this machine")}`);
|
|
243
|
+
printManualInstructions(entry);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
let configured = 0;
|
|
247
|
+
let skipped = 0;
|
|
248
|
+
for (const client of candidates) {
|
|
249
|
+
const result = configureClient(client, entry, options.dryRun);
|
|
250
|
+
if (result === "configured") {
|
|
251
|
+
const prefix = options.dryRun ? dim("~") : green("+");
|
|
252
|
+
console.log(` ${prefix} ${client.name} ${dim("\u2192 " + client.configPath)}`);
|
|
253
|
+
configured++;
|
|
254
|
+
} else if (result === "skipped") {
|
|
255
|
+
console.log(` ${dim("=")} ${client.name} ${dim("(already configured)")}`);
|
|
256
|
+
skipped++;
|
|
257
|
+
} else {
|
|
258
|
+
console.log(` ${yellow("!")} ${client.name} ${dim("\u2014 failed to write config")}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (configured === 0 && skipped > 0) {
|
|
262
|
+
console.log(` ${dim(" All detected clients already configured")}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function printManualInstructions(entry) {
|
|
266
|
+
console.log("");
|
|
267
|
+
console.log(` ${dim("Add this to your MCP client config:")}`);
|
|
268
|
+
console.log("");
|
|
269
|
+
const snippet = { "crawlio-browser": entry };
|
|
270
|
+
const lines = JSON.stringify(snippet, null, 2).split("\n");
|
|
271
|
+
for (const line of lines) {
|
|
272
|
+
console.log(` ${dim(line)}`);
|
|
273
|
+
}
|
|
274
|
+
console.log("");
|
|
76
275
|
}
|
|
77
276
|
function buildStdioEntry(options) {
|
|
78
277
|
if (platform() === "darwin") {
|
|
@@ -620,7 +819,7 @@ async function portalFlow(options) {
|
|
|
620
819
|
await ensurePortalRunning(options.dryRun);
|
|
621
820
|
console.log("");
|
|
622
821
|
console.log(` ${cyan("\u25C6")} ${bold("MCP Configuration")} ${dim("(portal mode)")}`);
|
|
623
|
-
|
|
822
|
+
configureAllClients(options);
|
|
624
823
|
}
|
|
625
824
|
async function configureMetaMcp(found, options) {
|
|
626
825
|
console.log("");
|
|
@@ -667,47 +866,7 @@ async function configureMetaMcp(found, options) {
|
|
|
667
866
|
function configureStdioClients(options) {
|
|
668
867
|
console.log("");
|
|
669
868
|
console.log(` ${cyan("\u25C6")} ${bold("MCP Configuration")} ${dim("(stdio mode)")}`);
|
|
670
|
-
|
|
671
|
-
}
|
|
672
|
-
function runAddMcp(options) {
|
|
673
|
-
const npxBin = platform() === "win32" ? "npx.cmd" : "npx";
|
|
674
|
-
const args = buildAddMcpArgs(options);
|
|
675
|
-
if (options.dryRun) {
|
|
676
|
-
console.log(` ${dim("~")} Would run: ${npxBin} ${args.join(" ")}`);
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
try {
|
|
680
|
-
const output = execFileSync(npxBin, args, {
|
|
681
|
-
encoding: "utf-8",
|
|
682
|
-
timeout: 6e4,
|
|
683
|
-
env: { ...process.env, npm_config_yes: "true" }
|
|
684
|
-
});
|
|
685
|
-
const lines = output.split("\n").filter((l) => l.trim());
|
|
686
|
-
let configuredCount = 0;
|
|
687
|
-
for (const line of lines) {
|
|
688
|
-
const trimmed = line.trim();
|
|
689
|
-
if (trimmed) {
|
|
690
|
-
console.log(` ${green("+")} ${trimmed}`);
|
|
691
|
-
configuredCount++;
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
if (configuredCount === 0) {
|
|
695
|
-
console.log(` ${dim(" add-mcp ran but no clients detected")}`);
|
|
696
|
-
}
|
|
697
|
-
} catch (error) {
|
|
698
|
-
const errObj = error;
|
|
699
|
-
const code = errObj?.code;
|
|
700
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
701
|
-
if (code === "ENOENT") {
|
|
702
|
-
console.log(` ${yellow("!")} ${npxBin} not found in PATH \u2014 install Node.js 18+ and retry`);
|
|
703
|
-
} else if (code === "ETIMEDOUT" || msg.includes("ETIMEDOUT") || msg.includes("timed out")) {
|
|
704
|
-
console.log(` ${yellow("!")} add-mcp timed out \u2014 check network and retry`);
|
|
705
|
-
} else {
|
|
706
|
-
console.log(` ${yellow("!")} add-mcp failed: ${msg.slice(0, 200)}`);
|
|
707
|
-
}
|
|
708
|
-
const target = options.portal ? MCP_URL : "crawlio-browser";
|
|
709
|
-
console.log(` ${dim(` Manual: npx add-mcp ${target} --name crawlio-browser --global`)}`);
|
|
710
|
-
}
|
|
869
|
+
configureAllClients(options);
|
|
711
870
|
}
|
|
712
871
|
var LOGO_LINES = [
|
|
713
872
|
" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
@@ -832,10 +991,12 @@ async function runInit(argv) {
|
|
|
832
991
|
await printSummary(options);
|
|
833
992
|
}
|
|
834
993
|
export {
|
|
835
|
-
|
|
994
|
+
CLIENT_REGISTRY,
|
|
836
995
|
buildCloudflareEntry,
|
|
837
996
|
buildPortalEntry,
|
|
838
997
|
buildStdioEntry,
|
|
998
|
+
configureAllClients,
|
|
999
|
+
configureClient,
|
|
839
1000
|
createAppWrapper,
|
|
840
1001
|
extractSkillName,
|
|
841
1002
|
findConflictingConfigs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlio-browser",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "MCP server with 96 CDP-backed tools for browser automation — screenshots, DOM, network capture, framework detection, cookies, storage, session recording, performance metrics via Chrome",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/mcp-server/index.js",
|