Exiting the cursor will not kill the mcp process

Version: 0.48.7
VSCode Version: 1.96.2
Commit: 66290080aae40d23364ba2371832bda0933a3640
Date: 2025-04-01T23:52:09.566Z
Electron: 34.3.4
Chromium: 132.0.6834.210
Node.js: 20.18.3
V8: 13.2.152.41-electron.0
OS: Linux x64 6.13.9-gentoo-dist

I started a mcp:


However, when I close the cursor, this mcp process is still there!

If I open the cursor again, another identical mcp process will be added:

This is really amazing, can this kind of bug also exist? :smiley:

{
  "mcpServers": {
    "arxiv-mcp-server": {
      "command": "uv",
      "args": [
        "tool",
        "run",
        "arxiv-mcp-server"
      ]
    },
    "web-browser-mcp-server": {
      "command": "uv",
      "args": [
        "tool",
        "run",
        "web-browser-mcp-server"
      ],
      "env": {
        "REQUEST_TIMEOUT": "30"
      }
    }
  }
}
1 Like

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.
)

echo.
pause

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