#Requires -Version 5.1
<#
.SYNOPSIS
Wrapper script to run MCP Memory HTTP Server in background with logging and restart logic.
.DESCRIPTION
This script is designed to be executed by Windows Task Scheduler.
It runs the HTTP server with proper environment setup, logging, and automatic restart on failure.
.NOTES
File Name : run_http_server_background.ps1
Prerequisite : Python, uv package manager
Location : scripts/service/windows/
#>
# Configuration
$ErrorActionPreference = "Stop"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectRoot = (Get-Item "$ScriptDir\..\..\..").FullName
$LogDir = Join-Path $env:LOCALAPPDATA "mcp-memory\logs"
$LogFile = Join-Path $LogDir "http-server.log"
$PidFile = Join-Path $env:LOCALAPPDATA "mcp-memory\http-server.pid"
$MaxRestarts = 3
$RestartDelaySeconds = 60
# Ensure log directory exists
if (-not (Test-Path $LogDir)) {
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
}
# Logging function
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogMessage = "[$Timestamp] [$Level] $Message"
Add-Content -Path $LogFile -Value $LogMessage
# Keep log file under 10MB
if ((Get-Item $LogFile -ErrorAction SilentlyContinue).Length -gt 10MB) {
$OldLog = "$LogFile.old"
if (Test-Path $OldLog) { Remove-Item $OldLog -Force }
Rename-Item $LogFile $OldLog
}
}
# Load .env file
function Load-EnvFile {
$EnvFile = Join-Path $ProjectRoot ".env"
if (Test-Path $EnvFile) {
Write-Log "Loading environment from $EnvFile"
Get-Content $EnvFile | ForEach-Object {
if ($_ -match '^\s*([^#][^=]+)=(.*)$') {
$Name = $matches[1].Trim()
$Value = $matches[2].Trim().Trim('"').Trim("'")
[Environment]::SetEnvironmentVariable($Name, $Value, "Process")
}
}
} else {
Write-Log "No .env file found at $EnvFile" "WARN"
}
}
# Check if server is already running
function Test-ServerRunning {
if (Test-Path $PidFile) {
$StoredPid = Get-Content $PidFile -ErrorAction SilentlyContinue
if ($StoredPid) {
$Process = Get-Process -Id $StoredPid -ErrorAction SilentlyContinue
if ($Process -and $Process.ProcessName -like "*python*") {
return $true
}
}
}
# Also check via HTTP health endpoint
try {
$Response = Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/health" -TimeoutSec 2 -UseBasicParsing -ErrorAction SilentlyContinue
if ($Response.StatusCode -eq 200) {
return $true
}
} catch {
# Server not responding
}
return $false
}
# Main execution
Write-Log "========== MCP Memory HTTP Server Starting =========="
Write-Log "Project Root: $ProjectRoot"
Write-Log "Log File: $LogFile"
# Check if already running
if (Test-ServerRunning) {
Write-Log "Server is already running. Exiting." "WARN"
exit 0
}
# Change to project directory
Set-Location $ProjectRoot
Write-Log "Working directory: $(Get-Location)"
# Load environment variables
Load-EnvFile
# Restart loop
$RestartCount = 0
while ($RestartCount -lt $MaxRestarts) {
Write-Log "Starting HTTP server (attempt $($RestartCount + 1)/$MaxRestarts)..."
try {
# Start the server process
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "uv"
$ProcessInfo.Arguments = "run python scripts/server/run_http_server.py"
$ProcessInfo.WorkingDirectory = $ProjectRoot
$ProcessInfo.UseShellExecute = $false
$ProcessInfo.RedirectStandardOutput = $true
$ProcessInfo.RedirectStandardError = $true
$ProcessInfo.CreateNoWindow = $true
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
# Event handlers for output
$OutputHandler = {
if (-not [String]::IsNullOrEmpty($EventArgs.Data)) {
Add-Content -Path $using:LogFile -Value "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [SERVER] $($EventArgs.Data)"
}
}
$Process.add_OutputDataReceived($OutputHandler)
$Process.add_ErrorDataReceived($OutputHandler)
$Process.Start() | Out-Null
$Process.BeginOutputReadLine()
$Process.BeginErrorReadLine()
# Save PID
Set-Content -Path $PidFile -Value $Process.Id
Write-Log "Server started with PID $($Process.Id)"
# Wait for process to exit
$Process.WaitForExit()
$ExitCode = $Process.ExitCode
Write-Log "Server exited with code $ExitCode" $(if ($ExitCode -eq 0) { "INFO" } else { "ERROR" })
# Clean up PID file
if (Test-Path $PidFile) {
Remove-Item $PidFile -Force
}
# If clean exit (0), don't restart
if ($ExitCode -eq 0) {
Write-Log "Server stopped gracefully. Not restarting."
break
}
} catch {
Write-Log "Error starting server: $_" "ERROR"
}
$RestartCount++
if ($RestartCount -lt $MaxRestarts) {
Write-Log "Waiting $RestartDelaySeconds seconds before restart..."
Start-Sleep -Seconds $RestartDelaySeconds
}
}
if ($RestartCount -ge $MaxRestarts) {
Write-Log "Max restart attempts ($MaxRestarts) reached. Giving up." "ERROR"
}
Write-Log "========== MCP Memory HTTP Server Stopped =========="