From 83c1e613a149516e891ea2e05c5f1e1f63205b3f Mon Sep 17 00:00:00 2001 From: bookworm Date: Mon, 6 Apr 2026 00:26:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BA=B3=E5=85=A5=E6=8B=93=E5=B1=95?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=20+=20guide.html=20badges=20=E5=AF=B9?= =?UTF-8?q?=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 拓展/: MCP配置向导、PowerShell工具、mcp-auto-loader 纳入版本管理 - guide.html: badges 从模糊 "90+" 改为精确 "92 Skills | 18 Agents | 34 Hooks" --- guide.html | 6 +- 拓展/create-admin-powershell.bat | 59 +++ 拓展/install-pwsh7.bat | 162 +++++++++ 拓展/mcp-auto-loader.js | 29 ++ 拓展/mcp-config-wizard/README.md | 265 ++++++++++++++ 拓展/mcp-config-wizard/START.bat | 64 ++++ 拓展/mcp-config-wizard/START.sh | 60 ++++ 拓展/mcp-config-wizard/apply.js | 119 ++++++ 拓展/mcp-config-wizard/detect.js | 142 ++++++++ 拓展/mcp-config-wizard/package.json | 19 + 拓展/mcp-config-wizard/wizard.js | 496 ++++++++++++++++++++++++++ 11 files changed, 1418 insertions(+), 3 deletions(-) create mode 100644 拓展/create-admin-powershell.bat create mode 100644 拓展/install-pwsh7.bat create mode 100644 拓展/mcp-auto-loader.js create mode 100644 拓展/mcp-config-wizard/README.md create mode 100644 拓展/mcp-config-wizard/START.bat create mode 100644 拓展/mcp-config-wizard/START.sh create mode 100644 拓展/mcp-config-wizard/apply.js create mode 100644 拓展/mcp-config-wizard/detect.js create mode 100644 拓展/mcp-config-wizard/package.json create mode 100644 拓展/mcp-config-wizard/wizard.js diff --git a/guide.html b/guide.html index 68a27ad..616a5cd 100644 --- a/guide.html +++ b/guide.html @@ -199,10 +199,10 @@

Bookworm Portable 保姆式安装手册

从零开始,一步步教你在任意 Windows 电脑上激活 Bookworm

