diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c59570ea..3051af711 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,8 @@ jobs: run: sed -i '' 's|registry.npmmirror.com|registry.npmjs.org|g' bun.lock - name: Install dependencies + env: + CLAUDE_CODE_SKIP_CHROME_MCP_SETUP: '1' run: bun install --frozen-lockfile - name: Test diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 80bb154d6..f0e81cfdb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -33,6 +33,8 @@ jobs: bun-version: latest - name: Install dependencies + env: + CLAUDE_CODE_SKIP_CHROME_MCP_SETUP: '1' run: bun install - name: Initialize CodeQL diff --git a/docs/features/chrome-use-mcp.md b/docs/features/chrome-use-mcp.md new file mode 100644 index 000000000..3cbe91b5a --- /dev/null +++ b/docs/features/chrome-use-mcp.md @@ -0,0 +1,38 @@ +# Chrome Use — 浏览器自动化快速指南 + +让 Claude Code 直接控制你的 Chrome 浏览器,用自然语言完成网页操作。 + +## 快速开始(3 分钟) + +### 第一步:安装 Chrome 扩展 + +1. 下载扩展:https://github.com/hangwin/mcp-chrome/releases +2. 解压 zip 文件 +3. 打开 Chrome 访问 `chrome://extensions/` +4. 开启右上角「开发者模式」 +5. 点击「加载已解压的扩展程序」,选择解压后的文件夹 + +### 第二步:启动 CCP + +```bash +bun run dev +ccp # 或者 ccp 安装版也行 +``` + +### 第三步:启用 Chrome MCP + +1. 在 REPL 中输入 `/mcp` 打开 MCP 面板 +2. 找到 `mcp-chrome`,按空格键启用 +3. 按 Enter 确认 + +## 在 Linux 服务器上使用 + +如果你的服务器没有图形界面,可以通过以下方式使用 Chrome MCP: + +1. 在本地有 Chrome 的机器上安装扩展 +2. 通过网络将 Chrome DevTools 端口暴露给服务器 +3. 或者使用 `CLAUDE_CODE_SKIP_CHROME_MCP_SETUP=1` 跳过自动设置(之后手动执行 `node scripts/setup-chrome-mcp.mjs`) + +## 相关文档 + +- GitHub 仓库:https://github.com/hangwin/mcp-chrome diff --git a/package.json b/package.json index b68a5f870..61e114612 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "check:bundle": "bun run scripts/check-bundle-integrity.ts", "check:unused": "knip-bun", "health": "bun run scripts/health-check.ts", - "postinstall": "node scripts/postinstall.cjs", + "postinstall": "node scripts/run-parallel.mjs scripts/postinstall.cjs scripts/setup-chrome-mcp.mjs", "docs:dev": "npx mintlify dev", "typecheck": "tsc --noEmit", "precheck": "bun run typecheck && bun run check:fix && bun test", diff --git a/scripts/setup-chrome-mcp.mjs b/scripts/setup-chrome-mcp.mjs new file mode 100644 index 000000000..022fb9e42 --- /dev/null +++ b/scripts/setup-chrome-mcp.mjs @@ -0,0 +1,70 @@ +#!/usr/bin/env node + +/** + * Unified Chrome MCP setup script. + * + * Usage: + * node scripts/setup-chrome-mcp.mjs # Run full setup (fix-permissions → register → doctor) + * node scripts/setup-chrome-mcp.mjs doctor # Run a single sub-command + */ + +import { execFileSync } from 'node:child_process' +import { mkdirSync } from 'node:fs' +import { createRequire } from 'node:module' +import { homedir } from 'node:os' +import { join } from 'node:path' + +if (process.env.CLAUDE_CODE_SKIP_CHROME_MCP_SETUP === '1') { + process.exit(0) +} + +const require = createRequire(import.meta.url) +const cliPath = require.resolve( + '@claude-code-best/mcp-chrome-bridge/dist/cli.js', +) + +const userArgs = process.argv.slice(2) + +function getChromeMcpLogDir() { + const home = homedir() + if (process.platform === 'darwin') { + return join(home, 'Library', 'Logs', 'mcp-chrome-bridge') + } + if (process.platform === 'win32') { + return join( + process.env.LOCALAPPDATA || join(home, 'AppData', 'Local'), + 'mcp-chrome-bridge', + 'logs', + ) + } + return join( + process.env.XDG_STATE_HOME || join(home, '.local', 'state'), + 'mcp-chrome-bridge', + 'logs', + ) +} + +if (userArgs.length > 0) { + // Forward single sub-command + execFileSync('node', [cliPath, ...userArgs], { stdio: 'inherit' }) +} else { + // Full setup sequence + const steps = [ + ['fix-permissions'], + ['register', '--browser', 'chrome'], + ['doctor'], + ] + + mkdirSync(getChromeMcpLogDir(), { recursive: true }) + + for (let i = 0; i < steps.length; i++) { + const args = steps[i] + const isLast = i === steps.length - 1 + if (isLast) console.log(`\n[${i + 1}/${steps.length}] ${args.join(' ')}`) + execFileSync('node', [cliPath, ...args], { + stdio: isLast ? 'inherit' : 'pipe', + }) + } + + console.log('\nChrome MCP setup complete!') +}