MCP fails to start — utility process never reaches `ipcReady` (Windows)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Summary

On Windows, Cursor’s MCP feature never connects. Cursor forks the MCP host as an
Electron utility process (Cursor.exe --type=utility, entry point
vs/code/electron-utility/mcpProcess/mcpProcessMain). The child process starts
successfully and does not crash, but never completes its IPC handshake back
to the main process. After a 10s timeout Cursor retries 5x with backoff, then
gives up. This affects every MCP server, including the built-in
cursor-ide-browser, and an HTTP-type server (Glean) that spawns no shell.

Environment

  • Cursor version: 3.7.27
  • Commit: e48ee6102a199492b0c9964699bf011886708ba3
  • OS: Windows 10.0.26100 (x64), corporate-managed
  • Install type: per-user (%LOCALAPPDATA%\Programs\cursor)

Symptoms / log evidence

Renderer (MCP service log):

[MCPService] createClient: identifier="user-glean_default", serverName="glean_default"
[MCPService] Error creating client: Failed to acquire MessagePort for response channel 'vscode:createMcpProcessChannelConnectionResult'

Main process (logs/<session>/main.log), repeats every launch:

[McpProcess] ipcReady wait failed; entryPoint=vs/code/electron-utility/mcpProcess/mcpProcessMain
  waitingFor=ipcReady lastPhase=<none> lastMessage=<none> lastPhaseElapsedMs=<none>
  spawnPid=20572 startReturned=true crashEventReceived=false restartCount=0
  coldStartTimeoutMs=10000 elapsedMs=10010
  [McpProcess] timed out waiting for ipcReady after 10000ms
[McpProcess] whenReady rejected, dropping window connection
[McpProcess] initial main connect failed

Then retries at restartCount 1..4 (1s,2s,4s,8s,16s backoff), all identical.

Key fields: startReturned=true (fork succeeded), crashEventReceived=false
(no crash), lastPhase=<none> lastMessage=<none> (zero bytes ever traverse the
IPC pipe). The process is alive but silent for the full 10s, then is killed by
the timeout.

Independent confirmation via Sysmon (OS-level, vendor-neutral)

  • The MCP utility process DID launch as a real OS process: Sysmon ProcessCreate
    (ID 1) at the exact spawnPid and time from main.log
    (e.g. pid 20572, sub=node.mojom.NodeService).
  • That MCP pid made zero network connections (Sysmon ID 3) — so it never
    reaches networking; this is not a proxy/DNS/Zscaler stall on its own traffic.
  • Other Cursor utility processes of the SAME type (node.mojom.NodeService),
    spawned seconds apart by the same parent, initialize fine and network
    normally. Only the MCP-host node process hangs at the ipcReady/MessagePort
    handshake. This suggests the issue is specific to the MCP process-channel /
    MessagePort bootstrap path, not a blanket child-process block.

Already ruled out (extensive)

  • Full machine reboot.
  • Latest version (3.7.27); clean full reinstall (uninstall + fresh install,
    verified new install dir/registry InstallDate) — identical failure.
  • Launched with --no-sandbox.
  • Cleared all caches (Cache, Code Cache, GPUCache, Dawn caches).
  • Reset MCP OAuth state (globalStorage\mcp-oauth-attempts).
  • Removed & re-added the server; toggled off/on.
  • No PowerShell profile and no cmd AutoRun (ruled out stdout-pollution of stdio
    transport). Also irrelevant since failure also hits the built-in server and an
    HTTP server.
  • No block/audit events in WDAC CodeIntegrity, AppLocker, or Windows
    Application error/hang logs for Cursor.

Steps to Reproduce

Try to add any any HTTP-based MCP server on Windows.

Operating System

Windows 10/11

Version Information

  • Cursor version: 3.7.27
  • Commit: e48ee6102a199492b0c9964699bf011886708ba3
  • OS: Windows 10.0.26100 (x64), corporate-managed
  • Install type: per-user (%LOCALAPPDATA%\Programs\cursor)

Does this stop you from using Cursor

Yes - Cursor is unusable

I am on a Windows App virtual PC and this issue is stopping me from connecting to the MIRO MCP server. he issue started when upon advice in a forum, I tried to switch to the MIRO plugin and delete the MIRO Tools & MCP web connection.

Since then I have tried to delete all web Tools & MCP entries and only use the Plugin - but this does not resolve the issue. Uninstalling the Plugin and using the web worked for a moment.

I am having this same issue with multiple MCPs since updating to 3.7.27.

Same problem i think with new version

Same issue on Cursor 3.7.27 — Windows 10 (non-corporate), persists after full restart

Confirming this matches my environment exactly.

Environment

  • Cursor: 3.7.27 (stable)
  • OS: Windows 10 x64 (10.0.19045), per-user install
  • MCP config: HTTP servers only (~/.cursor/mcp.json — Supabase, Context7, Linear, Autodesk); config unchanged and was working before the upgrade

Symptoms

  • All 7 external MCP servers show error, 0 tools
  • Built-in cursor-ide-browser connects; everything else fails
  • Agent cannot call MCP tools (No MCP servers available)

Logs (identical to OP)

[McpProcess] timed out waiting for ipcReady after 10000ms

(repeats at restartCount 0..2, then host eventually reaches initDone on ~3rd retry)

[MCPService] Error creating client: Failed to acquire MessagePort for response channel

‘vscode:createMcpProcessChannelConnectionResult’

Timeline

  • Before upgrade (June 11): MCP host connected to streamableHttp servers successfully (Successfully connected to streamableHttp server in mcpprocess.log)
  • After upgrade to 3.7.27 (June 12): host sometimes reaches initDone, but workbench never attaches via MessagePort; no connecting streamableHttp lines in the new session at all
  • Renderer log: latched shared-process MCP routing enabled for this session after OAuth migration

Already tried (no fix)

  • Full Cursor quit + relaunch (new session at 18:33 — same failure)
  • Toggle MCP servers off/on in Settings
  • Config is valid; not a server-side or OAuth token issue

Impact: Supabase/Context7/Linear MCP unusable; relying on CLI as workaround.

+1 — blocking daily workflow. Happy to attach log excerpts if useful.

Where does the bug appear?
Cursor IDE

Describe the Bug

