Yeah, Iām no MCP expert but I was having a similar issue with my dev servers. When cursors llmās try to run dev servers to see the errors (or ignore them LOL) sometimes the processes donāt kill correctly. I had cursor write a kill script that has a check to NOT KILL CURSOR. Maybe you could try that with mcp servicesā¦
⦠@echo off
echo Killing development processesā¦
echo.
:: First kill all Node.js processes
echo Killing all Node.js processesā¦
taskkill /F /IM node.exe 2>nul
timeout /t 2 /nobreak > nul
:: Now kill specific port processes
echo Killing processes on specific portsā¦
echo.
:: Function to show process info and kill it
for %%p in (3000 4000 8080) do (
echo Checking port %%pā¦
for /f ātokens=5ā %%a in (ānetstat -aon ^| find ā:%%pā ^| find āLISTENINGāā) do (
echo Found process on port %%p [PID: %%a]
echo Process details:
tasklist /FI āPID eq %%aā /FO LIST
echo Killing processā¦
:: Check if the process is Cursor before killing it
tasklist /FI āPID eq %%aā /FO LIST | find /i āCursorā >nul
if errorlevel 1 (
echo Process is not Cursor, safe to killā¦
taskkill /F /PID %%a 2>nul
) else (
echo Process is Cursor IDE, skippingā¦
)
timeout /t 1 /nobreak > nul
)
)
:: Double check if any ports are still in use
echo.
echo Verifying ports are clearā¦
echo.
set āports_in_use=ā
for %%p in (3000 4000 8080) do (
netstat -ano | find ā:%%pā | find āLISTENINGā >nul
if not errorlevel 1 (
echo Port %%p is still in use!
for /f ātokens=2,5ā %%b in (ānetstat -aon ^| find ā:%%pā ^| find āLISTENINGāā) do (
echo Local port: %%b
echo Process ID: %%c
echo Process details:
tasklist /FI āPID eq %%cā /FO LIST
)
set āports_in_use=1ā
)
)
if defined ports_in_use (
echo.
echo Some ports are still in use. Try these steps:
echo 1. Open Task Manager ^(Ctrl+Shift+Esc^)
echo 2. Go to Details tab
echo 3. Look for node.exe processes EXCEPT Cursor
echo 4. End those tasks
echo.
echo If that doesnāt work, you may need to restart your computer.
) else (
echo All ports are now free.
)
I ran into the lingering-MCP issue too. My server just kept running after I closed Cursor. The fix turned out to be simple: watch the stdin file descriptor for a POLLHUP. When Cursor exits it drops the pipe, the HUP fires, and the server can shut itself down right away. I added a tiny fallback that checks if the parent PID turns to 1, but thatās only a safety net ā the stdin HUP does all the heavy lifting. Since adding this, every time I quit Cursor the process disappears instantly. Full patch is in the gist if anyone wants to see it (see zombie-killer section): mcp.json Ā· GitHub