fix: PR#151 - Enhance cross-platform support

- Improved error handling and path resolution in run-server.ps1 for better reliability.
- Implemented conversation tests for Docker mode compatibility in validation_crossplatform.py.
- Updated run-server.ps1 to include detailed help documentation, configuration management, and backup retention for configuration files.
- Added Docker path validation tests in validation_crossplatform.py to ensure correct path handling in Docker mode.
- Enhanced integration test script run_integration_tests.ps1 with comprehensive documentation and parameter support for output customization.
This commit is contained in:
OhMyApps
2025-07-05 14:57:27 +02:00
parent ad6b216265
commit 9b5d03747e
5 changed files with 1212 additions and 61 deletions

View File

@@ -1,4 +1,63 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Installation, configuration, and launch script for Zen MCP server on Windows.
.DESCRIPTION
This PowerShell script prepares the environment for the Zen MCP server:
- Installs and checks Python 3.10+ (with venv or uv if available)
- Installs required Python dependencies
- Configures environment files (.env)
- Validates presence of required API keys
- Cleans Python caches and obsolete Docker artifacts
- Offers automatic integration with Claude Desktop, Gemini CLI, VSCode, Cursor, Windsurf, and Trae
- Manages configuration file backups (max 3 retained)
- Allows real-time log following or server launch
.PARAMETER Help
Shows script help.
.PARAMETER Version
Shows Zen MCP server version.
.PARAMETER Follow
Follows server logs in real time.
.PARAMETER Config
Shows configuration instructions for Claude and other compatible clients.
.PARAMETER ClearCache
Removes Python cache files (__pycache__, .pyc).
.PARAMETER SkipVenv
Skips Python virtual environment creation.
.PARAMETER SkipDocker
Skips Docker checks and cleanup.
.PARAMETER Force
Forces recreation of the Python virtual environment.
.PARAMETER VerboseOutput
Enables more detailed output (currently unused).
.EXAMPLE
.\run-server.ps1
Prepares the environment and starts the Zen MCP server.
.\run-server.ps1 -Follow
Follows server logs in real time.
.\run-server.ps1 -Config
Shows configuration instructions for clients.
.NOTES
Project Author : BeehiveInnovations
Script Author : GiGiDKR (https://github.com/GiGiDKR)
Date : 07-05-2025
Version : See config.py (__version__)
References : https://github.com/BeehiveInnovations/zen-mcp-server
#>
#Requires -Version 5.1
[CmdletBinding()]
param(
@@ -126,6 +185,55 @@ function Remove-LockedDirectory {
}
}
# Manage configuration file backups with maximum 3 files retention
function Manage-ConfigBackups {
param(
[string]$ConfigFilePath,
[int]$MaxBackups = 3
)
if (!(Test-Path $ConfigFilePath)) {
Write-Warning "Configuration file not found: $ConfigFilePath"
return $null
}
try {
# Create new backup with timestamp
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$backupPath = "$ConfigFilePath.backup_$timestamp"
Copy-Item $ConfigFilePath $backupPath -ErrorAction Stop
# Find all existing backups for this config file
$configDir = Split-Path $ConfigFilePath -Parent
$configFileName = Split-Path $ConfigFilePath -Leaf
$backupPattern = "$configFileName.backup_*"
$existingBackups = Get-ChildItem -Path $configDir -Filter $backupPattern -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending
# Keep only the most recent MaxBackups files
if ($existingBackups.Count -gt $MaxBackups) {
$backupsToRemove = $existingBackups | Select-Object -Skip $MaxBackups
foreach ($backup in $backupsToRemove) {
try {
Remove-Item $backup.FullName -Force -ErrorAction Stop
Write-Info "Removed old backup: $($backup.Name)"
} catch {
Write-Warning "Could not remove old backup: $($backup.Name)"
}
}
Write-Success "Backup retention: kept $MaxBackups most recent backups"
}
Write-Success "Backup created: $(Split-Path $backupPath -Leaf)"
return $backupPath
} catch {
Write-Warning "Failed to create backup: $_"
return $null
}
}
# Get version from config.py
function Get-Version {
try {
@@ -160,6 +268,19 @@ function Clear-PythonCache {
}
}
# Get absolute path
function Get-AbsolutePath {
param([string]$Path)
if (Test-Path $Path) {
# Use Resolve-Path for full resolution
return Resolve-Path $Path
} else {
# Use unresolved method
return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
}
}
# Check Python version
function Test-PythonVersion {
param([string]$PythonCmd)
@@ -356,7 +477,7 @@ function Initialize-Environment {
Write-Success "Virtual environment already exists"
$pythonPath = "$VENV_PATH\Scripts\python.exe"
if (Test-Path $pythonPath) {
return $pythonPath
return Get-AbsolutePath $pythonPath
}
}
}
@@ -365,15 +486,8 @@ function Initialize-Environment {
Write-Info "Creating virtual environment with uv..."
uv venv $VENV_PATH --python 3.12
if ($LASTEXITCODE -eq 0) {
# Install pip in the uv environment for compatibility
Write-Info "Installing pip in uv environment..."
uv pip install --python "$VENV_PATH\Scripts\python.exe" pip
if ($LASTEXITCODE -eq 0) {
Write-Success "Environment created with uv (pip installed)"
} else {
Write-Success "Environment created with uv"
}
return "$VENV_PATH\Scripts\python.exe"
Write-Success "Environment created with uv"
return Get-AbsolutePath "$VENV_PATH\Scripts\python.exe"
}
} catch {
Write-Warning "uv failed, falling back to venv"
@@ -415,7 +529,7 @@ function Initialize-Environment {
}
} else {
Write-Success "Virtual environment already exists"
return "$VENV_PATH\Scripts\python.exe"
return Get-AbsolutePath "$VENV_PATH\Scripts\python.exe"
}
}
@@ -431,7 +545,7 @@ function Initialize-Environment {
}
Write-Success "Virtual environment created"
return "$VENV_PATH\Scripts\python.exe"
return Get-AbsolutePath "$VENV_PATH\Scripts\python.exe"
}
# Setup virtual environment (legacy function for compatibility)
@@ -553,18 +667,8 @@ function Install-Dependencies {
if (Test-Uv) {
Write-Info "Installing dependencies with uv..."
try {
# Install in the virtual environment
uv pip install --python "$VENV_PATH\Scripts\python.exe" -r requirements.txt
uv pip install -r requirements.txt
if ($LASTEXITCODE -eq 0) {
# Also install dev dependencies if available
if (Test-Path "requirements-dev.txt") {
uv pip install --python "$VENV_PATH\Scripts\python.exe" -r requirements-dev.txt
if ($LASTEXITCODE -eq 0) {
Write-Success "Development dependencies installed with uv"
} else {
Write-Warning "Failed to install dev dependencies with uv, continuing..."
}
}
Write-Success "Dependencies installed with uv"
return
}
@@ -678,8 +782,8 @@ function Test-ClaudeDesktopIntegration {
}
Write-Host ""
$response = Read-Host "Configure Zen for Claude Desktop? (Y/n)"
if ($response -eq 'n' -or $response -eq 'N') {
$response = Read-Host "Configure Zen for Claude Desktop? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping Claude Desktop integration"
New-Item -Path $DESKTOP_CONFIG_FLAG -ItemType File -Force | Out-Null
return
@@ -698,9 +802,8 @@ function Test-ClaudeDesktopIntegration {
if (Test-Path $claudeConfigPath) {
Write-Info "Updating existing Claude Desktop config..."
# Create backup
$backupPath = "$claudeConfigPath.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item $claudeConfigPath $backupPath
# Create backup with retention management
$backupPath = Manage-ConfigBackups $claudeConfigPath
# Read existing config
$existingContent = Get-Content $claudeConfigPath -Raw
@@ -804,8 +907,8 @@ function Test-GeminiCliIntegration {
# Ask user if they want to add Zen to Gemini CLI
Write-Host ""
$response = Read-Host "Configure Zen for Gemini CLI? (Y/n)"
if ($response -eq 'n' -or $response -eq 'N') {
$response = Read-Host "Configure Zen for Gemini CLI? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping Gemini CLI integration"
return
}
@@ -821,7 +924,7 @@ if exist ".zen_venv\Scripts\python.exe" (
) else (
python server.py %*
)
"@ | Out-File -FilePath $zenWrapper -Encoding UTF8
"@ | Out-File -FilePath $zenWrapper -Encoding ASCII
Write-Success "Created zen-mcp-server.cmd wrapper script"
}
@@ -830,9 +933,8 @@ if exist ".zen_venv\Scripts\python.exe" (
Write-Info "Updating Gemini CLI configuration..."
try {
# Create backup
$backupPath = "$geminiConfig.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item $geminiConfig $backupPath -ErrorAction SilentlyContinue
# Create backup with retention management
$backupPath = Manage-ConfigBackups $geminiConfig
# Read existing config or create new one
$config = @{}
@@ -876,6 +978,464 @@ if exist ".zen_venv\Scripts\python.exe" (
}
}
# Check and update Cursor configuration
function Test-CursorIntegration {
param([string]$PythonPath, [string]$ServerPath)
Write-Step "Checking Cursor Integration"
# Check if Cursor is installed
if (!(Test-Command "cursor")) {
Write-Info "Cursor not detected - skipping Cursor integration"
return
}
Write-Info "Found Cursor"
$cursorConfigPath = "$env:USERPROFILE\.cursor\mcp.json"
# Check if MCP is already configured
if (Test-Path $cursorConfigPath) {
try {
$settings = Get-Content $cursorConfigPath -Raw | ConvertFrom-Json
if ($settings.mcpServers -and $settings.mcpServers.zen) {
Write-Success "Zen MCP already configured in Cursor"
return
}
} catch {
Write-Warning "Could not read existing Cursor configuration"
}
}
# Ask user if they want to configure Cursor
Write-Host ""
$response = Read-Host "Configure Zen MCP for Cursor? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping Cursor integration"
return
}
try {
# Create config directory if it doesn't exist
$configDir = Split-Path $cursorConfigPath -Parent
if (!(Test-Path $configDir)) {
New-Item -ItemType Directory -Path $configDir -Force | Out-Null
}
# Create backup with retention management
if (Test-Path $cursorConfigPath) {
$backupPath = Manage-ConfigBackups $cursorConfigPath
}
# Read existing config or create new one
$config = @{}
if (Test-Path $cursorConfigPath) {
$config = Get-Content $cursorConfigPath -Raw | ConvertFrom-Json
}
# Ensure mcpServers exists
if (!$config.mcpServers) {
$config | Add-Member -MemberType NoteProperty -Name "mcpServers" -Value @{} -Force
}
# Add zen server configuration
$serverConfig = @{
command = $PythonPath
args = @($ServerPath)
}
$config.mcpServers | Add-Member -MemberType NoteProperty -Name "zen" -Value $serverConfig -Force
# Write updated config
$config | ConvertTo-Json -Depth 10 | Out-File $cursorConfigPath -Encoding UTF8
Write-Success "Successfully configured Cursor"
Write-Host " Config: $cursorConfigPath" -ForegroundColor Gray
Write-Host " Restart Cursor to use Zen MCP Server" -ForegroundColor Gray
} catch {
Write-Error "Failed to update Cursor configuration: $_"
Write-Host ""
Write-Host "Manual configuration for Cursor:"
Write-Host "Location: $cursorConfigPath"
Write-Host "Add this configuration:"
Write-Host @"
{
"mcpServers": {
"zen": {
"command": "$PythonPath",
"args": ["$ServerPath"]
}
}
}
"@ -ForegroundColor Yellow
}
}
# Check and update Windsurf configuration
function Test-WindsurfIntegration {
param([string]$PythonPath, [string]$ServerPath)
Write-Step "Checking Windsurf Integration"
$windsurfConfigPath = "$env:USERPROFILE\.codeium\windsurf\mcp_config.json"
$windsurfAppDir = "$env:USERPROFILE\.codeium\windsurf"
# Check if Windsurf directory exists (better detection than command)
if (!(Test-Path $windsurfAppDir)) {
Write-Info "Windsurf not detected - skipping Windsurf integration"
return
}
Write-Info "Found Windsurf installation"
# Check if MCP is already configured
if (Test-Path $windsurfConfigPath) {
try {
$settings = Get-Content $windsurfConfigPath -Raw | ConvertFrom-Json
if ($settings.mcpServers -and $settings.mcpServers.zen) {
Write-Success "Zen MCP already configured in Windsurf"
return
}
} catch {
Write-Warning "Could not read existing Windsurf configuration"
}
}
# Ask user if they want to configure Windsurf
Write-Host ""
$response = Read-Host "Configure Zen MCP for Windsurf? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping Windsurf integration"
return
}
try {
# Create config directory if it doesn't exist
$configDir = Split-Path $windsurfConfigPath -Parent
if (!(Test-Path $configDir)) {
New-Item -ItemType Directory -Path $configDir -Force | Out-Null
}
# Create backup with retention management
if (Test-Path $windsurfConfigPath) {
$backupPath = Manage-ConfigBackups $windsurfConfigPath
}
# Read existing config or create new one
$config = @{}
if (Test-Path $windsurfConfigPath) {
$config = Get-Content $windsurfConfigPath -Raw | ConvertFrom-Json
}
# Ensure mcpServers exists
if (!$config.mcpServers) {
$config | Add-Member -MemberType NoteProperty -Name "mcpServers" -Value @{} -Force
}
# Add zen server configuration
$serverConfig = @{
command = $PythonPath
args = @($ServerPath)
}
$config.mcpServers | Add-Member -MemberType NoteProperty -Name "zen" -Value $serverConfig -Force
# Write updated config
$config | ConvertTo-Json -Depth 10 | Out-File $windsurfConfigPath -Encoding UTF8
Write-Success "Successfully configured Windsurf"
Write-Host " Config: $windsurfConfigPath" -ForegroundColor Gray
Write-Host " Restart Windsurf to use Zen MCP Server" -ForegroundColor Gray
} catch {
Write-Error "Failed to update Windsurf configuration: $_"
Write-Host ""
Write-Host "Manual configuration for Windsurf:"
Write-Host "Location: $windsurfConfigPath"
Write-Host "Add this configuration:"
Write-Host @"
{
"mcpServers": {
"zen": {
"command": "$PythonPath",
"args": ["$ServerPath"]
}
}
}
"@ -ForegroundColor Yellow
}
}
# Check and update Trae configuration
function Test-TraeIntegration {
param([string]$PythonPath, [string]$ServerPath)
Write-Step "Checking Trae Integration"
$traeConfigPath = "$env:APPDATA\Trae\User\mcp.json"
$traeAppDir = "$env:APPDATA\Trae"
# Check if Trae directory exists (better detection than command)
if (!(Test-Path $traeAppDir)) {
Write-Info "Trae not detected - skipping Trae integration"
return
}
Write-Info "Found Trae installation"
# Check if MCP is already configured
if (Test-Path $traeConfigPath) {
try {
$settings = Get-Content $traeConfigPath -Raw | ConvertFrom-Json
if ($settings.mcpServers -and $settings.mcpServers.zen) {
Write-Success "Zen MCP already configured in Trae"
return
}
} catch {
Write-Warning "Could not read existing Trae configuration"
}
}
# Ask user if they want to configure Trae
Write-Host ""
$response = Read-Host "Configure Zen MCP for Trae? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping Trae integration"
return
}
try {
# Create config directory if it doesn't exist
$configDir = Split-Path $traeConfigPath -Parent
if (!(Test-Path $configDir)) {
New-Item -ItemType Directory -Path $configDir -Force | Out-Null
}
# Create backup with retention management
if (Test-Path $traeConfigPath) {
$backupPath = Manage-ConfigBackups $traeConfigPath
}
# Read existing config or create new one
$config = @{}
if (Test-Path $traeConfigPath) {
$config = Get-Content $traeConfigPath -Raw | ConvertFrom-Json
}
# Ensure mcpServers exists
if (!$config.mcpServers) {
$config | Add-Member -MemberType NoteProperty -Name "mcpServers" -Value @{} -Force
}
# Add zen server configuration
$serverConfig = @{
command = $PythonPath
args = @($ServerPath)
}
$config.mcpServers | Add-Member -MemberType NoteProperty -Name "zen" -Value $serverConfig -Force
# Write updated config
$config | ConvertTo-Json -Depth 10 | Out-File $traeConfigPath -Encoding UTF8
Write-Success "Successfully configured Trae"
Write-Host " Config: $traeConfigPath" -ForegroundColor Gray
Write-Host " Restart Trae to use Zen MCP Server" -ForegroundColor Gray
} catch {
Write-Error "Failed to update Trae configuration: $_"
Write-Host ""
Write-Host "Manual configuration for Trae:"
Write-Host "Location: $traeConfigPath"
Write-Host "Add this configuration:"
Write-Host @"
{
"mcpServers": {
"zen": {
"command": "$PythonPath",
"args": ["$ServerPath"]
}
}
}
"@ -ForegroundColor Yellow
}
}
# Check and update VSCode configuration
function Test-VSCodeIntegration {
param([string]$PythonPath, [string]$ServerPath)
Write-Step "Checking VSCode Integration"
# Check for VSCode installations
$vscodeVersions = @()
# VSCode standard
if (Test-Command "code") {
$vscodeVersions += @{
Name = "VSCode"
Command = "code"
UserPath = "$env:APPDATA\Code\User"
}
}
# VSCode Insiders
if (Test-Command "code-insiders") {
$vscodeVersions += @{
Name = "VSCode Insiders"
Command = "code-insiders"
UserPath = "$env:APPDATA\Code - Insiders\User"
}
}
if ($vscodeVersions.Count -eq 0) {
Write-Info "VSCode not detected - skipping VSCode integration"
return
}
foreach ($vscode in $vscodeVersions) {
Write-Info "Found $($vscode.Name)"
# Find settings.json files with modification dates
$settingsFiles = @()
$userPath = $vscode.UserPath
# Check default profile
$defaultSettings = Join-Path $userPath "settings.json"
if (Test-Path $defaultSettings) {
$lastWrite = (Get-Item $defaultSettings).LastWriteTime
$settingsFiles += @{
Path = $defaultSettings
ProfileName = "Default Profile"
LastModified = $lastWrite
}
}
# Check profiles directory
$profilesPath = Join-Path $userPath "profiles"
if (Test-Path $profilesPath) {
$profiles = Get-ChildItem $profilesPath -Directory
foreach ($profile in $profiles) {
$profileSettings = Join-Path $profile.FullName "settings.json"
if (Test-Path $profileSettings) {
$lastWrite = (Get-Item $profileSettings).LastWriteTime
$settingsFiles += @{
Path = $profileSettings
ProfileName = "Profile: $($profile.Name)"
LastModified = $lastWrite
}
}
}
}
if ($settingsFiles.Count -eq 0) {
Write-Warning "No settings.json found for $($vscode.Name)"
continue
}
# Sort by last modified date (most recent first) and take only the most recent
$mostRecentProfile = $settingsFiles | Sort-Object LastModified -Descending | Select-Object -First 1
# Process only the most recent settings file
$settingsFile = $mostRecentProfile
$settingsPath = $settingsFile.Path
$profileName = $settingsFile.ProfileName
# Check if MCP is already configured
if (Test-Path $settingsPath) {
try {
$settings = Get-Content $settingsPath -Raw | ConvertFrom-Json
if ($settings.mcp -and $settings.mcp.servers -and $settings.mcp.servers.zen) {
Write-Success "Zen MCP already configured in $($vscode.Name)"
continue
}
} catch {
Write-Warning "Could not read existing settings for $($vscode.Name)"
}
}
# Ask user if they want to configure this VSCode instance
Write-Host ""
$response = Read-Host "Configure Zen MCP for $($vscode.Name)? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
Write-Info "Skipping $($vscode.Name)"
continue
}
try {
# Create backup with retention management
if (Test-Path $settingsPath) {
$backupPath = Manage-ConfigBackups $settingsPath
}
# Read existing settings as JSON string
$jsonContent = "{}"
if (Test-Path $settingsPath) {
$jsonContent = Get-Content $settingsPath -Raw
if (!$jsonContent.Trim()) {
$jsonContent = "{}"
}
} else {
# Create directory if it doesn't exist
$settingsDir = Split-Path $settingsPath -Parent
if (!(Test-Path $settingsDir)) {
New-Item -ItemType Directory -Path $settingsDir -Force | Out-Null
}
}
# Parse JSON
$settings = $jsonContent | ConvertFrom-Json
# Build zen configuration
$zenConfigObject = New-Object PSObject
$zenConfigObject | Add-Member -MemberType NoteProperty -Name "command" -Value $PythonPath
$zenConfigObject | Add-Member -MemberType NoteProperty -Name "args" -Value @($ServerPath)
# Build servers object
$serversObject = New-Object PSObject
$serversObject | Add-Member -MemberType NoteProperty -Name "zen" -Value $zenConfigObject
# Build mcp object
$mcpObject = New-Object PSObject
$mcpObject | Add-Member -MemberType NoteProperty -Name "servers" -Value $serversObject
# Add mcp to settings (replace if exists)
if ($settings.PSObject.Properties.Name -contains "mcp") {
$settings.mcp = $mcpObject
} else {
$settings | Add-Member -MemberType NoteProperty -Name "mcp" -Value $mcpObject
}
# Write updated settings
$settings | ConvertTo-Json -Depth 10 | Out-File $settingsPath -Encoding UTF8
Write-Success "Successfully configured $($vscode.Name)"
Write-Host " Config: $settingsPath" -ForegroundColor Gray
Write-Host " Restart $($vscode.Name) to use Zen MCP Server" -ForegroundColor Gray
} catch {
Write-Error "Failed to update $($vscode.Name) settings: $_"
Write-Host ""
Write-Host "Manual configuration for $($vscode.Name):"
Write-Host "Location: $settingsPath"
Write-Host "Add this to your settings.json:"
Write-Host @"
{
"mcp": {
"servers": {
"zen": {
"command": "$PythonPath",
"args": ["$ServerPath"]
}
}
}
}
"@ -ForegroundColor Yellow
}
}
}
# Display configuration instructions
function Show-ConfigInstructions {
param([string]$PythonPath, [string]$ServerPath)
@@ -924,7 +1484,77 @@ function Show-ConfigInstructions {
Write-Host $geminiConfigJson -ForegroundColor Yellow
Write-Host ""
Write-Info "3. Restart Claude Desktop or Gemini CLI after updating the config files"
Write-Info "3. For VSCode:"
Write-Host " Add this configuration to your VSCode settings.json:"
Write-Host " Location: $env:APPDATA\Code\User\<profile-id>\settings.json"
Write-Host ""
$vscodeConfigJson = @{
mcp = @{
servers = @{
zen = @{
command = $PythonPath
args = @($ServerPath)
}
}
}
} | ConvertTo-Json -Depth 5
Write-Host $vscodeConfigJson -ForegroundColor Yellow
Write-Host ""
Write-Info "4. For Cursor:"
Write-Host " Add this configuration to your Cursor config file:"
Write-Host " Location: $env:USERPROFILE\.cursor\mcp.json"
Write-Host ""
$cursorConfigJson = @{
mcpServers = @{
zen = @{
command = $PythonPath
args = @($ServerPath)
}
}
} | ConvertTo-Json -Depth 5
Write-Host $cursorConfigJson -ForegroundColor Yellow
Write-Host ""
Write-Info "5. For Trae:"
Write-Host " Add this configuration to your Trae config file:"
Write-Host " Location: $env:APPDATA\Trae\Users\mcp.json"
Write-Host ""
$traeConfigJson = @{
mcpServers = @{
zen = @{
command = $PythonPath
args = @($ServerPath)
}
}
} | ConvertTo-Json -Depth 5
Write-Host $traeConfigJson -ForegroundColor Yellow
Write-Host ""
Write-Info "6. For Windsurf:"
Write-Host " Add this configuration to your Windsurf config file:"
Write-Host " Location: $env:USERPROFILE\.codeium\windsurf\mcp_config.json"
Write-Host ""
$windsurfConfigJson = @{
mcpServers = @{
zen = @{
command = $PythonPath
args = @($ServerPath)
}
}
} | ConvertTo-Json -Depth 5
Write-Host $windsurfConfigJson -ForegroundColor Yellow
Write-Host ""
Write-Info "7. Restart Claude Desktop, Gemini CLI, VSCode, Cursor, Windsurf, or Trae after updating the config files"
Write-Host ""
Write-Info "Note: Claude Code (CLI) is not available on Windows (except in WSL2)"
Write-Host ""
@@ -1119,7 +1749,7 @@ function Start-MainProcess {
Write-Host ""
try {
$pythonPath = Initialize-Environment
$serverPath = Resolve-Path "server.py"
$serverPath = Get-AbsolutePath "server.py"
Show-ConfigInstructions $pythonPath $serverPath
} catch {
Write-Error "Failed to setup environment: $_"
@@ -1174,7 +1804,7 @@ function Start-MainProcess {
}
# Step 7: Get absolute server path
$serverPath = Resolve-Path "server.py"
$serverPath = Get-AbsolutePath "server.py"
# Step 8: Display setup instructions
Show-SetupInstructions $pythonPath $serverPath
@@ -1183,18 +1813,30 @@ function Start-MainProcess {
Test-ClaudeCliIntegration $pythonPath $serverPath
Test-ClaudeDesktopIntegration $pythonPath $serverPath
# Step 10: Check Gemini CLI integration
# Step 10: Check VSCode integration
Test-VSCodeIntegration $pythonPath $serverPath
# Step 11: Check Cursor integration
Test-CursorIntegration $pythonPath $serverPath
# Step 12: Check Windsurf integration
Test-WindsurfIntegration $pythonPath $serverPath
# Step 13: Check Trae integration
Test-TraeIntegration $pythonPath $serverPath
# Step 14: Check Gemini CLI integration
Test-GeminiCliIntegration (Split-Path $serverPath -Parent)
# Step 11: Setup logging directory
# Step 15: Setup logging directory
Initialize-Logging
# Step 12: Display log information
# Step 16: Display log information
Write-Host ""
Write-Host "Logs will be written to: $(Resolve-Path $LOG_DIR)\$LOG_FILE"
Write-Host "Logs will be written to: $(Get-AbsolutePath $LOG_DIR)\$LOG_FILE"
Write-Host ""
# Step 12: Handle command line arguments
# Step 17: Handle command line arguments
if ($Follow) {
Follow-Logs
} else {