My HTTP-based MCP server is configured correctly and the server itself is running, but Cursor never connects. The MCP service log shows Cursor finds the server, then fails during internal IPC setup before any HTTP connection is attempted.

Environment

  • Cursor version: 3.7.27
  • OS: Windows 11 Enterprise (10.0.22631), x64
  • Install type: per-user
  • MCP config location: ~/.cursor/mcp.json

MCP server config

HTTP/streamable-http server pointing at a local XYZ MCP instance:

“xyz-mcp-local”: {

“url”: “http://127.0.0.1:8000/mcp

}

Symptoms

  • MCP Settings shows xyz-mcp-local in error state (0 tools)
  • Agent reports: MCP server does not exist: user-xyz-mcp-local. Available servers: cursor-app-control
  • The local server is running — port 8000 is listening and accepts connections
  • Same failure pattern as other reports on this thread

Log excerpt (MCP Service)

2026-06-13 01:26:13.918 [info] [MCPService] createClient: identifier=“user-xyz-mcp-local”, serverName=“xyz-mcp-local”

2026-06-13 01:26:13.918 [error] [MCPService] Error creating client: Failed to acquire MessagePort for response channel ‘vscode:createMcpProcessChannelConnectionResult’

2026-06-13 01:26:16.759 [info] [MCPService] createClient: identifier=“user-xyz-mcp-local”, serverName=“xyzmcp-local”

2026-06-13 01:26:16.763 [error] [MCPService] Error creating client: Failed to acquire MessagePort for response channel ‘vscode:createMcpProcessChannelConnectionResult’

(retries continue with the same MessagePort error)

What this suggests

Cursor does read and recognize the server config (createClient is called with the correct identifier). The failure happens at the internal MCP host IPC handshake (createMcpProcessChannelConnectionResult / MessagePort), before Cursor attempts to connect to http://127.0.0.1:8000/mcp. This appears to be the same regression described in MCP fails to start — utility process never reaches ipcReady (Windows), not a misconfiguration of the HTTP server itself.

Steps to Reproduce

  1. Configure an HTTP MCP server in ~/.cursor/mcp.json (streamable-http, local URL)
  2. Ensure the server is running and listening (e.g. 127.0.0.1:8000)
  3. Open Cursor and check Settings → MCP
  4. Observe MessagePort / createMcpProcessChannelConnectionResult errors in MCP logs
  5. Agent cannot call any tools from the configured server

Already tried

  • Confirmed server is up (port 8000 listening)
  • Confirmed MCP config is valid and server name matches
  • Toggled server off/on in MCP Settings
  • (add anything else you tried: restart, reinstall, clear cache, etc.)

Impact

Blocks use of XYZ MCP tools in Cursor Agent. Previously worked in earlier sessions; broke after recent Cursor update.

Does this stop you from using Cursor?

Yes — for MCP-dependent agent workflows.

Still reproducible on Cursor 3.7.36 Stable.

Version: 3.7.36 (user setup)
VS Code Extension API: 1.105.1
Commit: 776d1f9d76df50a4e0aeca61819a88e7c1b861e0
Date: 2026-06-13T00:31:56.287Z
Layout: glass
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
OS: Windows_NT x64 10.0.26200

All MCP servers fail with:
Error creating client: Failed to acquire MessagePort for response channel 'vscode:createMcpProcessChannelConnectionResult'

Restarting Cursor and Windows had no effect. MCP configs were working before and the logs show createClient failing before server spawn/output.


### Where does the bug appear (feature/product)?

Cursor IDE

### Describe the Bug

External MCP servers (HTTP/SSE / streamableHttp) fail to connect on Windows. The remote MCP server itself is healthy and reachable, but Cursor never completes the internal `mcpProcess` → workbench IPC handshake.

This matches the existing report in, with an additional detail: **`mcpProcess` eventually reaches `initDone` on retry, but the renderer/workbench connection is permanently dropped after the first `ipcReady` timeout**, so all subsequent `createClient` calls fail with the MessagePort error.

The built-in `cursor-ide-browser` MCP connects fine (it does not appear to depend on the same `mcpProcess` path). All user-configured remote servers fail.

### Environment

- **Cursor version:** 3.7.36 (user setup)

- **VS Code Extension API:** 1.105.1

- **Commit:** `776d1f9d76df50a4e0aeca61819a88e7c1b861e0`

- **Date:** 2026-06-13T00:31:56.287Z

- **Release track:** `dev` (switched from stable; dev update 3.7.39 downloaded but not yet applied at time of report)

- **Electron:** 39.8.1

- **Chromium:** 142.0.7444.265

- **Node.js:** 22.22.1

- **OS:** Windows_NT x64 **10.0.26200**

- **Install type:** per-user (`%LOCALAPPDATA%\Programs\cursor`)

- **MCP config:** `~/.cursor/mcp.json` — HTTP/SSE remote server

```json

{

“mcpServers”: {

“planka”: {

“url”: “https://planka-mcp.example.de/sse

}

}

}

```

### Timeline

| Date | Cursor version | MCP status |

|------|----------------|------------|

| 2026-06-12 | **3.7.27** (stable) | :white_check_mark: Remote MCP connected: `createClient completed … connected=true` |

| 2026-06-13 | Upgraded to **3.7.36** | :cross_mark: MessagePort errors from first launch |

| 2026-06-14 | 3.7.36 + cache repair | :cross_mark: Same failure after full MCP/GPU cache cleanup |

### Symptoms / log evidence

**Renderer (`mcp-server-user-planka.workbench.log`):**

```

[MCPService] createClient: identifier=“user-planka”, serverName=“planka”

[MCPService] Error creating client: Failed to acquire MessagePort for response channel ‘vscode:createMcpProcessChannelConnectionResult’

```

**Main process (`main.log`):**

```

[McpProcess] ipcReady wait failed; coldStartTimeoutMs=10000 elapsedMs=10011

[McpProcess] timed out waiting for ipcReady after 10000ms

[McpProcess] whenReady rejected, dropping window connection

[McpProcess] initial main connect failed

```

**`mcpprocess.log` — race condition:**