- 90+ 专家技能 - 多模态 AI 协作 + 92 Skills + 18 Agents + 34 Hooks AES-256 加密 - HTTPS 传输 NDA 技术保密
⬇ 下载一键安装器 diff --git a/拓展/create-admin-powershell.bat b/拓展/create-admin-powershell.bat new file mode 100644 index 0000000..a0f8146 --- /dev/null +++ b/拓展/create-admin-powershell.bat @@ -0,0 +1,59 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +echo. +echo ======================================================== +echo Create Admin PowerShell Shortcut for Claude Code +echo ======================================================== +echo. + +:: Check admin privileges +net session >nul 2>&1 +if %errorlevel% neq 0 ( + echo [!] Requesting administrator privileges... + powershell -Command "Start-Process '%~f0' -Verb RunAs" + exit /b +) + +:: Detect PowerShell path +set "PS_PATH=" +for %%p in ( + "%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" + "%ProgramFiles%\PowerShell\7\pwsh.exe" + "%ProgramFiles(x86)%\PowerShell\7\pwsh.exe" +) do ( + if exist %%p ( + set "PS_PATH=%%p" + goto :ps_found + ) +) + +:ps_found +if "!PS_PATH!" == "" ( + echo [ERROR] PowerShell not found + pause + exit /b 1 +) + +echo [OK] PowerShell: !PS_PATH! + +:: Create admin shortcut +set "SHORTCUT_PATH=%USERPROFILE%\Desktop\Claude Code (Admin Terminal).lnk" + +powershell -NoProfile -Command "$WshShell = New-Object -ComObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut('%SHORTCUT_PATH%'); $Shortcut.TargetPath = '!PS_PATH!'; $Shortcut.Arguments = '-NoExit -Command \"Write-Host ''Claude Code Admin Terminal Ready'' -ForegroundColor Green; Write-Host ''Type: claude'' -ForegroundColor Yellow\"'; $Shortcut.WorkingDirectory = '%USERPROFILE%'; $Shortcut.Description = 'PowerShell with Admin Rights for Claude Code'; $Shortcut.Save(); $bytes = [System.IO.File]::ReadAllBytes('%SHORTCUT_PATH%'); $bytes[0x15] = $bytes[0x15] -bor 0x20; [System.IO.File]::WriteAllBytes('%SHORTCUT_PATH%', $bytes)" + +if exist "%SHORTCUT_PATH%" ( + echo. + echo [SUCCESS] Admin terminal shortcut created! + echo. + echo [Usage] + echo 1. Double-click "Claude Code (Admin Terminal)" on desktop + echo 2. Type: claude + echo 3. Claude Code will run with administrator privileges + echo. +) else ( + echo [ERROR] Failed to create shortcut +) + +pause diff --git a/拓展/install-pwsh7.bat b/拓展/install-pwsh7.bat new file mode 100644 index 0000000..09f9c88 --- /dev/null +++ b/拓展/install-pwsh7.bat @@ -0,0 +1,162 @@ +@echo off +setlocal enabledelayedexpansion + +:: Check for administrator privileges +net session >nul 2>&1 +if %errorlevel% neq 0 ( + echo Requesting administrator privileges... + powershell -Command "Start-Process '%~f0' -Verb RunAs" + exit /b +) + +title PowerShell 7 Auto Setup + +echo. +echo ======================================================== +echo PowerShell 7 Auto Setup +echo Automatic Installation and Configuration +echo ======================================================== +echo. + +:: Check if PowerShell 7 is already installed +where pwsh >nul 2>nul +if %errorlevel% equ 0 ( + echo [OK] PowerShell 7 is already installed + for /f "tokens=*" %%i in ('pwsh -NoProfile -Command "$PSVersionTable.PSVersion.ToString()"') do set PWSH_VERSION=%%i + echo [INFO] Version: !PWSH_VERSION! + echo. + goto :configure +) + +echo [INFO] PowerShell 7 not found. Starting installation... +echo. + +:: Method 1: Try winget (Windows 10 1809+) +echo [1/3] Trying winget installation... +winget --version >nul 2>nul +if %errorlevel% equ 0 ( + echo [INFO] Installing via winget... + winget install --id Microsoft.PowerShell --silent --accept-package-agreements --accept-source-agreements + if %errorlevel% equ 0 ( + echo [OK] PowerShell 7 installed successfully via winget + goto :verify_install + ) +) + +:: Method 2: Try Chocolatey +echo [2/3] Trying Chocolatey installation... +where choco >nul 2>nul +if %errorlevel% equ 0 ( + echo [INFO] Installing via Chocolatey... + choco install powershell-core -y + if %errorlevel% equ 0 ( + echo [OK] PowerShell 7 installed successfully via Chocolatey + goto :verify_install + ) +) + +:: Method 3: Direct MSI download +echo [3/3] Downloading PowerShell 7 MSI installer... +powershell -NoProfile -ExecutionPolicy Bypass -Command "$ProgressPreference = 'SilentlyContinue'; $latestRelease = Invoke-RestMethod 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest'; $msiAsset = $latestRelease.assets | Where-Object { $_.name -like '*win-x64.msi' } | Select-Object -First 1; if ($msiAsset) { Write-Host '[INFO] Downloading' $msiAsset.name; Invoke-WebRequest -Uri $msiAsset.browser_download_url -OutFile '%TEMP%\PowerShell-7.msi'; exit 0; } else { Write-Host '[ERROR] Failed to find MSI asset'; exit 1; }" + +if %errorlevel% neq 0 ( + echo [ERROR] Failed to download PowerShell 7 + echo. + echo Please install manually from: https://github.com/PowerShell/PowerShell/releases + pause + exit /b 1 +) + +echo [INFO] Installing PowerShell 7... +msiexec /i "%TEMP%\PowerShell-7.msi" /quiet /norestart ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1 +set INSTALL_EXIT=%errorlevel% +del "%TEMP%\PowerShell-7.msi" >nul 2>&1 + +if %INSTALL_EXIT% neq 0 ( + echo [ERROR] Installation failed with exit code %INSTALL_EXIT% + pause + exit /b 1 +) + +:verify_install +echo. +echo [INFO] Verifying installation... +timeout /t 2 /nobreak >nul + +where pwsh >nul 2>nul +if %errorlevel% neq 0 ( + echo [ERROR] PowerShell 7 installation verification failed + echo [INFO] Trying to refresh PATH... + set "PATH=%PATH%;C:\Program Files\PowerShell\7" + where pwsh >nul 2>nul + if %errorlevel% neq 0 ( + echo [ERROR] Still cannot find pwsh.exe + echo [INFO] Please restart your computer and try again + pause + exit /b 1 + ) +) + +for /f "tokens=*" %%i in ('pwsh -NoProfile -Command "$PSVersionTable.PSVersion.ToString()"') do set PWSH_VERSION=%%i +echo [OK] PowerShell 7 installed successfully +echo [INFO] Version: !PWSH_VERSION! +echo. + +:configure +echo ======================================================== +echo Configuring Default Terminal Settings... +echo ======================================================== +echo. + +:: Get PowerShell 7 installation path +for /f "tokens=*" %%i in ('where pwsh') do set PWSH_PATH=%%i +echo [INFO] PowerShell 7 path: !PWSH_PATH! +echo. + +:: Configure Windows Terminal default profile (if installed) +echo [1/4] Configuring Windows Terminal... +reg query "HKCU\Console\%%Startup" >nul 2>&1 +if %errorlevel% equ 0 ( + reg add "HKCU\Console\%%Startup" /v DelegationConsole /t REG_SZ /d "{574e775e-4f2a-5b96-ac1e-a2962a402336}" /f >nul 2>&1 + reg add "HKCU\Console\%%Startup" /v DelegationTerminal /t REG_SZ /d "{574e775e-4f2a-5b96-ac1e-a2962a402336}" /f >nul 2>&1 + echo [OK] Windows Terminal configured +) else ( + echo [SKIP] Windows Terminal not found +) + +:: Set PowerShell 7 as default for .ps1 files +echo [2/4] Configuring file associations... +assoc .ps1=Microsoft.PowerShellScript.1 >nul 2>&1 +ftype Microsoft.PowerShellScript.1="!PWSH_PATH!" -NoLogo -ExecutionPolicy Bypass -File "%%1" %%* >nul 2>&1 +echo [OK] .ps1 files associated with PowerShell 7 + +:: Add PowerShell 7 to App Paths (for Win+R) +echo [3/4] Configuring Win+R shortcut... +reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\pwsh.exe" /ve /t REG_SZ /d "!PWSH_PATH!" /f >nul 2>&1 +reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\powershell.exe" /ve /t REG_SZ /d "!PWSH_PATH!" /f >nul 2>&1 +echo [OK] Win+R configured (type 'pwsh' or 'powershell') + +:: Set PowerShell 7 as default shell for developers +echo [4/4] Configuring developer settings... +reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v DefaultTerminalApplication /t REG_SZ /d "{574e775e-4f2a-5b96-ac1e-a2962a402336}" /f >nul 2>&1 +echo [OK] Developer settings configured + +echo. +echo ======================================================== +echo Installation and Configuration Complete! +echo ======================================================== +echo. +echo [OK] PowerShell 7 installed: !PWSH_VERSION! +echo [OK] Default terminal configured +echo [OK] File associations updated +echo [OK] Win+R shortcut configured +echo. +echo [IMPORTANT] Please restart your computer for all changes +echo to take effect, especially Win+R shortcut. +echo. +echo After restart: +echo - Press Win+R and type 'pwsh' or 'powershell' +echo - Right-click .ps1 files to run with PowerShell 7 +echo - Windows Terminal will use PowerShell 7 by default +echo. +pause diff --git a/拓展/mcp-auto-loader.js b/拓展/mcp-auto-loader.js new file mode 100644 index 0000000..24a2ba5 --- /dev/null +++ b/拓展/mcp-auto-loader.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const { execSync } = require('child_process'); + +console.log('MCP Auto Loader v1.0'); +console.log('====================\n'); + +const outputDir = 'E:\'; +const services = { + playwright: '@modelcontextprotocol/server-playwright', + 'chrome-devtools': '@executeautomation/chrome-devtools-mcp', + github: '@modelcontextprotocol/server-github', + slack: '@modelcontextprotocol/server-slack', + linear: '@modelcontextprotocol/server-linear' +}; + +const mcpServers = {}; +for (const [name, pkg] of Object.entries(services)) { + mcpServers[name] = { + command: 'cmd', + args: ['/c', 'npx', '-y', pkg] + }; +} + +const configPath = path.join(outputDir, 'mcp-configs-summary.json'); +fs.writeFileSync(configPath, JSON.stringify({ mcpServers }, null, 2)); +console.log('Config saved to:', configPath); diff --git a/拓展/mcp-config-wizard/README.md b/拓展/mcp-config-wizard/README.md new file mode 100644 index 0000000..beac86a --- /dev/null +++ b/拓展/mcp-config-wizard/README.md @@ -0,0 +1,265 @@ +# MCP Configuration Wizard + +Universal MCP configuration tool for Claude Code - works on any system, any user. + +## 🎯 Features + +- **Auto-Detection**: Automatically detects your system, existing configs, and environment +- **Interactive Wizard**: Step-by-step guided setup +- **Cross-Platform**: Works on Windows, macOS, and Linux +- **Safe Installation**: Backup existing configs before changes +- **Export/Import**: Share configurations between machines +- **19 MCP Services**: Pre-configured popular services + +## 📦 Quick Start + +### 1. Install Dependencies + +```bash +npm install +``` + +### 2. Detect Your System + +```bash +npm run detect +``` + +This will scan your system and detect: +- Claude Code installation +- Existing MCP configurations +- Environment variables +- Installed npm packages + +### 3. Run Configuration Wizard + +```bash +npm start +``` + +Choose from 4 modes: +1. **Quick Setup** - Install recommended services (no API keys needed) +2. **Custom Setup** - Choose specific services +3. **Import** - Load configuration from file +4. **Export** - Save current config for another machine + +### 4. Apply Configuration + +```bash +npm run apply +``` + +This will: +- Install MCP configuration to `~/.claude.json` +- Generate environment variable scripts +- Create installation guide + +### 5. Restart Claude Code + +Close and reopen Claude Code to load the new MCP services. + +## 🔧 Configuration Modes + +### Quick Setup (Recommended for beginners) + +Installs 6 essential services that work without API keys: +- playwright - Browser automation +- chrome-devtools - Chrome DevTools integration +- context7 - Programming documentation +- deep-research - Research assistant +- sequential-thinking - Reasoning engine +- scrapling - Web scraping + +### Custom Setup (For advanced users) + +Choose from 19 services across categories: +- **Automation**: playwright, chrome-devtools, browserbase +- **Development**: github, vercel, firebase +- **Communication**: slack +- **Productivity**: linear, notion +- **Documentation**: context7 +- **Research**: deep-research +- **Web**: scrapling, firecrawl +- **Database**: supabase +- **Monitoring**: sentry +- **Infrastructure**: cloudflare + +### Import/Export + +**Export** your configuration to share with another machine: +```bash +npm start +# Select option 4 +``` + +**Import** a configuration file: +```bash +npm start +# Select option 3 +# Enter path to config file +``` + +## 📋 Available Services + +### No API Key Required (9 services) + +| Service | Description | Category | +|---------|-------------|----------| +| playwright | Browser automation testing | Automation | +| chrome-devtools | Chrome DevTools integration | Automation | +| context7 | Programming documentation | Documentation | +| deep-research | Deep research assistant | Research | +| sequential-thinking | Sequential reasoning | Reasoning | +| scrapling | Web scraping tool | Web | +| figma | Figma design integration | Design | + +### API Key Required (10 services) + +| Service | Description | Setup Link | +|---------|-------------|------------| +| github | GitHub repository integration | [Get Token](https://github.com/settings/tokens) | +| slack | Slack team collaboration | [Create App](https://api.slack.com/apps) | +| linear | Linear project management | [API Settings](https://linear.app/settings/api) | +| browserbase | Cloud browser service | [Dashboard](https://browserbase.com) | +| cloudflare | Cloudflare CDN management | [API Tokens](https://dash.cloudflare.com/profile/api-tokens) | +| firecrawl | Intelligent web crawler | [Sign Up](https://firecrawl.dev) | +| supabase | Supabase database | [API Settings](https://supabase.com/dashboard) | +| sentry | Error monitoring | [Auth Tokens](https://sentry.io/settings/account/api/auth-tokens/) | +| notion | Notion knowledge base | [Integrations](https://www.notion.so/my-integrations) | +| vercel | Vercel deployment | [Tokens](https://vercel.com/account/tokens) | +| firebase | Firebase backend | [Service Accounts](https://console.firebase.google.com) | + +## 🔐 Environment Variables + +The wizard generates scripts to set environment variables: + +**Windows (PowerShell):** +```powershell +.\apply-env.ps1 +``` + +**Unix/Mac (Bash/Zsh):** +```bash +source ./apply-env.sh +``` + +Or set them manually from `generated-env.json`. + +## 📁 Generated Files + +After running the wizard, you'll get: + +- `detection-result.json` - System detection results +- `generated-claude.json` - MCP configuration for Claude Code +- `generated-env.json` - Environment variables (JSON format) +- `apply-env.ps1` - PowerShell script (Windows) +- `apply-env.sh` - Shell script (Unix/Mac) +- `INSTALL.md` - Installation guide + +## 🚀 Usage Examples + +### Example 1: First-time setup on new machine + +```bash +npm install +npm run detect +npm start +# Choose option 1 (Quick Setup) +npm run apply +# Restart Claude Code +``` + +### Example 2: Add GitHub integration + +```bash +npm start +# Choose option 2 (Custom Setup) +# Enter: github +# Enter your GitHub token +npm run apply +# Restart Claude Code +``` + +### Example 3: Export config for another machine + +```bash +npm start +# Choose option 4 (Export) +# Copy mcp-config-export.json to other machine +``` + +On the other machine: +```bash +npm install +npm start +# Choose option 3 (Import) +# Enter path to mcp-config-export.json +npm run apply +``` + +## 🛠️ Manual Installation + +If automatic installation fails: + +1. Copy content from `generated-claude.json` +2. Paste into `~/.claude.json` (create if doesn't exist) +3. Set environment variables from `generated-env.json` +4. Restart Claude Code + +## ⚠️ Troubleshooting + +### "Cannot find module 'inquirer'" + +```bash +npm install +``` + +### "Permission denied" on Unix/Mac + +```bash +chmod +x apply-env.sh +``` + +### PowerShell execution policy error + +```powershell +Set-ExecutionPolicy RemoteSigned -Scope CurrentUser +``` + +### MCP services not loading + +1. Check `~/.claude.json` exists and has `mcpServers` section +2. Verify environment variables are set: `echo $GITHUB_PERSONAL_ACCESS_TOKEN` +3. Restart Claude Code completely +4. Check Claude Code logs for errors + +## 📖 Documentation + +- [MCP Protocol](https://modelcontextprotocol.io/) +- [Claude Code](https://claude.ai/code) +- [Service Documentation](./docs/services.md) + +## 🤝 Contributing + +Contributions welcome! To add a new MCP service: + +1. Add service definition to `MCP_SERVICES` in `wizard.js` +2. Include package name, description, category, and required env vars +3. Test with `npm start` +4. Submit PR + +## 📄 License + +MIT + +## 🔗 Links + +- [MCP Official Site](https://modelcontextprotocol.io/) +- [Claude Code](https://claude.ai/code) +- [GitHub Repository](https://github.com/your-repo/mcp-config-wizard) + +--- + +**Version**: 1.0.0 +**Last Updated**: 2026-04-04 +**Maintained by**: Bookworm Team diff --git a/拓展/mcp-config-wizard/START.bat b/拓展/mcp-config-wizard/START.bat new file mode 100644 index 0000000..16aec5a --- /dev/null +++ b/拓展/mcp-config-wizard/START.bat @@ -0,0 +1,64 @@ +@echo off +chcp 65001 >nul +title MCP Configuration Wizard - Setup + +echo. +echo ╔════════════════════════════════════════════════════════╗ +echo ║ MCP Configuration Wizard - First Time Setup ║ +echo ╚════════════════════════════════════════════════════════╝ +echo. + +REM 检查 Node.js 是否安装 +where node >nul 2>nul +if %errorlevel% neq 0 ( + echo [ERROR] Node.js is not installed! + echo. + echo Please install Node.js from: https://nodejs.org/ + echo. + pause + exit /b 1 +) + +echo [OK] Node.js found: +node --version +echo. + +REM 检查是否已安装依赖 +if exist "node_modules\" ( + echo [OK] Dependencies already installed + echo. + goto :run_wizard +) + +echo [INFO] Installing dependencies... +echo This may take a minute... +echo. + +call npm install + +if %errorlevel% neq 0 ( + echo. + echo [ERROR] Failed to install dependencies + echo. + pause + exit /b 1 +) + +echo. +echo [OK] Dependencies installed successfully +echo. + +:run_wizard +echo ════════════════════════════════════════════════════════ +echo Starting Configuration Wizard... +echo ════════════════════════════════════════════════════════ +echo. + +node wizard.js + +echo. +echo ════════════════════════════════════════════════════════ +echo Wizard completed +echo ════════════════════════════════════════════════════════ +echo. +pause diff --git a/拓展/mcp-config-wizard/START.sh b/拓展/mcp-config-wizard/START.sh new file mode 100644 index 0000000..577308c --- /dev/null +++ b/拓展/mcp-config-wizard/START.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# MCP Configuration Wizard - Launcher for Unix/Mac + +echo "" +echo "╔════════════════════════════════════════════════════════╗" +echo "║ MCP Configuration Wizard - First Time Setup ║" +echo "╚════════════════════════════════════════════════════════╝" +echo "" + +# 检查 Node.js +if ! command -v node &> /dev/null; then + echo "[ERROR] Node.js is not installed!" + echo "" + echo "Please install Node.js from: https://nodejs.org/" + echo "" + read -p "Press Enter to exit..." + exit 1 +fi + +echo "[OK] Node.js found: $(node --version)" +echo "" + +# 检查依赖 +if [ -d "node_modules" ]; then + echo "[OK] Dependencies already installed" + echo "" +else + echo "[INFO] Installing dependencies..." + echo "This may take a minute..." + echo "" + + npm install + + if [ $? -ne 0 ]; then + echo "" + echo "[ERROR] Failed to install dependencies" + echo "" + read -p "Press Enter to exit..." + exit 1 + fi + + echo "" + echo "[OK] Dependencies installed successfully" + echo "" +fi + +# 运行向导 +echo "════════════════════════════════════════════════════════" +echo "Starting Configuration Wizard..." +echo "════════════════════════════════════════════════════════" +echo "" + +node wizard.js + +echo "" +echo "════════════════════════════════════════════════════════" +echo "Wizard completed" +echo "════════════════════════════════════════════════════════" +echo "" +read -p "Press Enter to exit..." diff --git a/拓展/mcp-config-wizard/apply.js b/拓展/mcp-config-wizard/apply.js new file mode 100644 index 0000000..3ed277c --- /dev/null +++ b/拓展/mcp-config-wizard/apply.js @@ -0,0 +1,119 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const readline = require('readline'); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +function question(prompt) { + return new Promise(resolve => rl.question(prompt, resolve)); +} + +async function main() { + console.log('╔════════════════════════════════════════════════════════╗'); + console.log('║ MCP Configuration Installer ║'); + console.log('╚════════════════════════════════════════════════════════╝\n'); + + // 检查生成的配置文件 + const generatedConfig = path.join(__dirname, 'generated-claude.json'); + if (!fs.existsSync(generatedConfig)) { + console.log('✗ No configuration found. Run "node wizard.js" first.'); + rl.close(); + return; + } + + const config = JSON.parse(fs.readFileSync(generatedConfig, 'utf-8')); + console.log(`Found configuration with ${Object.keys(config.mcpServers).length} MCP services\n`); + + // 目标配置文件路径 + const targetConfig = path.join(os.homedir(), '.claude.json'); + let existingConfig = {}; + + // 检查现有配置 + if (fs.existsSync(targetConfig)) { + console.log('⚠ Existing .claude.json found\n'); + console.log('Installation options:'); + console.log(' 1. Merge - Keep existing settings, add/update MCP servers'); + console.log(' 2. Replace - Overwrite with new configuration'); + console.log(' 3. Backup & Replace - Backup existing, then replace'); + console.log(' 4. Cancel\n'); + + const choice = await question('Select option (1-4): '); + + switch (choice) { + case '1': + existingConfig = JSON.parse(fs.readFileSync(targetConfig, 'utf-8')); + existingConfig.mcpServers = { + ...(existingConfig.mcpServers || {}), + ...config.mcpServers + }; + break; + case '2': + existingConfig = config; + break; + case '3': + const backupPath = targetConfig + `.backup-${Date.now()}`; + fs.copyFileSync(targetConfig, backupPath); + console.log(`\n✓ Backup created: ${backupPath}`); + existingConfig = config; + break; + case '4': + console.log('\nInstallation cancelled'); + rl.close(); + return; + default: + console.log('\nInvalid option'); + rl.close(); + return; + } + } else { + existingConfig = config; + } + + // 写入配置 + try { + fs.writeFileSync(targetConfig, JSON.stringify(existingConfig, null, 2)); + console.log(`\n✓ Configuration installed to: ${targetConfig}`); + } catch (e) { + console.log(`\n✗ Failed to write configuration: ${e.message}`); + console.log('\nManual installation:'); + console.log(` 1. Copy ${generatedConfig}`); + console.log(` 2. To ${targetConfig}`); + rl.close(); + return; + } + + // 应用环境变量 + const envFile = path.join(__dirname, 'generated-env.json'); + if (fs.existsSync(envFile)) { + console.log('\n=== Environment Variables ===\n'); + console.log('Environment variables need to be set manually:'); + + if (os.platform() === 'win32') { + console.log('\nWindows: Run the PowerShell script:'); + console.log(' .\\apply-env.ps1'); + } else { + console.log('\nUnix/Mac: Source the shell script:'); + console.log(' source ./apply-env.sh'); + } + + console.log('\nOr set them manually from: generated-env.json'); + } + + console.log('\n╔════════════════════════════════════════════════════════╗'); + console.log('║ Installation Complete ║'); + console.log('╚════════════════════════════════════════════════════════╝'); + console.log('\n✓ MCP configuration installed successfully'); + console.log('\n📋 Next steps:'); + console.log(' 1. Set environment variables (if needed)'); + console.log(' 2. Restart Claude Code'); + console.log(' 3. Verify MCP services are loaded\n'); + + rl.close(); +} + +main().catch(console.error); diff --git a/拓展/mcp-config-wizard/detect.js b/拓展/mcp-config-wizard/detect.js new file mode 100644 index 0000000..cbf82fe --- /dev/null +++ b/拓展/mcp-config-wizard/detect.js @@ -0,0 +1,142 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const { execSync } = require('child_process'); + +console.log('╔════════════════════════════════════════════════════════╗'); +console.log('║ MCP Configuration Wizard - System Detection ║'); +console.log('╚════════════════════════════════════════════════════════╝\n'); + +// 检测系统信息 +const detection = { + timestamp: new Date().toISOString(), + system: { + platform: os.platform(), + username: os.userInfo().username, + homedir: os.homedir(), + nodeVersion: process.version + }, + claude: { + configDir: null, + configFile: null, + hasExistingConfig: false, + existingMcpServers: [] + }, + environment: { + variables: {}, + mcpRelated: [] + }, + npm: { + globalPackages: [], + mcpPackages: [] + } +}; + +// 1. 检测 Claude Code 配置目录 +console.log('🔍 Detecting Claude Code configuration...'); +const possibleConfigDirs = [ + path.join(os.homedir(), '.claude'), + path.join(os.homedir(), 'AppData', 'Roaming', 'Claude'), + path.join(os.homedir(), 'Library', 'Application Support', 'Claude') +]; + +for (const dir of possibleConfigDirs) { + if (fs.existsSync(dir)) { + detection.claude.configDir = dir; + console.log(` ✓ Found: ${dir}`); + break; + } +} + +if (!detection.claude.configDir) { + console.log(' ⚠ Claude config directory not found, will create on apply'); +} + +// 检测现有配置文件 +const configFile = path.join(os.homedir(), '.claude.json'); +if (fs.existsSync(configFile)) { + detection.claude.configFile = configFile; + detection.claude.hasExistingConfig = true; + try { + const config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); + if (config.mcpServers) { + detection.claude.existingMcpServers = Object.keys(config.mcpServers); + console.log(` ✓ Existing config found with ${detection.claude.existingMcpServers.length} MCP servers`); + } + } catch (e) { + console.log(' ⚠ Config file exists but cannot be parsed'); + } +} else { + console.log(' ℹ No existing .claude.json found'); +} + +// 2. 检测环境变量 +console.log('\n🔍 Detecting environment variables...'); +const mcpEnvVars = [ + 'GITHUB_PERSONAL_ACCESS_TOKEN', + 'SLACK_BOT_TOKEN', 'SLACK_TEAM_ID', + 'LINEAR_API_KEY', + 'BROWSERBASE_PROJECT_ID', 'BROWSERBASE_API_KEY', + 'CLOUDFLARE_API_TOKEN', + 'FIRECRAWL_API_KEY', + 'SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY', + 'SENTRY_AUTH_TOKEN', + 'NOTION_API_KEY', + 'VERCEL_TOKEN', + 'FIREBASE_PROJECT_ID', 'FIREBASE_PRIVATE_KEY', 'FIREBASE_CLIENT_EMAIL' +]; + +mcpEnvVars.forEach(varName => { + const value = process.env[varName]; + if (value) { + detection.environment.mcpRelated.push(varName); + detection.environment.variables[varName] = value.substring(0, 10) + '...'; // 只保存前缀用于检测 + } +}); + +console.log(` ✓ Found ${detection.environment.mcpRelated.length} MCP-related environment variables`); +detection.environment.mcpRelated.forEach(v => console.log(` - ${v}`)); + +// 3. 检测已安装的 npm 包 +console.log('\n🔍 Detecting installed npm packages...'); +try { + const globalList = execSync('npm list -g --depth=0 --json', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }); + const packages = JSON.parse(globalList); + if (packages.dependencies) { + detection.npm.globalPackages = Object.keys(packages.dependencies); + + // 筛选 MCP 相关包 + const mcpKeywords = ['mcp', 'modelcontextprotocol', 'claude']; + detection.npm.mcpPackages = detection.npm.globalPackages.filter(pkg => + mcpKeywords.some(kw => pkg.toLowerCase().includes(kw)) + ); + + if (detection.npm.mcpPackages.length > 0) { + console.log(` ✓ Found ${detection.npm.mcpPackages.length} MCP packages installed globally`); + detection.npm.mcpPackages.forEach(p => console.log(` - ${p}`)); + } else { + console.log(' ℹ No MCP packages found (will use npx)'); + } + } +} catch (e) { + console.log(' ⚠ Cannot detect npm packages (npm may not be installed)'); +} + +// 4. 保存检测结果 +const outputFile = path.join(__dirname, 'detection-result.json'); +fs.writeFileSync(outputFile, JSON.stringify(detection, null, 2)); + +console.log('\n╔════════════════════════════════════════════════════════╗'); +console.log('║ Detection Complete ║'); +console.log('╚════════════════════════════════════════════════════════╝'); +console.log(`\n📄 Results saved to: ${outputFile}`); +console.log('\n📊 Summary:'); +console.log(` Platform: ${detection.system.platform}`); +console.log(` User: ${detection.system.username}`); +console.log(` Claude Config: ${detection.claude.configDir || 'Not found'}`); +console.log(` Existing MCP Servers: ${detection.claude.existingMcpServers.length}`); +console.log(` Environment Variables: ${detection.environment.mcpRelated.length}`); +console.log(` MCP Packages: ${detection.npm.mcpPackages.length}`); + +console.log('\n💡 Next step: Run "node wizard.js" to configure MCP services'); diff --git a/拓展/mcp-config-wizard/package.json b/拓展/mcp-config-wizard/package.json new file mode 100644 index 0000000..e6a4020 --- /dev/null +++ b/拓展/mcp-config-wizard/package.json @@ -0,0 +1,19 @@ +{ + "name": "mcp-config-wizard", + "version": "1.0.0", + "description": "Universal MCP Configuration Wizard for Claude Code", + "main": "wizard.js", + "scripts": { + "start": "node wizard.js", + "detect": "node detect.js", + "apply": "node apply.js" + }, + "keywords": ["mcp", "claude-code", "configuration"], + "author": "Bookworm Team", + "license": "MIT", + "dependencies": { + "inquirer": "^8.2.5", + "chalk": "^4.1.2", + "ora": "^5.4.1" + } +} diff --git a/拓展/mcp-config-wizard/wizard.js b/拓展/mcp-config-wizard/wizard.js new file mode 100644 index 0000000..e341a9c --- /dev/null +++ b/拓展/mcp-config-wizard/wizard.js @@ -0,0 +1,496 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const readline = require('readline'); + +// MCP 服务定义 +const MCP_SERVICES = { + // 无需环境变量的服务 + 'playwright': { + package: '@modelcontextprotocol/server-playwright', + description: '浏览器自动化测试', + category: 'automation', + envVars: [] + }, + 'chrome-devtools': { + package: '@executeautomation/chrome-devtools-mcp', + description: 'Chrome 开发者工具集成', + category: 'automation', + envVars: [] + }, + 'context7': { + package: 'context7-mcp', + description: '编程文档查询', + category: 'documentation', + envVars: [] + }, + 'deep-research': { + package: 'deep-research-mcp', + description: '深度研究助手', + category: 'research', + envVars: [] + }, + 'sequential-thinking': { + package: '@modelcontextprotocol/server-sequential-thinking', + description: '顺序思考推理', + category: 'reasoning', + envVars: [] + }, + 'scrapling': { + package: 'scrapling-mcp', + description: '网页抓取工具', + category: 'web', + envVars: [] + }, + 'figma': { + package: '@figma/mcp-server-figma', + description: 'Figma 设计工具集成', + category: 'design', + envVars: [], + oauth: true + }, + + // 需要环境变量的服务 + 'github': { + package: '@modelcontextprotocol/server-github', + description: 'GitHub 代码仓库集成', + category: 'development', + envVars: ['GITHUB_PERSONAL_ACCESS_TOKEN'], + setup: 'https://github.com/settings/tokens' + }, + 'slack': { + package: '@modelcontextprotocol/server-slack', + description: 'Slack 团队协作', + category: 'communication', + envVars: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'], + setup: 'https://api.slack.com/apps' + }, + 'linear': { + package: '@modelcontextprotocol/server-linear', + description: 'Linear 项目管理', + category: 'productivity', + envVars: ['LINEAR_API_KEY'], + setup: 'https://linear.app/settings/api' + }, + 'browserbase': { + package: '@browserbasehq/mcp-server-browserbase', + description: '云端浏览器服务', + category: 'automation', + envVars: ['BROWSERBASE_PROJECT_ID', 'BROWSERBASE_API_KEY'], + setup: 'https://browserbase.com' + }, + 'cloudflare': { + package: '@cloudflare/mcp-server-cloudflare', + description: 'Cloudflare CDN 管理', + category: 'infrastructure', + envVars: ['CLOUDFLARE_API_TOKEN'], + setup: 'https://dash.cloudflare.com/profile/api-tokens' + }, + 'firecrawl': { + package: '@mendable/firecrawl-mcp', + description: '智能网页爬虫', + category: 'web', + envVars: ['FIRECRAWL_API_KEY'], + setup: 'https://firecrawl.dev' + }, + 'supabase': { + package: '@supabase/mcp-server-supabase', + description: 'Supabase 数据库', + category: 'database', + envVars: ['SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY'], + setup: 'https://supabase.com/dashboard/project/_/settings/api' + }, + 'sentry': { + package: '@sentry/mcp-server', + description: 'Sentry 错误监控', + category: 'monitoring', + envVars: ['SENTRY_AUTH_TOKEN'], + setup: 'https://sentry.io/settings/account/api/auth-tokens/' + }, + 'notion': { + package: '@notionhq/mcp-server', + description: 'Notion 知识库', + category: 'productivity', + envVars: ['NOTION_API_KEY'], + setup: 'https://www.notion.so/my-integrations' + }, + 'vercel': { + package: '@vercel/mcp-server', + description: 'Vercel 部署平台', + category: 'deployment', + envVars: ['VERCEL_TOKEN'], + setup: 'https://vercel.com/account/tokens' + }, + 'firebase': { + package: '@firebase/mcp-server', + description: 'Firebase 后端服务', + category: 'backend', + envVars: ['FIREBASE_PROJECT_ID', 'FIREBASE_PRIVATE_KEY', 'FIREBASE_CLIENT_EMAIL'], + setup: 'https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk' + } +}; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +function question(prompt) { + return new Promise(resolve => rl.question(prompt, resolve)); +} + +async function main() { + console.log('╔════════════════════════════════════════════════════════╗'); + console.log('║ MCP Configuration Wizard v1.0 ║'); + console.log('║ Universal Setup Tool for Claude Code ║'); + console.log('╚════════════════════════════════════════════════════════╝\n'); + + // 加载检测结果 + let detection = null; + const detectionFile = path.join(__dirname, 'detection-result.json'); + if (fs.existsSync(detectionFile)) { + detection = JSON.parse(fs.readFileSync(detectionFile, 'utf-8')); + console.log('✓ Loaded system detection results\n'); + } else { + console.log('⚠ No detection results found. Run "node detect.js" first.\n'); + const proceed = await question('Continue anyway? (y/n): '); + if (proceed.toLowerCase() !== 'y') { + rl.close(); + return; + } + } + + console.log('This wizard will help you configure MCP services for Claude Code.\n'); + console.log('Available configuration modes:'); + console.log(' 1. Quick Setup - Install recommended services'); + console.log(' 2. Custom Setup - Choose services manually'); + console.log(' 3. Import from file - Load existing configuration'); + console.log(' 4. Export current config - Save for another machine\n'); + + const mode = await question('Select mode (1-4): '); + + const config = { + mcpServers: {}, + environment: {} + }; + + switch (mode) { + case '1': + await quickSetup(config, detection); + break; + case '2': + await customSetup(config, detection); + break; + case '3': + await importConfig(config); + break; + case '4': + await exportConfig(detection); + rl.close(); + return; + default: + console.log('Invalid selection'); + rl.close(); + return; + } + + // 生成配置文件 + await generateConfig(config, detection); + + rl.close(); +} + +async function quickSetup(config, detection) { + console.log('\n=== Quick Setup ===\n'); + console.log('Installing recommended services:'); + + const recommended = [ + 'playwright', 'chrome-devtools', 'context7', + 'deep-research', 'sequential-thinking', 'scrapling' + ]; + + recommended.forEach(name => { + const service = MCP_SERVICES[name]; + console.log(` ✓ ${name} - ${service.description}`); + addService(config, name, service); + }); + + console.log('\nOptional services with API keys:'); + console.log(' - github, slack, linear, supabase, etc.\n'); + + const addMore = await question('Configure services with API keys? (y/n): '); + if (addMore.toLowerCase() === 'y') { + await configureApiServices(config, detection); + } +} + +async function customSetup(config, detection) { + console.log('\n=== Custom Setup ===\n'); + console.log('Available services by category:\n'); + + const categories = {}; + Object.entries(MCP_SERVICES).forEach(([name, service]) => { + if (!categories[service.category]) { + categories[service.category] = []; + } + categories[service.category].push({ name, ...service }); + }); + + for (const [category, services] of Object.entries(categories)) { + console.log(`\n${category.toUpperCase()}:`); + services.forEach((s, i) => { + const envInfo = s.envVars.length > 0 ? ' (requires API key)' : ''; + console.log(` ${i + 1}. ${s.name} - ${s.description}${envInfo}`); + }); + } + + console.log('\nEnter service names separated by commas (or "all" for all services):'); + const selection = await question('Services: '); + + if (selection.toLowerCase() === 'all') { + Object.entries(MCP_SERVICES).forEach(([name, service]) => { + addService(config, name, service); + }); + } else { + const selected = selection.split(',').map(s => s.trim()); + selected.forEach(name => { + if (MCP_SERVICES[name]) { + addService(config, name, MCP_SERVICES[name]); + } + }); + } + + await configureApiServices(config, detection); +} + +async function configureApiServices(config, detection) { + console.log('\n=== API Key Configuration ===\n'); + + for (const [name, service] of Object.entries(config.mcpServers)) { + const serviceDef = MCP_SERVICES[name]; + if (serviceDef.envVars && serviceDef.envVars.length > 0) { + console.log(`\n${name} requires:`); + serviceDef.envVars.forEach(v => console.log(` - ${v}`)); + + if (serviceDef.setup) { + console.log(` Setup: ${serviceDef.setup}`); + } + + // 检查是否已有环境变量 + const hasExisting = detection && serviceDef.envVars.every(v => + detection.environment.mcpRelated.includes(v) + ); + + if (hasExisting) { + console.log(' ✓ Found existing environment variables'); + const useExisting = await question(' Use existing? (y/n): '); + if (useExisting.toLowerCase() === 'y') { + continue; + } + } + + const configure = await question(' Configure now? (y/n): '); + if (configure.toLowerCase() === 'y') { + for (const varName of serviceDef.envVars) { + const value = await question(` ${varName}: `); + if (value) { + config.environment[varName] = value; + } + } + } + } + } +} + +async function importConfig(config) { + console.log('\n=== Import Configuration ===\n'); + const filePath = await question('Enter path to config file (.json): '); + + if (fs.existsSync(filePath)) { + const imported = JSON.parse(fs.readFileSync(filePath, 'utf-8')); + if (imported.mcpServers) { + config.mcpServers = imported.mcpServers; + console.log(`✓ Imported ${Object.keys(config.mcpServers).length} services`); + } + if (imported.environment) { + config.environment = imported.environment; + console.log(`✓ Imported ${Object.keys(config.environment).length} environment variables`); + } + } else { + console.log('✗ File not found'); + } +} + +async function exportConfig(detection) { + console.log('\n=== Export Configuration ===\n'); + + if (!detection || !detection.claude.hasExistingConfig) { + console.log('✗ No existing configuration found'); + return; + } + + const configFile = path.join(os.homedir(), '.claude.json'); + const config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); + + const exportData = { + mcpServers: config.mcpServers || {}, + environment: {} + }; + + // 导出环境变量 + if (detection.environment.mcpRelated.length > 0) { + console.log('Export environment variables?'); + const exportEnv = await question('(y/n): '); + if (exportEnv.toLowerCase() === 'y') { + detection.environment.mcpRelated.forEach(varName => { + const value = process.env[varName]; + if (value) { + exportData.environment[varName] = value; + } + }); + } + } + + const outputPath = path.join(__dirname, 'mcp-config-export.json'); + fs.writeFileSync(outputPath, JSON.stringify(exportData, null, 2)); + console.log(`\n✓ Configuration exported to: ${outputPath}`); +} + +function addService(config, name, service) { + const isWindows = os.platform() === 'win32'; + const command = isWindows ? 'cmd' : 'npx'; + const args = isWindows + ? ['/c', 'npx', '-y', service.package] + : ['-y', service.package]; + + config.mcpServers[name] = { command, args }; + + if (service.envVars && service.envVars.length > 0) { + config.mcpServers[name].env = {}; + service.envVars.forEach(v => { + config.mcpServers[name].env[v] = `\${${v}}`; + }); + } +} + +async function generateConfig(config, detection) { + console.log('\n=== Generating Configuration Files ===\n'); + + // 1. 生成 .claude.json + const claudeConfigPath = path.join(__dirname, 'generated-claude.json'); + fs.writeFileSync(claudeConfigPath, JSON.stringify({ mcpServers: config.mcpServers }, null, 2)); + console.log(`✓ Generated: ${claudeConfigPath}`); + + // 2. 生成环境变量文件 + if (Object.keys(config.environment).length > 0) { + const envPath = path.join(__dirname, 'generated-env.json'); + fs.writeFileSync(envPath, JSON.stringify(config.environment, null, 2)); + console.log(`✓ Generated: ${envPath}`); + + // 生成 PowerShell 脚本(Windows) + if (os.platform() === 'win32') { + const psScript = generatePowerShellScript(config.environment); + const psPath = path.join(__dirname, 'apply-env.ps1'); + fs.writeFileSync(psPath, psScript); + console.log(`✓ Generated: ${psPath}`); + } + + // 生成 Shell 脚本(Unix) + const shScript = generateShellScript(config.environment); + const shPath = path.join(__dirname, 'apply-env.sh'); + fs.writeFileSync(shPath, shScript); + fs.chmodSync(shPath, '755'); + console.log(`✓ Generated: ${shPath}`); + } + + // 3. 生成安装说明 + const readme = generateReadme(config, detection); + const readmePath = path.join(__dirname, 'INSTALL.md'); + fs.writeFileSync(readmePath, readme); + console.log(`✓ Generated: ${readmePath}`); + + console.log('\n╔════════════════════════════════════════════════════════╗'); + console.log('║ Configuration Generated Successfully ║'); + console.log('╚════════════════════════════════════════════════════════╝'); + console.log('\nNext steps:'); + console.log(' 1. Review generated files'); + console.log(' 2. Run "node apply.js" to install configuration'); + console.log(' 3. Restart Claude Code'); +} + +function generatePowerShellScript(env) { + let script = '# MCP Environment Variables Setup\n'; + script += '# Generated by MCP Configuration Wizard\n\n'; + script += '$ErrorActionPreference = "Continue"\n\n'; + script += 'Write-Host "Setting up MCP environment variables..." -ForegroundColor Cyan\n\n'; + + Object.entries(env).forEach(([key, value]) => { + script += `[System.Environment]::SetEnvironmentVariable("${key}", "${value}", [System.EnvironmentVariableTarget]::User)\n`; + script += `Write-Host "[OK] ${key}" -ForegroundColor Green\n`; + }); + + script += '\nWrite-Host "\\nEnvironment variables configured successfully!" -ForegroundColor Green\n'; + script += 'Write-Host "Please restart Claude Code to apply changes" -ForegroundColor Yellow\n'; + script += 'Read-Host "\\nPress Enter to exit"\n'; + + return script; +} + +function generateShellScript(env) { + let script = '#!/bin/bash\n'; + script += '# MCP Environment Variables Setup\n'; + script += '# Generated by MCP Configuration Wizard\n\n'; + + Object.entries(env).forEach(([key, value]) => { + script += `export ${key}="${value}"\n`; + }); + + script += '\necho "Environment variables configured for this session"\n'; + script += 'echo "To make permanent, add these exports to your ~/.bashrc or ~/.zshrc"\n'; + + return script; +} + +function generateReadme(config, detection) { + let readme = '# MCP Configuration Installation Guide\n\n'; + readme += 'Generated by MCP Configuration Wizard\n\n'; + readme += `## System Information\n\n`; + + if (detection) { + readme += `- Platform: ${detection.system.platform}\n`; + readme += `- User: ${detection.system.username}\n`; + readme += `- Node.js: ${detection.system.nodeVersion}\n\n`; + } + + readme += `## Configured Services (${Object.keys(config.mcpServers).length})\n\n`; + Object.keys(config.mcpServers).forEach(name => { + const service = MCP_SERVICES[name]; + readme += `- **${name}**: ${service.description}\n`; + }); + + readme += '\n## Installation Steps\n\n'; + readme += '### 1. Apply Environment Variables\n\n'; + + if (os.platform() === 'win32') { + readme += '**Windows:**\n```powershell\n.\\apply-env.ps1\n```\n\n'; + } + + readme += '**Unix/Mac:**\n```bash\nsource ./apply-env.sh\n```\n\n'; + + readme += '### 2. Install MCP Configuration\n\n'; + readme += '```bash\nnode apply.js\n```\n\n'; + + readme += '### 3. Restart Claude Code\n\n'; + readme += 'Close and reopen Claude Code to load the new MCP services.\n\n'; + + readme += '## Manual Installation\n\n'; + readme += 'If automatic installation fails:\n\n'; + readme += '1. Copy `generated-claude.json` content to `~/.claude.json`\n'; + readme += '2. Set environment variables from `generated-env.json`\n'; + readme += '3. Restart Claude Code\n'; + + return readme; +} + +main().catch(console.error);