@predotdev/mcp 2.0.2 → 2.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/README.md CHANGED
@@ -31,7 +31,7 @@ One MCP server gives your coding agent everything pre.dev does:
31
31
  - **Browser Agents in the cloud.** Send a URL and a task to pre.dev's browsers and get structured data back, many runs in parallel.
32
32
  - **Specs and plans.** Plan an app or feature before building it: architecture, tech stack, milestones and user stories.
33
33
 
34
- It works with **any coding agent that runs MCP servers locally**: Claude Code, Codex, Cursor, Windsurf, VS Code, Gemini CLI, OpenCode, Claude Desktop, the [pre.dev CLI](https://pre.dev) and more. Run as many agents as you like at the same time. They all share one connection to Chrome, so Chrome only asks you to allow it once.
34
+ It works with **any coding agent**: Claude Code, Codex, Hermes, Pi, OpenClaw, Cursor, GitHub Copilot, Cline, Gemini CLI and Antigravity, OpenCode, Zed, Goose, the [pre.dev CLI](https://pre.dev) and 20 more, and any agent that can run a shell command. Run as many agents as you like at the same time. They all share one connection to Chrome, so Chrome only asks you to allow it once.
35
35
 
36
36
  Built with the [pre.dev CLI](https://docs.pre.dev/cli/overview).
37
37
 
@@ -46,7 +46,7 @@ npx -y @predotdev/mcp setup
46
46
  It walks you through everything:
47
47
 
48
48
  1. **Signs you in to pre.dev** in your browser (or creates a free account). Approve, and your key is saved for every agent. Nothing to copy. Already signed in to the pre.dev CLI? It uses that login.
49
- 2. **Adds it to every coding agent on your Mac**: Claude Code, Codex, Cursor, Windsurf, VS Code, Gemini CLI, OpenCode, Claude Desktop and the pre.dev CLI. Already using the hosted pre.dev MCP? This one includes all of its tools, so setup replaces it.
49
+ 2. **Adds it to every coding agent on your Mac**: Claude Code, Codex, Hermes, Pi, OpenClaw, Cursor, Copilot CLI, Cline, Antigravity, Gemini CLI, OpenCode, VS Code, Claude Desktop, the pre.dev CLI and more (28 in all; [list](#setup-for-every-agent)). Already using the hosted pre.dev MCP? This one includes all of its tools, so setup replaces it.
50
50
  3. **Connects to Chrome.** The first time, it asks you to turn on remote debugging at `chrome://inspect/#remote-debugging` (it copies the address for you), and Chrome asks **"Allow remote debugging?"**: click **Allow**.
51
51
 
52
52
  Then restart your agent and try:
@@ -138,6 +138,8 @@ Once you are signed in to pre.dev (`setup` or `login` does it, or set `PREDEV_AP
138
138
  npx -y @predotdev/mcp env: PREDEV_API_KEY=your_key (optional after login)
139
139
  ```
140
140
 
141
+ `setup` finds and configures each of these that is installed: Claude Code, Codex, Hermes, Pi, OpenClaw, Cursor (editor and CLI), Windsurf, GitHub Copilot CLI, Antigravity, Gemini CLI, Cline, Kiro, Qwen Code, Factory Droid, Augment, Amp, Kilo Code, Kimi Code, Junie, Warp, Rovo Dev, OpenHands, LM Studio, OpenCode, VS Code, VS Code Insiders, Claude Desktop and the pre.dev CLI. Devin CLI, Grok Build and Warp also read Claude Code's or Cursor's config, so they pick it up from there. Zed's settings file usually has comments, so `setup` leaves it to you (below).
142
+
141
143
  <details>
142
144
  <summary><b>Claude Code</b></summary>
143
145
 
@@ -147,10 +149,34 @@ claude mcp add --scope user predev -e PREDEV_API_KEY=your_key -- npx -y @predotd
147
149
 
148
150
  </details>
149
151
 
152
+ <details>
153
+ <summary><b>Hermes</b></summary>
154
+
155
+ ```bash
156
+ hermes mcp add predev --command npx --args -y @predotdev/mcp
157
+ hermes config set mcp_servers.predev.timeout 900
158
+ ```
159
+
160
+ Answer `Y` to turn on its tools. The longer timeout gives specs and cloud runs time to finish. In a running chat, `/reload-mcp` picks it up.
161
+
162
+ </details>
163
+
164
+ <details>
165
+ <summary><b>Pi</b></summary>
166
+
167
+ ```bash
168
+ pi mcp add predev -- npx -y @predotdev/mcp
169
+ pi mcp list
170
+ ```
171
+
172
+ `pi mcp list` should say `predev: connected`. Pi versions without built-in MCP need `pi install npm:pi-mcp-adapter` first; it reads the same `~/.pi/agent/mcp.json`.
173
+
174
+ </details>
175
+
150
176
  <details>
151
177
  <summary><b>pre.dev CLI</b></summary>
152
178
 
153
- The pre.dev CLI has pre.dev's cloud tools built in, so it only needs the Chrome tools. `setup` adds this to `~/.predev/mcp.json`, and the server uses your pre.dev CLI login:
179
+ In the pre.dev CLI, type `/chrome` (and `/chrome off` to turn it off). The CLI has pre.dev's cloud tools built in, so it only needs the Chrome tools, and the server uses your pre.dev CLI login. `/chrome` and `setup` both add this to `~/.predev/mcp.json`:
154
180
 
155
181
  ```json
156
182
  {
@@ -166,6 +192,8 @@ The pre.dev CLI has pre.dev's cloud tools built in, so it only needs the Chrome
166
192
 
167
193
  The agent sees the tools as `predev_chrome_open`, `predev_chrome_act` and so on.
168
194
 
195
+ From the pre.dev CLI, `predev mcp setup` runs this package's `setup` for your other agents.
196
+
169
197
  </details>
170
198
 
171
199
  <details>
@@ -303,6 +331,114 @@ Put that entry inside `"mcpServers"` in `~/Library/Application Support/Claude/cl
303
331
 
304
332
  </details>
305
333
 
334
+ <details>
335
+ <summary><b>More agents, by hand</b></summary>
336
+
337
+ Every entry below is the same server: command `npx`, arguments `-y @predotdev/mcp`.
338
+
339
+ | Agent | Command, or file and key |
340
+ | --- | --- |
341
+ | GitHub Copilot CLI | `copilot mcp add predev -- npx -y @predotdev/mcp`, or `~/.copilot/mcp-config.json` under `mcpServers` (add `"type": "local", "tools": ["*"]`) |
342
+ | Antigravity (`agy`) | `~/.gemini/config/mcp_config.json` under `mcpServers` |
343
+ | Cline | `cline mcp add predev --yes -- npx -y @predotdev/mcp`, or `~/.cline/data/settings/cline_mcp_settings.json` under `mcpServers` |
344
+ | Kiro | `kiro-cli mcp add --name predev --command "npx -y @predotdev/mcp" --scope global`, or `~/.kiro/settings/mcp.json` |
345
+ | Qwen Code | `qwen mcp add --scope user predev npx -y @predotdev/mcp` |
346
+ | Factory Droid | `droid mcp add predev "npx -y @predotdev/mcp"` |
347
+ | Augment (Auggie) | `auggie mcp add predev --command npx --args "-y @predotdev/mcp"` |
348
+ | Amp | `amp mcp add predev -- npx -y @predotdev/mcp` |
349
+ | OpenClaw | `openclaw mcp set predev '{"command":"npx","args":["-y","@predotdev/mcp"]}'` |
350
+ | Grok Build | `grok mcp add predev -- npx -y @predotdev/mcp` |
351
+ | Devin CLI | `devin mcp add -s user predev -- npx -y @predotdev/mcp` |
352
+ | OpenHands | `openhands mcp add predev --transport stdio npx -- -y @predotdev/mcp` |
353
+ | Kilo Code | `~/.config/kilo/kilo.jsonc` under `mcp`: `"predev": {"type": "local", "command": ["npx", "-y", "@predotdev/mcp"], "enabled": true}` |
354
+ | Kimi Code | `~/.kimi-code/mcp.json` under `mcpServers` |
355
+ | Junie | `~/.junie/mcp/mcp.json` under `mcpServers` |
356
+ | Warp | `~/.warp/.mcp.json` under `mcpServers` |
357
+ | Rovo Dev | `~/.rovodev/mcp.json` under `mcpServers` (add `"transport": "stdio"`) |
358
+ | LM Studio | `~/.lmstudio/mcp.json` under `mcpServers` |
359
+ | JetBrains AI Assistant | Settings → MCP → Import from Claude (after `setup` adds it to Claude Desktop) |
360
+
361
+ </details>
362
+
363
+ <details>
364
+ <summary><b>Zed</b></summary>
365
+
366
+ In `~/.config/zed/settings.json`:
367
+
368
+ ```json
369
+ "context_servers": {
370
+ "predev": { "command": "npx", "args": ["-y", "@predotdev/mcp"], "env": {} }
371
+ }
372
+ ```
373
+
374
+ </details>
375
+
376
+ <details>
377
+ <summary><b>Goose</b></summary>
378
+
379
+ In `~/.config/goose/config.yaml`, under `extensions:`:
380
+
381
+ ```yaml
382
+ predev:
383
+ type: stdio
384
+ name: predev
385
+ enabled: true
386
+ cmd: npx
387
+ args: [-y, "@predotdev/mcp"]
388
+ envs: {}
389
+ timeout: 900
390
+ ```
391
+
392
+ For one session only: `goose session --with-extension "npx -y @predotdev/mcp"`.
393
+
394
+ </details>
395
+
396
+ <details>
397
+ <summary><b>Continue, Crush and Mistral Vibe</b></summary>
398
+
399
+ Continue, in `~/.continue/config.yaml`:
400
+
401
+ ```yaml
402
+ mcpServers:
403
+ - name: predev
404
+ command: npx
405
+ args: ["-y", "@predotdev/mcp"]
406
+ ```
407
+
408
+ Crush, one line in `~/.config/crush/crushrc`:
409
+
410
+ ```bash
411
+ mcp add predev --command npx --args -y --args @predotdev/mcp
412
+ ```
413
+
414
+ Mistral Vibe, in `~/.vibe/config.toml`:
415
+
416
+ ```toml
417
+ [[mcp_servers]]
418
+ name = "predev"
419
+ transport = "stdio"
420
+ command = "npx"
421
+ args = ["-y", "@predotdev/mcp"]
422
+ ```
423
+
424
+ </details>
425
+
426
+ <details>
427
+ <summary><b>Agents without MCP (Aider, scripts, anything with a shell)</b></summary>
428
+
429
+ Every tool also runs from a shell, so any agent that can run commands can drive your Chrome:
430
+
431
+ ```bash
432
+ npx -y @predotdev/mcp tools # list the tools and their arguments
433
+ npx -y @predotdev/mcp call chrome_open '{"profile":"Personal","url":"https://example.com"}'
434
+ npx -y @predotdev/mcp call chrome_snapshot '{"tab":"A1B2C3"}'
435
+ npx -y @predotdev/mcp call chrome_click '{"tab":"A1B2C3","ref":"e4"}'
436
+ ```
437
+
438
+ Text goes to stdout, a screenshot is saved to a file and its path is printed, and the exit code is 1 when the tool failed. Point your agent at this section, or paste `npx -y @predotdev/mcp tools` into its instructions.
439
+
440
+ </details>
441
+
306
442
  <details>
307
443
  <summary><b>Any other MCP client</b></summary>
308
444
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@predotdev/mcp",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "pre.dev in any coding agent: Browser Agents in the Chrome you already use and in the cloud, plus specs and plans. One command to set up. Free and open source.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/bridge.mjs CHANGED
@@ -428,6 +428,10 @@ Commands:
428
428
  predev-mcp stop stop the background daemon (it restarts on the next tool call)
429
429
  predev-mcp uninstall remove it from every agent and delete its files
430
430
  predev-mcp run the MCP server (what your agent launches)
431
+ predev-mcp tools list the tools and their arguments
432
+ predev-mcp call <tool> '<json args>'
433
+ run one tool from a shell, for agents without MCP; e.g.
434
+ predev-mcp call chrome_open '{"profile":"Default","url":"https://example.com"}'
431
435
  predev-mcp --version
432
436
 
433
437
  Docs: https://docs.pre.dev/browser-agents/local
@@ -495,6 +499,53 @@ if (typeof WebSocket === 'undefined') {
495
499
  process.exit(1);
496
500
  }
497
501
 
502
+ // `tools` and `call`: the same tools from a shell, for agents that run commands but don't speak MCP.
503
+ // Text goes to stdout; an image (a screenshot) is saved to a private temp file and its path printed.
504
+ async function runTools() {
505
+ const ctx = shimCtx();
506
+ const tools = [...(await loadTools()).toolList(ctx), ...(CLOUD ? await remote.listTools(ctx).catch(() => []) : [])];
507
+ for (const tool of tools) {
508
+ const props = Object.keys(tool.inputSchema?.properties || {});
509
+ const required = tool.inputSchema?.required || [];
510
+ console.log(`${tool.name}(${props.map(p => (required.includes(p) ? p : `${p}?`)).join(', ')})`);
511
+ console.log(` ${String(tool.description || '').split('\n')[0]}`);
512
+ }
513
+ }
514
+
515
+ async function runCall(name, raw) {
516
+ if (!name) {
517
+ process.stderr.write(`Usage: predev-mcp call <tool> '<json args>' (predev-mcp tools lists them)\n`);
518
+ process.exit(2);
519
+ }
520
+ let args = {};
521
+ try { args = raw ? JSON.parse(raw) : {}; } catch {
522
+ process.stderr.write('The arguments must be one JSON object, e.g. \'{"tab":"A1B2C3"}\'.\n');
523
+ process.exit(2);
524
+ }
525
+ const ctx = shimCtx();
526
+ let result;
527
+ try {
528
+ if (CLOUD && await remote.isRemote(ctx, name)) {
529
+ result = ctx.apiKey ? await remote.callTool(ctx, name, args)
530
+ : { content: [{ type: 'text', text: 'pre.dev tools need a free pre.dev account. Sign in with: npx -y @predotdev/mcp login' }], isError: true };
531
+ } else {
532
+ result = await request(await ensureDaemon(), 'POST', '/call', { name, args });
533
+ }
534
+ } catch (error) {
535
+ result = { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
536
+ }
537
+ for (const part of result.content || []) {
538
+ if (part.type === 'text') console.log(part.text);
539
+ else if (part.type === 'image' && part.data) {
540
+ const ext = /png/.test(part.mimeType || '') ? 'png' : 'jpg';
541
+ const file = path.join(os.tmpdir(), `predev-${name}-${Date.now()}.${ext}`);
542
+ fs.writeFileSync(file, Buffer.from(part.data, 'base64'), { mode: 0o600 });
543
+ console.log(`Image saved to ${file}`);
544
+ }
545
+ }
546
+ process.exit(result.isError ? 1 : 0);
547
+ }
548
+
498
549
  async function runSetupCommand(name) {
499
550
  const { createSetup } = await import(pathToFileURL(path.join(path.dirname(SELF), 'setup.mjs')).href);
500
551
  const setup = createSetup({
@@ -509,6 +560,8 @@ const command = process.argv[2] || '';
509
560
  if (command === 'daemon') runDaemon();
510
561
  else if (['setup', 'install', 'login', 'logout', 'uninstall'].includes(command)) runSetupCommand(command === 'install' ? 'setup' : command);
511
562
  else if (command === 'check') runCheck();
563
+ else if (command === 'tools') runTools();
564
+ else if (command === 'call') runCall(process.argv[3], process.argv[4]);
512
565
  else if (command === 'stop') runStop();
513
566
  else if (command === '--version' || command === '-v') console.log(PKG.version || '0.0.0');
514
567
  else if (command === '--help' || command === '-h' || command === 'help') process.stdout.write(HELP);
package/src/setup.mjs CHANGED
@@ -59,7 +59,8 @@ export function createSetup(ctx) {
59
59
  }
60
60
 
61
61
  const has = bin => spawnSync(process.platform === 'win32' ? 'where' : 'which', [bin], { stdio: 'ignore' }).status === 0;
62
- const run = (bin, args) => spawnSync(bin, args, { encoding: 'utf8', timeout: 30000 });
62
+ // `input` answers a CLI's own confirmation prompts (Hermes asks before it adds or removes a server).
63
+ const run = (bin, args, input, timeout = 30000) => spawnSync(bin, args, { encoding: 'utf8', timeout, ...(input ? { input } : {}) });
63
64
 
64
65
  // ------------------------------------------------------------------ sign in
65
66
 
@@ -232,6 +233,22 @@ export function createSetup(ctx) {
232
233
  try { return Object.fromEntries(JSON.parse(out.stdout).map(server => [server.name, server])); } catch { return {}; }
233
234
  };
234
235
 
236
+ // Hermes keeps its servers in config.yaml (under mcp_servers); each entry's block of lines, by name.
237
+ const hermesHome = process.env.HERMES_HOME || path.join(home, '.hermes');
238
+ const hermesEntries = () => {
239
+ let lines;
240
+ try { lines = fs.readFileSync(path.join(hermesHome, 'config.yaml'), 'utf8').split('\n'); } catch { return {}; }
241
+ const at = lines.findIndex(line => /^mcp_servers:\s*$/.test(line));
242
+ const entries = {};
243
+ let name = null;
244
+ for (const line of at < 0 ? [] : lines.slice(at + 1)) {
245
+ if (/^\S/.test(line)) break;
246
+ const key = /^ {2}([A-Za-z0-9_.-]+):\s*$/.exec(line);
247
+ if (key) { name = key[1]; entries[name] = ''; } else if (name) entries[name] += `${line}\n`;
248
+ }
249
+ return entries;
250
+ };
251
+
235
252
  function cliAgent(label, bin, entries, remove, add) {
236
253
  return {
237
254
  label, detect: () => has(bin),
@@ -276,10 +293,56 @@ export function createSetup(ctx) {
276
293
  return added;
277
294
  }),
278
295
  // The pre.dev CLI runs the chrome_* tools only: it has pre.dev's cloud tools built in.
296
+ // Hermes registers it with its own CLI, which checks the server and asks to enable its tools.
297
+ cliAgent('Hermes', 'hermes', hermesEntries,
298
+ name => run('hermes', ['mcp', 'remove', name], 'y\n', 90000),
299
+ name => {
300
+ const added = run('hermes', ['mcp', 'add', name, '--command', NODE, '--args', APP_ENTRY], 'Y\nY\n', 90000);
301
+ // Specs and cloud browser runs need more than Hermes's default tool timeout.
302
+ if (added.status === 0) run('hermes', ['config', 'set', `mcp_servers.${name}.timeout`, '900']);
303
+ return added;
304
+ }),
305
+ // Pi's built-in MCP (and the pi-mcp-adapter extension) read ~/.pi/agent/mcp.json.
306
+ jsonAgent('Pi', path.join(process.env.PI_CODING_AGENT_DIR || path.join(home, '.pi/agent'), 'mcp.json'), 'mcpServers',
307
+ () => ({ ...stdio(), timeout: 900 }),
308
+ () => exists(process.env.PI_CODING_AGENT_DIR || path.join(home, '.pi')) || has('pi')),
309
+ // OpenClaw keeps its servers in JSON5; its CLI edits them (set replaces, unset removes) and `show` prints JSON.
310
+ cliAgent('OpenClaw', 'openclaw', () => {
311
+ const out = String(run('openclaw', ['mcp', 'show'], null, 60000).stdout || '');
312
+ try { return JSON.parse(out.slice(out.indexOf('{'))); } catch { return {}; }
313
+ },
314
+ name => run('openclaw', ['mcp', 'unset', name], null, 60000),
315
+ name => run('openclaw', ['mcp', 'set', name, JSON.stringify({ ...stdio(), requestTimeoutMs: 900000 })], null, 60000)),
279
316
  jsonAgent('pre.dev CLI', path.join(home, '.predev/mcp.json'), 'mcpServers',
280
317
  () => ({ type: 'stdio', ...stdio(), env: { PREDEV_MCP_CLOUD: 'off' } }),
281
318
  () => exists(path.join(home, '.predev/bin')) || exists(path.join(home, '.predev/auth.json'))),
282
319
  jsonAgent('Cursor', path.join(home, '.cursor/mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.cursor'))),
320
+ // Copilot CLI's file, which VS Code's agent host reads too.
321
+ jsonAgent('GitHub Copilot CLI', path.join(process.env.COPILOT_HOME || path.join(home, '.copilot'), 'mcp-config.json'), 'mcpServers',
322
+ () => ({ type: 'local', ...stdio(), tools: ['*'] }), () => exists(process.env.COPILOT_HOME || path.join(home, '.copilot')) || has('copilot')),
323
+ jsonAgent('Antigravity', path.join(home, '.gemini/config/mcp_config.json'), 'mcpServers', stdio,
324
+ () => exists(path.join(home, '.gemini/config')) || has('agy')),
325
+ jsonAgent('Cline', path.join(home, '.cline/data/settings/cline_mcp_settings.json'), 'mcpServers',
326
+ () => ({ ...stdio(), timeout: 900 }), () => exists(path.join(home, '.cline')) || has('cline')),
327
+ jsonAgent('Kiro', path.join(home, '.kiro/settings/mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.kiro')) || has('kiro-cli')),
328
+ jsonAgent('Qwen Code', path.join(home, '.qwen/settings.json'), 'mcpServers', () => ({ ...stdio(), timeout: 900000 }),
329
+ () => exists(path.join(home, '.qwen')) || has('qwen')),
330
+ jsonAgent('Factory Droid', path.join(home, '.factory/mcp.json'), 'mcpServers', () => ({ type: 'stdio', ...stdio() }),
331
+ () => exists(path.join(home, '.factory')) || has('droid')),
332
+ jsonAgent('Augment', path.join(home, '.augment/settings.json'), 'mcpServers', stdio, () => exists(path.join(home, '.augment')) || has('auggie')),
333
+ jsonAgent('Amp', path.join(home, '.config/amp/settings.json'), 'amp.mcpServers', stdio, () => exists(path.join(home, '.config/amp')) || has('amp')),
334
+ jsonAgent('Kilo Code', path.join(home, '.config/kilo/kilo.jsonc'), 'mcp', () => ({ type: 'local', command: [NODE, APP_ENTRY], enabled: true }),
335
+ () => exists(path.join(home, '.config/kilo'))),
336
+ jsonAgent('Zed', path.join(home, '.config/zed/settings.json'), 'context_servers', () => ({ ...stdio(), env: {} }),
337
+ () => exists(path.join(home, '.config/zed'))),
338
+ jsonAgent('Kimi Code', path.join(home, '.kimi-code/mcp.json'), 'mcpServers', () => ({ ...stdio(), toolTimeoutMs: 900000 }),
339
+ () => exists(path.join(home, '.kimi-code'))),
340
+ jsonAgent('Junie', path.join(home, '.junie/mcp/mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.junie'))),
341
+ jsonAgent('Warp', path.join(home, '.warp/.mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.warp'))),
342
+ jsonAgent('Rovo Dev', path.join(home, '.rovodev/mcp.json'), 'mcpServers', () => ({ ...stdio(), transport: 'stdio' }),
343
+ () => exists(path.join(home, '.rovodev'))),
344
+ jsonAgent('OpenHands', path.join(home, '.openhands/mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.openhands'))),
345
+ jsonAgent('LM Studio', path.join(home, '.lmstudio/mcp.json'), 'mcpServers', stdio, () => exists(path.join(home, '.lmstudio'))),
283
346
  jsonAgent('Windsurf', path.join(home, '.codeium/windsurf/mcp_config.json'), 'mcpServers', stdio, () => exists(path.join(home, '.codeium/windsurf'))),
284
347
  jsonAgent('Gemini CLI', path.join(home, '.gemini/settings.json'), 'mcpServers', stdio, () => exists(path.join(home, '.gemini')) || has('gemini')),
285
348
  jsonAgent('OpenCode', path.join(home, '.config/opencode/opencode.json'), 'mcp',
@@ -288,6 +351,10 @@ export function createSetup(ctx) {
288
351
  ...(appSupport ? [
289
352
  jsonAgent('VS Code', path.join(appSupport, 'Code/User/mcp.json'), 'servers',
290
353
  () => ({ type: 'stdio', ...stdio() }), () => exists(path.join(appSupport, 'Code/User'))),
354
+ jsonAgent('VS Code Insiders', path.join(appSupport, 'Code - Insiders/User/mcp.json'), 'servers',
355
+ () => ({ type: 'stdio', ...stdio() }), () => exists(path.join(appSupport, 'Code - Insiders/User'))),
356
+ jsonAgent('Cline in VS Code', path.join(appSupport, 'Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json'), 'mcpServers',
357
+ () => ({ ...stdio(), timeout: 900 }), () => exists(path.join(appSupport, 'Code/User/globalStorage/saoudrizwan.claude-dev'))),
291
358
  jsonAgent('Claude Desktop', path.join(appSupport, 'Claude/claude_desktop_config.json'), 'mcpServers', stdio,
292
359
  () => exists(path.join(appSupport, 'Claude'))),
293
360
  ] : []),
@@ -389,7 +456,7 @@ export function createSetup(ctx) {
389
456
  step(4, 'Connect to Chrome');
390
457
  await connectChrome();
391
458
  console.log(failed ? '\nFix the ✗ items above, then run this again (it is safe to repeat).'
392
- : `\nAll set.${added.length ? ` Restart ${added.join(', ')} so ${added.length === 1 ? 'it loads' : 'they load'} the new server,` : ''} then ask your agent:\n "List my Chrome profiles and the tabs I have open."`);
459
+ : `\nAll set.${added.length ? ` Restart ${added.length > 4 ? `your agents (${added.length} set up above)` : added.join(', ')} so ${added.length === 1 ? 'it loads' : 'they load'} the new server,` : ''} then ask your agent:\n "List my Chrome profiles and the tabs I have open."`);
393
460
  process.exit(failed ? 1 : 0);
394
461
  }
395
462