```

09:58:31 mcpProcess start (attempt 0, pid 25304)

09:58:41 ipcReady timeout → process killed

09:58:42 mcpProcess restart (attempt 1, pid 21756)

09:58:45 ipcReady + initDone :white_check_mark: (elapsed ~3s on retry)

09:59:03 createClient for user-planka → MessagePort error :cross_mark: (18s after initDone)

The MCP server log shows **no new `Client connected`** from Cursor after the regression — consistent with Cursor failing before any HTTP connection is attempted.

**Structured log metadata:**

- `serverType`: `streamableHttp`

- `mcpMeta.errorMessage`: `Failed to acquire MessagePort for response channel ‘vscode:createMcpProcessChannelConnectionResult’`

- `toolCount` in agent snapshot: `0` (snapshot refresh also fails with same MessagePort error)

Also observed once: `Extension host became UNRESPONSIVE` with 5 active composers during the same session.

### Steps to Reproduce

1. Configure a remote HTTP/SSE MCP server in `~/.cursor/mcp.json`

2. Confirm the server is up (`/health` returns 200, `/sse` streams)

3. Launch Cursor on Windows (3.7.36)

4. Open Settings → MCP → server shows **error**, 0 tools

5. Check logs: MessagePort error in workbench; `whenReady rejected, dropping window connection` in `main.log`

### Already tried (no fix)

- Full Cursor quit + relaunch (multiple times)

- Cleared MCP cache: `%APPDATA%\Cursor\User\globalStorage\anysphere.cursor-mcp`

- Cleared `Cache`, `Code Cache`, `GPUCache`

- Cleared project-level `mcps/` snapshots under `~/.cursor/projects/*/mcps`

- Toggled MCP server off/on in Settings

- Switched release track to `dev` (3.7.39 downloaded, pending restart)

- **Developer: Reload Window** after waiting 20s — still failing

- Remote server verified healthy independently (health + SSE endpoints)

**Not tried:** full reinstall, Windows Defender exclusions, `–disable-gpu-sandbox`

### What this suggests

1. Not a misconfigured MCP server or OAuth/token issue

2. Not a network/DNS issue (server reachable from same machine via curl)

3. Failure is in Cursor’s internal `mcpProcess` ↔ renderer MessagePort bootstrap

4. Likely a **cold-start race**: first `ipcReady` attempt exceeds 10s timeout → window connection dropped → even after `mcpProcess` recovers, workbench cannot acquire `createMcpProcessChannelConnectionResult`

5. Regression introduced between **3.7.27** (worked) and **3.7.36** (broken)

### Impact

Blocks all external MCP tooling in Agent workflows (Kanban/project management integration, etc.). Built-in browser MCP still works. Daily workflow significantly impacted.

### Does this stop you from using Cursor?

No for general editing, but **yes for MCP-dependent agent workflows**.

Happy to attach full log excerpts (`main.log`, `mcpprocess.log`, `mcp-server-user-planka.workbench.log`) if useful.

-–

Hi all, this is a known issue on our side, not your configs, and our team is actively working on it.

Until the fix ships, these tend to recover it on current builds:

  • Reload the window - Ctrl+Shift+P → Developer: Reload Window. This is the most reliable one and re-establishes the MCP connection in most reports.
  • Switch workspaces - open a different folder and come back, which also re-triggers the connection.
  • Reduce the number of enabled MCP servers - the timeout is more likely when many servers initialize at once on startup, so temporarily turning a few off in Settings → MCP can help the rest come up.

One note for anyone on a corporate-managed or locked-down Windows machine: endpoint security (Core Isolation / EDR / antivirus) can interfere with Cursor’s helper processes at startup. If reloads don’t help on a managed device, it’s worth asking your IT team to allowlist Cursor’s install folder and its helper processes.

No ETA to share yet, but I’ll update this thread once the fix lands. If reloading or switching workspaces does not recover MCP for you, that’s useful signal - let me know your exact Cursor version and whether the host eventually recovers on its own after a minute or two.

Docs: Model Context Protocol

hi @mohitjain ,

Adding signal here - unfortunately, reloading and switching workspaces does NOT work for me.

Current output from Help>About:

Version: 3.7.36 (user setup)
VS Code Extension API: 1.105.1
Commit: 776d1f9d76df50a4e0aeca61819a88e7c1b861e0
Date: 2026-06-13T00:31:56.287Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

There are only 3 MCP servers running and all experience the same error. This does not resolve at any point for me.

FWIW I had been able to get things working by Developer - Reload Window as late as Jun 11 last week (not sure what version I had then, but I generally take updates as soon as they are available). After updating this morning, that reload no longer works.

Editing - I see that another reload seems to have fixed it. This feels wildly intermittent on my end – gotta be the 4th or 5th attempt at that workaround.

Still reloading your windows, guys?

I have enabled logging level “trace”, fully restarted Cursor and saw this logged:

[error] [uncaught exception in sharedProcess]: A system error occurred (EBUSY: resource busy or locked, unlink 'c:\Users\my-user-name\AppData\Roaming\Cursor\logs\20260527T093904\window1\exthost\extHostTelemetry.log'): Error: EBUSY: resource busy or locked, unlink 'c:\Users\my-user-name\AppData\Roaming\Cursor\logs\20260527T093904\window1\exthost\extHostTelemetry.log'

I decided this is Cursor crash-reporting telemetry holding lock, but turning it off didn’t help.

But the directory 20260527T093904 was quite old and it was suspicious why the cursor trying to lock files there after complete restart. So i have stopped Cursor completely, deleted all subdirs in the logs directory and next run my MCPs are working again!

But, this w/a didn’t work for my colleague, who got similar symptoms but cause was different.. So obviously it was number of issues included in the same update.

Where does the bug appear (feature/product)?

Somewhere else…

Describe the Bug

On Windows, every MCP server in Settings → MCP shows “Error” — including pure-local stdio servers that use no OAuth and no network. Reconnect, Reload Window, toggling off/on, and a full Cursor restart all have no effect.

Indicators that this is a wedged MCP host (not a per-server config problem):

  • All servers fail at once, including local stdio ones.
  • Server/process count for the MCP runtime is 0 — nothing is ever spawned.
  • The MCP host log is 0 bytes (host never attempts to spawn):
    %APPDATA%\Cursor\logs{session}\window1\exthost\anysphere.cursor-mcp\MCP Logs.log

Root cause (confirmed on my machine): stale OAuth-attempt records left behind by a previously failed MCP OAuth flow wedge the entire MCP host initialization on startup, so ALL servers go down regardless of transport. Removing that stale state restores every server.

Confirmation it is the host, not your config: run a server’s command manually, e.g.
node “C:\path\to\mcp-server\index.js”
If it prints “… server running on stdio”, your config/runtime are fine and the fault is Cursor’s MCP host.

Steps to Reproduce

  1. Use an MCP server that requires OAuth (HTTP/SSE) and let an OAuth flow fail or get interrupted (this leaves stale records under mcp-oauth-attempts).
  2. Restart Cursor.
  3. Observe Settings → MCP: ALL servers show “Error”, including local stdio servers unrelated to OAuth.
  4. Reconnect / Reload Window / full restart do nothing. Process count is 0 and the MCP host log is 0 bytes.

Recovery (also the proof of root cause):

  1. Close Cursor completely (Task Manager → end all “Cursor” processes).
  2. Delete these if present (back them up first; Cursor regenerates them):
    • %APPDATA%\Cursor\User\globalStorage\mcp-oauth-attempts\
    • %APPDATA%\Cursor\User\globalStorage\anysphere.cursor-mcp\mcp-oauth-attempts\
    • %USERPROFILE%.mcp-auth\
  3. Restart Cursor → all servers spawn normally again (re-sign-in to OAuth servers as needed).

Expected Behavior

A failed or stale OAuth attempt for one MCP server must not wedge the entire MCP host. Local stdio servers (no OAuth, no network) should always start regardless of any OAuth state, and stale mcp-oauth-attempts records should be ignored / self-cleaned on startup instead of blocking host initialization.

Operating System

Windows 10/11

Version Information

IDE:
Version: 3.7.21
VSCode Version:

Additional Information

Manual fix (no tools needed) is in Steps to Reproduce above.

For convenience I wrote a single self-contained Windows .cmd (no Python, no Node required to run it) that diagnoses servers and performs the cleanup WITH an automatic backup:

  • health / status are read-only.
  • reset refuses to run while Cursor is open, and backs up everything to
    %USERPROFILE%.cursor_mcp_state_backup_ before deleting.
  • It only touches Cursor’s regenerable MCP OAuth/cache state.
@echo off
chcp 65001 >nul 2>&1
setlocal EnableDelayedExpansion
title MCP Reanimate - Cursor MCP Recovery

REM ===========================================================================
REM  MCP Reanimate  -  Cursor MCP connection recovery for Windows
REM  Version 1.0  |  Tested on: Cursor 3.7.21, Windows 10/11, PowerShell 5.1+
REM ---------------------------------------------------------------------------
REM  WHAT IT DOES
REM    Diagnoses and recovers Cursor MCP servers when they all show "Error"
REM    and Reconnect / Reload Window / restart have no effect.
REM    Targets the known root cause: stale OAuth-attempt records that wedge
REM    Cursor's MCP host on startup, taking down ALL servers (even local ones).
REM
REM  REQUIREMENTS
REM    Windows + built-in PowerShell only. No Python, no Node needed to run it.
REM
REM  SAFETY
REM    health / status : READ-ONLY, no side effects.
REM    restore         : only removes "disabled" flags from mcp.json.
REM    kill-zombies    : kills orphaned processes of DISABLED servers only,
REM                      and only on an unambiguous (specific path) match.
REM    reset           : refuses to run while Cursor is open; ALWAYS backs up
REM                      to %USERPROFILE%\.cursor\_mcp_state_backup_<timestamp>
REM                      before deleting. Only touches Cursor's regenerable
REM                      MCP OAuth/cache state.
REM
REM  FUTURE CURSOR VERSIONS
REM    If Cursor moves its internal paths, 'reset' just skips the missing
REM    folders ([skip]) - no harm done. Verify the paths in Invoke-McpReset.
REM
REM  License: public domain / CC0 - use freely.
REM ===========================================================================

echo.
echo  MCP Reanimate - Cursor MCP connection recovery
echo  ================================================
echo.

if /i "%~1"=="help" goto :show_help
if /i "%~1"=="/?" goto :show_help

if /i "%~1"=="reset" (
  echo  WARNING: reset requires Cursor to be FULLY CLOSED!
  echo           Task Manager - end all "Cursor" processes
  echo.
)

set "TMP=%TEMP%\mcp-reanimate-%RANDOM%.ps1"
more +85 "%~f0" > "%TMP%"
if errorlevel 1 (
  echo ERROR: failed to prepare script.
  pause
  exit /b 1
)

powershell -NoProfile -ExecutionPolicy Bypass -File "%TMP%" %*
set "EC=!ERRORLEVEL!"
del "%TMP%" 2>nul

echo.
if !EC! equ 0 (echo Done.) else (echo Check messages above.)
if "%~1"=="" pause
exit /b !EC!

:show_help
echo Usage: double-click OR mcp-reanimate.cmd [action] [-ConfigPath path\to\mcp.json]
echo.
echo  (none)   auto-recovery - start here
echo  health   quick test: are stdio servers running?
echo  status   detailed server list
echo  restore  remove disabled flags from mcp.json
echo  reset    full OAuth cache reset - no mcp.json needed; Cursor MUST be closed!
echo  help     this help
echo.
echo Config: auto-discovers %%USERPROFILE%%\.cursor\mcp.json and workspace .cursor\mcp.json
echo         (walks up from current directory). Override: -ConfigPath or MCP_CONFIG_PATH env var.
echo.
echo No Python or Node required to run this script. Run from cmd OUTSIDE Cursor terminal.
echo.
pause
exit /b 0

REM ===== POWERSHELL BELOW (extracted via 'more +85'; keep this marker at line 85) =====
[CmdletBinding()]
param(
    [Parameter(Position = 0)]
    [ValidateSet('reanimate', 'health', 'status', 'restore', 'reset', 'kill-zombies')]
    [string]$Action = 'reanimate',

    [string]$ConfigPath,
    [switch]$Force
)

$ErrorActionPreference = 'Stop'

function Write-Info([string]$Message) { Write-Host $Message }
function Write-Ok([string]$Message) { Write-Host $Message -ForegroundColor Green }
function Write-Warn([string]$Message) { Write-Host $Message -ForegroundColor Yellow }
function Write-Err([string]$Message) { Write-Host $Message -ForegroundColor Red }

function Find-McpConfigPaths {
    if ($ConfigPath) {
        if (-not (Test-Path -LiteralPath $ConfigPath)) {
            throw "Config not found: $ConfigPath"
        }
        return @((Resolve-Path -LiteralPath $ConfigPath).Path)
    }

    if ($env:MCP_CONFIG_PATH) {
        if (-not (Test-Path -LiteralPath $env:MCP_CONFIG_PATH)) {
            throw "MCP_CONFIG_PATH not found: $env:MCP_CONFIG_PATH"
        }
        return @((Resolve-Path -LiteralPath $env:MCP_CONFIG_PATH).Path)
    }

    $ordered = [System.Collections.Generic.List[string]]::new()

    $globalPath = Join-Path $env:USERPROFILE '.cursor\mcp.json'
    if (Test-Path -LiteralPath $globalPath) {
        [void]$ordered.Add((Resolve-Path -LiteralPath $globalPath).Path)
    }

    $dir = (Get-Location).Path
    while ($dir) {
        $wsPath = Join-Path $dir '.cursor\mcp.json'
        if (Test-Path -LiteralPath $wsPath) {
            $resolved = (Resolve-Path -LiteralPath $wsPath).Path
            if ($ordered -notcontains $resolved) {
                [void]$ordered.Add($resolved)
            }
        }
        $parent = Split-Path -Parent $dir
        if (-not $parent -or $parent -eq $dir) { break }
        $dir = $parent
    }

    return @($ordered)
}

function Get-McpConfigFiles {
    $paths = Find-McpConfigPaths
    if ($paths.Count -eq 0) {
        return @()
    }

    $files = [System.Collections.Generic.List[object]]::new()
    foreach ($path in $paths) {
        $raw = Get-Content -LiteralPath $path -Raw -Encoding UTF8
        $config = $raw | ConvertFrom-Json
        if (-not $config.mcpServers) { continue }
        [void]$files.Add([PSCustomObject]@{
                Path   = $path
                Config = $config
            })
    }
    return @($files)
}

function Save-McpConfigFile([string]$Path, [object]$Config) {
    $json = ($Config | ConvertTo-Json -Depth 20)
    [System.IO.File]::WriteAllText($Path, $json + [Environment]::NewLine, [System.Text.UTF8Encoding]::new($false))
}

function Test-HttpServer([object]$ServerCfg) {
    return ($null -ne $ServerCfg.url) -and ([string]::IsNullOrWhiteSpace($ServerCfg.command))
}

$GenericRunners = @(
    'node', 'node.exe', 'npx', 'npx.cmd', 'npm', 'npm.cmd', 'pnpm', 'yarn',
    'python', 'python.exe', 'python3', 'pythonw', 'pythonw.exe', 'py', 'py.exe',
    'uv', 'uv.exe', 'uvx', 'uvx.exe', 'deno', 'deno.exe', 'bun', 'bun.exe',
    'ruby', 'ruby.exe', 'cmd', 'cmd.exe', 'sh', 'bash', 'powershell', 'powershell.exe', 'pwsh', 'pwsh.exe',
    '-y', '--yes', '-m', '--env-file', 'run', 'start', 'mcp', 'index.js'
)

function Test-NeedleSpecific([string]$Needle) {
    if ([string]::IsNullOrWhiteSpace($Needle)) { return $false }
    $lower = $Needle.ToLowerInvariant()
    if ($GenericRunners -contains $lower) { return $false }
    if ($Needle.Length -lt 5) { return $false }
    # Specific tokens look like a path, package, or hyphenated server id.
    return ($Needle -match '[\\/@:.]' -or $Needle -match '\w-\w')
}

function Get-ServerMatchNeedle([object]$ServerCfg) {
    $candidates = [System.Collections.Generic.List[string]]::new()
    if ($ServerCfg.args) {
        foreach ($arg in @($ServerCfg.args)) {
            $s = [string]$arg
            if (-not [string]::IsNullOrWhiteSpace($s)) { [void]$candidates.Add($s) }
        }
    }
    if ($ServerCfg.command) {
        [void]$candidates.Add([string]$ServerCfg.command)
    }
    if ($candidates.Count -eq 0) {
        return [PSCustomObject]@{ Needle = $null; Specific = $false }
    }

    # Prefer the longest SPECIFIC token (script path, scoped package, server id).
    $specific = $candidates |
        Where-Object { Test-NeedleSpecific $_ } |
        Sort-Object { $_.Length } -Descending |
        Select-Object -First 1
    if ($specific) {
        return [PSCustomObject]@{ Needle = $specific; Specific = $true }
    }

    # Fallback: longest token, but flagged non-specific (display only, never kill).
    $best = $candidates | Sort-Object { $_.Length } -Descending | Select-Object -First 1
    return [PSCustomObject]@{ Needle = $best; Specific = $false }
}

function Get-McpServerProcesses {
    $exeNames = @('node.exe', 'python.exe', 'pythonw.exe', 'deno.exe', 'uv.exe', 'ruby.exe', 'bun.exe')
    $filter = ($exeNames | ForEach-Object { "Name='$_'" }) -join ' OR '
    try {
        return @(Get-CimInstance Win32_Process -Filter $filter -ErrorAction Stop |
            Where-Object { $_.CommandLine } |
            ForEach-Object {
                [PSCustomObject]@{
                    Pid = [int]$_.ProcessId
                    Cmd = [string]$_.CommandLine
                }
            })
    }
    catch {
        Write-Warn "Could not list MCP server processes: $($_.Exception.Message)"
        return @()
    }
}

function Get-ServerPids([object]$ServerCfg, [array]$Processes) {
    $match = Get-ServerMatchNeedle $ServerCfg
    if (-not $match.Needle) { return @() }
    $norm = ($match.Needle -replace '\\', '/').ToLowerInvariant()
    return @($Processes | Where-Object {
            ($_.Cmd -replace '\\', '/').ToLowerInvariant().Contains($norm)
        } | ForEach-Object { $_.Pid })
}

function Test-ServerEnabled([object]$ServerCfg) {
    if ($null -eq $ServerCfg.disabled) { return $true }
    return ($ServerCfg.disabled -ne $true)
}

function Get-McpHealthReport([array]$ConfigFiles) {
    $processes = Get-McpServerProcesses
    $rows = [System.Collections.Generic.List[object]]::new()
    $dead = [System.Collections.Generic.List[string]]::new()
    $disabled = [System.Collections.Generic.List[string]]::new()
    $seen = @{}

    foreach ($file in $ConfigFiles) {
        foreach ($name in @($file.Config.mcpServers.PSObject.Properties.Name)) {
            if ($seen.ContainsKey($name)) { continue }
            $seen[$name] = $true

            $cfg = $file.Config.mcpServers.$name
            $enabled = Test-ServerEnabled $cfg
            $label = if ($ConfigFiles.Count -gt 1) {
                $srcDir = Split-Path -Leaf (Split-Path -Parent (Split-Path -Parent $file.Path))
                "$name [$srcDir]"
            }
            else { $name }

            if (Test-HttpServer $cfg) {
                $rows.Add([PSCustomObject]@{
                        Name       = $label
                        Tag        = 'HTTP'
                        Pids       = @()
                        Enabled    = $enabled
                        SourcePath = $file.Path
                    })
                continue
            }

            $pids = Get-ServerPids $cfg $processes
            $alive = ($pids.Count -gt 0)

            $tag = switch ($true) {
                ($enabled -and $alive) { 'ON' }
                ($enabled -and -not $alive) { 'DEAD' }
                (-not $enabled -and $alive) { 'ZOMBI' }
                default { 'OFF' }
            }

            if ($enabled -and -not $alive) { [void]$dead.Add($label) }
            if (-not $enabled) { [void]$disabled.Add($label) }

            $rows.Add([PSCustomObject]@{
                    Name       = $label
                    Tag        = $tag
                    Pids       = $pids
                    Enabled    = $enabled
                    SourcePath = $file.Path
                })
        }
    }

    return [PSCustomObject]@{
        Rows      = $rows
        Dead      = $dead
        Disabled  = $disabled
        NodeCount = $processes.Count
    }
}

function Assert-McpConfigFiles([array]$ConfigFiles) {
    if ($ConfigFiles.Count -gt 0) { return $ConfigFiles }

    Write-Err 'No mcp.json found.'
    Write-Info "Searched:"
    Write-Info "  - $env:USERPROFILE\.cursor\mcp.json (global / official Cursor config)"
    Write-Info "  - .cursor\mcp.json in current directory and parents"
    Write-Info ''
    Write-Info 'Tip: run from your project folder, set MCP_CONFIG_PATH, or pass -ConfigPath.'
    Write-Info 'Note: "reset" does not require mcp.json - use: mcp-reanimate.cmd reset'
    exit 1
}

function Show-ConfigSources([array]$ConfigFiles) {
    if ($ConfigFiles.Count -eq 0) { return }
    Write-Info 'Config sources:'
    foreach ($file in $ConfigFiles) {
        Write-Info "  - $($file.Path)"
    }
}

function Invoke-McpStatus {
    $configFiles = Assert-McpConfigFiles (Get-McpConfigFiles)
    Show-ConfigSources $configFiles
    Write-Info ''
    $report = Get-McpHealthReport $configFiles
    foreach ($row in $report.Rows) {
        switch ($row.Tag) {
            'HTTP' {
                Write-Info ("  HTTP   {0}  (managed by Cursor - Settings -> MCP)" -f $row.Name)
            }
            default {
                $pidInfo = if ($row.Pids.Count -gt 0) { "  (PID $($row.Pids -join ','))" } else { '' }
                Write-Info ("  {0,-5}  {1}{2}" -f $row.Tag, $row.Name, $pidInfo)
            }
        }
    }
}

function Invoke-McpHealth {
    $configFiles = Assert-McpConfigFiles (Get-McpConfigFiles)
    Show-ConfigSources $configFiles
    Write-Info ''
    $report = Get-McpHealthReport $configFiles
    $problems = $report.Dead.Count + $report.Disabled.Count

    if ($problems -eq 0) {
        Write-Ok 'ALL OK - all stdio servers enabled and running'
        exit 0
    }

    if ($report.Disabled.Count -gt 0) {
        Write-Err ("VIOLATION - {0} server(s) disabled: {1}" -f `
                $report.Disabled.Count, ($report.Disabled -join ', '))
        Write-Info '  Fix: mcp-reanimate.cmd restore, then restart Cursor.'
    }

    if ($report.Dead.Count -gt 0) {
        Write-Err ("UNHEALTHY - {0} server(s) dead: {1}" -f `
                $report.Dead.Count, ($report.Dead -join ', '))
        Write-Info '  Fix: Settings -> MCP -> Reconnect, or restart Cursor.'
        if ($report.NodeCount -eq 0) {
            Write-Info '  Hint: 0 MCP server processes - close Cursor, run: mcp-reanimate.cmd reset'
        }
    }

    exit 1
}

function Invoke-McpRestore {
    $configFiles = Assert-McpConfigFiles (Get-McpConfigFiles)
    $totalRestored = 0

    foreach ($file in $configFiles) {
        $restored = 0
        foreach ($name in @($file.Config.mcpServers.PSObject.Properties.Name)) {
            $server = $file.Config.mcpServers.$name
            if ($server.PSObject.Properties.Name -contains 'disabled') {
                $server.PSObject.Properties.Remove('disabled')
                $restored++
            }
        }
        if ($restored -gt 0) {
            Save-McpConfigFile $file.Path $file.Config
            Write-Ok "Restored $restored server(s) in $($file.Path)"
            $totalRestored += $restored
        }
    }

    if ($totalRestored -gt 0) {
        Write-Info 'Restart Cursor IDE to start the servers.'
    }
    else {
        Write-Ok 'All servers already enabled (no disabled field).'
    }
}

function Stop-ProcessSafe([int]$ProcessId) {
    try {
        Stop-Process -Id $ProcessId -Force -ErrorAction Stop
        return $true
    }
    catch {
        return $false
    }
}

function Invoke-McpKillZombies {
    $configFiles = Assert-McpConfigFiles (Get-McpConfigFiles)
    $processes = Get-McpServerProcesses
    $killed = [System.Collections.Generic.List[string]]::new()
    $skipped = [System.Collections.Generic.List[string]]::new()

    foreach ($file in $configFiles) {
        foreach ($name in @($file.Config.mcpServers.PSObject.Properties.Name)) {
            $cfg = $file.Config.mcpServers.$name
            if (Test-ServerEnabled $cfg) { continue }
            if (Test-HttpServer $cfg) { continue }

            # Safety: only kill when the process match is UNAMBIGUOUS (specific
            # script path / package id). A generic runner needle (node, npx,
            # python, ...) could match unrelated processes - never kill on it.
            $match = Get-ServerMatchNeedle $cfg
            if (-not $match.Specific) {
                [void]$skipped.Add($name)
                continue
            }

            $pids = Get-ServerPids $cfg $processes
            foreach ($procId in $pids) {
                if (Stop-ProcessSafe $procId) {
                    [void]$killed.Add("${name}:$procId")
                }
            }
        }
    }

    if ($killed.Count -gt 0) {
        Write-Ok ("Killed {0} zombie(s): {1}" -f $killed.Count, ($killed -join ', '))
    }
    else {
        Write-Info 'No zombie processes found'
    }
    if ($skipped.Count -gt 0) {
        Write-Warn ("Skipped {0} server(s) with ambiguous process match (not killed for safety): {1}" -f `
                $skipped.Count, ($skipped -join ', '))
    }
}

function Test-CursorRunning {
    return $null -ne (Get-Process -Name 'Cursor' -ErrorAction SilentlyContinue)
}

function Invoke-McpReset {
    if (Test-CursorRunning) {
        Write-Err 'Cursor is still running. Close Cursor completely (Task Manager), then re-run: mcp-reanimate.cmd reset'
        exit 1
    }
    Write-Ok '[OK] Cursor not running.'

    $ts = Get-Date -Format 'yyyyMMdd-HHmmss'
    $backup = Join-Path $env:USERPROFILE ".cursor\_mcp_state_backup_$ts"
    New-Item -ItemType Directory -Path $backup -Force | Out-Null
    Write-Info "Backup dir: $backup"

    function Backup-AndRemove([string]$Path, [string]$Label) {
        if (Test-Path -LiteralPath $Path) {
            $dest = Join-Path $backup $Label
            $destParent = Split-Path -Parent $dest
            if ($destParent -and -not (Test-Path $destParent)) {
                New-Item -ItemType Directory -Path $destParent -Force | Out-Null
            }
            Copy-Item -LiteralPath $Path -Destination $dest -Recurse -Force -ErrorAction SilentlyContinue
            Remove-Item -LiteralPath $Path -Recurse -Force
            Write-Warn "[CLEARED] $Label  <- $Path"
        }
        else {
            Write-Host "[skip] $Label (not present)" -ForegroundColor DarkGray
        }
    }

    $gs = Join-Path $env:APPDATA 'Cursor\User\globalStorage'

    Backup-AndRemove (Join-Path $gs 'mcp-oauth-attempts') 'globalStorage_mcp-oauth-attempts'
    Backup-AndRemove (Join-Path $gs 'anysphere.cursor-mcp\mcp-oauth-attempts') 'cursor-mcp_mcp-oauth-attempts'
    Backup-AndRemove (Join-Path $env:USERPROFILE '.mcp-auth') 'dot-mcp-auth'

    $cursorMcpDir = Join-Path $gs 'anysphere.cursor-mcp'
    if (Test-Path -LiteralPath $cursorMcpDir) {
        Get-ChildItem -LiteralPath $cursorMcpDir -File -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -match 'cache|snapshot|state' } |
            ForEach-Object { Backup-AndRemove $_.FullName "cursor-mcp_$($_.Name)" }
    }

    Write-Ok '=== RESET DONE ==='
    Write-Info "Backup: $backup"
    Write-Info 'Relaunch Cursor, then run: mcp-reanimate.cmd health'
}

function Invoke-McpReanimate {
    Write-Info '=== MCP Reanimate ==='

    $configFiles = Get-McpConfigFiles
    if ($configFiles.Count -eq 0) {
        Write-Warn 'No mcp.json found - skipping config-based recovery.'
        Write-Info "Searched: $env:USERPROFILE\.cursor\mcp.json and workspace .cursor\mcp.json"
        $procCount = (Get-McpServerProcesses).Count
        if ($procCount -eq 0) {
            Write-Warn '0 MCP server processes detected - possible MCP host wedge.'
            if (Test-CursorRunning) {
                Write-Err @"

Next steps:
  1. Close Cursor completely (Task Manager - end ALL Cursor processes)
  2. Run: mcp-reanimate.cmd reset
  3. Relaunch Cursor
"@
                exit 1
            }
            if (-not $Force) {
                $answer = Read-Host 'Run state reset now? Cursor is closed. [y/N]'
                if ($answer -notmatch '^[yY]') { exit 1 }
            }
            Invoke-McpReset
            exit 0
        }
        Write-Ok 'MCP processes running; no config file to repair. If issues persist, try reset after closing Cursor.'
        exit 0
    }

    Show-ConfigSources $configFiles
    Write-Info ''

    $report = Get-McpHealthReport $configFiles

    if ($report.Dead.Count -eq 0 -and $report.Disabled.Count -eq 0) {
        Write-Ok 'ALL OK - nothing to do.'
        exit 0
    }

    if ($report.Disabled.Count -gt 0) {
        Write-Warn 'Step 1: restoring disabled server flags in mcp.json...'
        Invoke-McpRestore
        $configFiles = Get-McpConfigFiles
        $report = Get-McpHealthReport $configFiles
    }

    if ($report.Dead.Count -eq 0 -and $report.Disabled.Count -eq 0) {
        Write-Ok 'Recovery complete after restore. Restart Cursor if it was open.'
        exit 0
    }

    if ($report.Dead.Count -gt 0 -and $report.NodeCount -eq 0) {
        Write-Warn 'All stdio servers dead, 0 MCP server processes - likely MCP host wedge.'
        if (Test-CursorRunning) {
            Write-Err @"

Next steps:
  1. Close Cursor completely (Task Manager - end ALL Cursor processes)
  2. Run: mcp-reanimate.cmd reset
  3. Relaunch Cursor, then: mcp-reanimate.cmd health
"@
            exit 1
        }

        if (-not $Force) {
            $answer = Read-Host 'Run state reset now? Cursor is closed. [y/N]'
            if ($answer -notmatch '^[yY]') {
                Write-Info 'Aborted. Run reset when ready: mcp-reanimate.cmd reset'
                exit 1
            }
        }

        Invoke-McpReset
        exit 0
    }

    if ($report.Dead.Count -gt 0) {
        Write-Warn 'Some servers dead but MCP server processes exist.'
        Write-Info @"
Try in order:
  1. Cursor Settings -> MCP -> Reconnect
  2. Restart Cursor IDE
  3. If ALL Error + 0 processes after restart: close Cursor, mcp-reanimate.cmd reset
"@
        exit 1
    }
}

switch ($Action) {
    'status' { Invoke-McpStatus; break }
    'health' { Invoke-McpHealth; break }
    'restore' { Invoke-McpRestore; break }
    'reset' { Invoke-McpReset; break }
    'kill-zombies' { Invoke-McpKillZombies; break }
    'reanimate' { Invoke-McpReanimate; break }
}

Likely trigger: the OAuth browser-open SDK failure tracked here —

A failed flow from that bug can leave the stale mcp-oauth-attempts records that then wedge the whole host on Windows.

Verified on Windows (Cursor 3.7.21):

  • Before fix: all MCP servers showed Error; Reconnect/restart had no effect; 0 server processes.
  • Recovery: closed Cursor completely, ran reset (backup created automatically at %USERPROFILE%.cursor_mcp_state_backup_20260612-170456).
  • After relaunch: mcp-reanimate.cmd health → “ALL OK - all stdio servers enabled and running”.

Note: during this reset run the oauth-attempt cache folders were already absent ([skip]), so the wedge may have cleared on a prior attempt or the host recovered after a clean restart. The manual paths in Steps to Reproduce remain the documented fix when those folders ARE present.

If a future Cursor version moves internal paths, reset reports [skip] for missing folders — no harm done.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hi @Tarrimar!

This looks a lot like this report over here.

Do you also see ipcReady wait failed in your main process logs?

Yes — same signature here, and for me the trigger is reproducible: it’s the first launch after a Cursor update. I’ve now hit it on two consecutive updates.

Most recent one, fully observed end to end (3.7.36): the first launch after the update left MCP dead — every server on Error, including local stdio ones that use no OAuth and no network. main.log repeated the same signature you posted:

[McpProcess] ipcReady wait failed; entryPoint=vs/code/electron-utility/mcpProcess/mcpProcessMain

waitingFor=ipcReady lastPhase= lastMessage=

coldStartTimeoutMs=10000 elapsedMs=10032

[McpProcess] timed out waiting for ipcReady after 10000ms

[McpProcess] whenReady rejected, dropping window connection

[McpProcess] initial main connect failed

For that session the exthost MCP Logs.log was 0 bytes — the host never even spawned. I fully closed Cursor, ran a small recovery script (it backs up first, then clears regenerable MCP state — in this run it removed one stale OAuth-attempt record) and relaunched. After relaunch every server, stdio included, came back immediately and ipcReady stopped firing.

The previous update (→3.7.27) began the exact same way: the prior 3.7.21 launch was clean, and the first launch on 3.7.27 wedged with the identical ipcReady signature. I’m deliberately not describing how I recovered that one — I don’t have a clean enough record of the restart/reset steps to attribute it, so I’d rather leave it out than guess.

One honest correction to my own original post: I framed stale OAuth state as the confirmed root cause, but the fuller picture doesn’t support that strongly. In the 3.7.36 recovery an OAuth-attempt record was present and got cleared — but the same step also fully restarts Cursor, so I can’t separate the OAuth cleanup from the clean restart. I run 8 MCP servers (5 stdio + 3 OAuth/HTTP), which fits the “more servers → more likely to hit the 10s cold-start timeout” note in the linked thread.

So I think you’re right that this is the same MCP-host IPC-handshake issue, not a per-config problem. The cleanest description for me: an app update forces a relaunch, the host loses the cold-start IPC handshake within 10s, and every server drops — recovered by a full close + relaunch. I’m not claiming the root cause; that’s internal to Cursor.

I can confirm it works for me with the latest Cursor version. No action was required from my side.

Version: 3.7.36 (user setup)
VS Code Extension API: 1.105.1
Commit: 776d1f9d76df50a4e0aeca61819a88e7c1b861e0
Date: 2026-06-13T00:31:56.287Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26100

I am on the latest Cursor version but still MCPs failing to start. Tried reloading windows multiple times but no help.

Version: 3.7.42 (system setup)
VS Code Extension API: 1.105.1
Commit: 5702c9cfca656d8710fad58402fe37f14345e3a0
Date: 2026-06-15T19:39:42.738Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

I am on the latest Cursor version but still MCPs failing to start. Tried reloading windows multiple times but no help.

Version: 3.7.42 (user setup)
VS Code Extension API: 1.105.1
Commit: 5702c9cfca656d8710fad58402fe37f14345e3a0
Date: 2026-06-15T19:39:42.738Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

I am having the same issues today and on cursor version 3.7.42. I have two MCPs setup, and one of them is connecting to a local SQL server. If I leave both disabled and then enable one of them, it still fails. Once in a while if kill everything and reload the IDE, then wait for a while to try and enable the MCP it will connect. I have burned a lot of cursor credits trying to have cursor look into the issue :frowning:

Same on my Apple Silicon MacBook. Latest versions.

[error] [MCPService] [MCPService] Error creating client: Failed to acquire MessagePort for response channel ‘vscode:createMcpProcessChannelConnectionResult’

All of my MCP servers (Maven, file, database, git etc.) cannot connect in Cursor, they throw the identical error repeatedly: Failed to acquire MessagePort for response channel 'vscode:createMcpProcessChannelConnectionResult'

What I tested:

  1. Only keep one single MCP server in mcp.json, remove all others, error still exists.
  2. Run MCP startup command manually in terminal, every server runs stable without crash.
  3. Killed all cursor, node, java background processes, cleared Cursor global storage cache.
  4. Created empty workspace with minimal MCP config, no extra extensions.
  5. Windows 11, Cursor latest version.

My question:

Since every MCP hits the same MessagePort error, this should be an internal Cursor Electron communication bug instead of wrong MCP config. Is there any known fix or compatible version for this issue?

Did you try deleting logs: MCP fails to start — utility process never reaches `ipcReady` (Windows) - #15 by Stanislav_Kostomakha ?