feat: 纳入拓展工具 + guide.html badges 对齐
- 拓展/: MCP配置向导、PowerShell工具、mcp-auto-loader 纳入版本管理 - guide.html: badges 从模糊 "90+" 改为精确 "92 Skills | 18 Agents | 34 Hooks"
This commit is contained in:
parent
bec863c5a9
commit
83c1e613a1
@ -199,10 +199,10 @@
|
||||
<h1>Bookworm <span>Portable</span> 保姆式安装手册</h1>
|
||||
<p>从零开始,一步步教你在任意 Windows 电脑上激活 Bookworm</p>
|
||||
<div class="badge-row">
|
||||
<span class="badge"><strong>90+</strong> 专家技能</span>
|
||||
<span class="badge"><strong>多模态</strong> AI 协作</span>
|
||||
<span class="badge"><strong>92</strong> Skills</span>
|
||||
<span class="badge"><strong>18</strong> Agents</span>
|
||||
<span class="badge"><strong>34</strong> Hooks</span>
|
||||
<span class="badge"><strong>AES-256</strong> 加密</span>
|
||||
<span class="badge"><strong>HTTPS</strong> 传输</span>
|
||||
<span class="badge"><strong>NDA</strong> 技术保密</span>
|
||||
</div>
|
||||
<a href="/Bookworm-Setup.bat" download style="display:inline-block;margin-top:1.2rem;padding:0.7rem 2rem;background:var(--accent);color:#000;font-weight:700;border-radius:8px;font-size:1rem;text-decoration:none;transition:opacity 0.2s" onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">⬇ 下载一键安装器</a>
|
||||
|
||||
59
拓展/create-admin-powershell.bat
Normal file
59
拓展/create-admin-powershell.bat
Normal file
@ -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
|
||||
162
拓展/install-pwsh7.bat
Normal file
162
拓展/install-pwsh7.bat
Normal file
@ -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
|
||||
29
拓展/mcp-auto-loader.js
Normal file
29
拓展/mcp-auto-loader.js
Normal file
@ -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);
|
||||
265
拓展/mcp-config-wizard/README.md
Normal file
265
拓展/mcp-config-wizard/README.md
Normal file
@ -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
|
||||
64
拓展/mcp-config-wizard/START.bat
Normal file
64
拓展/mcp-config-wizard/START.bat
Normal file
@ -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
|
||||
60
拓展/mcp-config-wizard/START.sh
Normal file
60
拓展/mcp-config-wizard/START.sh
Normal file
@ -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..."
|
||||
119
拓展/mcp-config-wizard/apply.js
Normal file
119
拓展/mcp-config-wizard/apply.js
Normal file
@ -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);
|
||||
142
拓展/mcp-config-wizard/detect.js
Normal file
142
拓展/mcp-config-wizard/detect.js
Normal file
@ -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');
|
||||
19
拓展/mcp-config-wizard/package.json
Normal file
19
拓展/mcp-config-wizard/package.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
496
拓展/mcp-config-wizard/wizard.js
Normal file
496
拓展/mcp-config-wizard/wizard.js
Normal file
@ -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);
|
||||
Loading…
Reference in New Issue
Block a user