Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save futuremotiondev/a08e9ad8b0875ad852b6380531235764 to your computer and use it in GitHub Desktop.

Select an option

Save futuremotiondev/a08e9ad8b0875ad852b6380531235764 to your computer and use it in GitHub Desktop.
using namespace System.IO
using namespace System.Collections.Generic
Clear-Host
function Stop-MCPServerProcesses {
<#
.SYNOPSIS
Terminates processes that are part of running MCP server stacks.
.DESCRIPTION
Queries running instances of python.exe, uv.exe, uvx.exe, cmd.exe,
node.exe, bun.exe, and chroma-mcp.exe, then terminates only those whose
command line contains "chroma-mcp" or "claude-mem". This prevents killing
unrelated instances of these common host processes.
.EXAMPLE
Stop-MCPServerProcesses
Finds and kills all matching MCP-related processes.
.EXAMPLE
Stop-MCPServerProcesses -Verbose
Same as above with detailed tracing of each discovered and killed process.
.NOTES
Author: Futuremotion
Date: 2026-04-15
#>
[CmdletBinding(SupportsShouldProcess)]
[OutputType([PSCustomObject])]
param ()
# ── Target process names ─────────────────────────────────────
[string[]] $targetNames = @(
'python'
'uv'
'uvx'
'cmd'
'node'
'bun'
'chroma-mcp'
)
[string[]] $matchStrings = @('chroma-mcp', 'claude-mem')
# ── Query WMI for matching processes ─────────────────────────
# Build a WQL filter for all target process names at once
[string] $nameFilter = ($targetNames | ForEach-Object {
"Name = '$_.exe'"
}) -join ' OR '
[string] $wqlQuery = "SELECT ProcessId, Name, CommandLine " +
"FROM Win32_Process WHERE ($nameFilter)"
Write-Verbose "WQL query: $wqlQuery"
$candidates = Get-CimInstance -Query $wqlQuery -ErrorAction Stop
if (-not $candidates -or $candidates.Count -eq 0) {
Write-Host "No target processes found running." `
-ForegroundColor DarkYellow
return [PSCustomObject]@{
Operation = 'Stop-MCPServerProcesses'
Killed = 0
Skipped = 0
Details = @()
ErrorMessage = $null
}
}
Write-Verbose "Found $($candidates.Count) candidate process(es)"
# ── Filter by command line and terminate ─────────────────────
[List[PSCustomObject]] $details = [List[PSCustomObject]]::new()
[int] $killed = 0
[int] $skipped = 0
foreach ($proc in $candidates) {
[string] $cmdLine = $proc.CommandLine
[int] $procId = $proc.ProcessId
[string] $name = $proc.Name
# Skip processes with no command line (zombie/system)
if ([string]::IsNullOrWhiteSpace($cmdLine)) {
Write-Verbose "PID $procId ($name): no command line, skipping"
$skipped++
continue
}
# chroma-mcp.exe always matches by definition; others must contain a match string
[bool] $isMatch = $name -eq 'chroma-mcp.exe'
[string] $hitString = $null
if (-not $isMatch) {
foreach ($ms in $matchStrings) {
if ($cmdLine.IndexOf($ms, [System.StringComparison]::OrdinalIgnoreCase) -ge 0) {
$isMatch = $true
$hitString = $ms
break
}
}
}
if (-not $isMatch) {
Write-Verbose "PID $procId ($name): no match strings in command line, skipping"
$skipped++
continue
}
# Truncate command line for display
[string] $displayCmd = if ($cmdLine.Length -gt 120) {
$cmdLine.Substring(0, 117) + '...'
} else { $cmdLine }
if ($PSCmdlet.ShouldProcess(
"PID $procId ($name)", "Terminate")) {
try {
Stop-Process -Id $procId -Force -ErrorAction Stop
Write-Host " Killed PID $procId ($name)" `
-ForegroundColor Green
Write-Verbose " CommandLine: $displayCmd"
$killed++
$details.Add([PSCustomObject]@{
PID = $procId
Name = $name
CommandLine = $cmdLine
Action = 'Killed'
ErrorMessage = $null
})
}
catch {
Write-Warning "Failed to kill PID ${procId}: $_"
$details.Add([PSCustomObject]@{
PID = $procId
Name = $name
CommandLine = $cmdLine
Action = 'Failed'
ErrorMessage = $_.Exception.Message
})
}
}
}
# ── Summary ──────────────────────────────────────────────────
Write-Host ""
if ($killed -gt 0) {
Write-Host "Terminated $killed MCP process(es)." `
-ForegroundColor Cyan
} else {
Write-Host "No matching MCP processes found to terminate." `
-ForegroundColor DarkYellow
}
if ($skipped -gt 0) {
Write-Verbose "Skipped $skipped non-matching process(es)"
}
[PSCustomObject]@{
Operation = 'Stop-MCPServerProcesses'
Killed = $killed
Skipped = $skipped
Details = $details.ToArray()
ErrorMessage = $null
}
}
# Self-execute
Stop-MCPServerProcesses -Verbose
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment