Describe the Bug
When using a custom MCP server launched via stdio on macOS, Cursor consistently logs “No server info found” during the ListOfferings phase, even though the server successfully receives and replies to the initialize request with the correct protocol version and response format. This appears to be a race condition or timing issue with how Cursor handles the MCP lifecycle.
Steps to Reproduce
- Create a stdio-based MCP server (e.g. Node.js script listening to stdin, writing to stdout with JSON-RPC).
- Return a valid
initializeresponse including:protocolVersion: “2025-03-26”serverInfo,capabilities,sessionId
- Add the MCP config to
.cursor/mcp.jsonusingtype: "stdio"with a command or wrapper script. - Open Cursor and allow it to auto-load the MCP.
Expected sequence:
- Cursor calls
initialize - MCP responds successfully
- Cursor calls
ListOfferings
What actually happens:
- Cursor calls
initialize - MCP responds correctly
- Cursor immediately logs “No server info found”, closes the process, and
ListOfferingsnever reaches the MCP server.
Expected Behavior
Cursor should wait until a successful response from initialize before attempting any tool-related methods like ListOfferings.
After a valid initialize response is received, Cursor should retain the MCP session context and proceed with tool listing.
Screenshots / Screen Recordings
Operating System
MacOS
Current Cursor Version (Menu → About Cursor → Copy)
Version: 1.1.6 (Universal)
VSCode Version: 1.96.2
Commit: 5b19bac7a947f54e4caa3eb7e4c5fbf832389850
Date: 2025-06-25T02:16:57.571Z
Electron: 34.5.1
Chromium: 132.0.6834.210
Node.js: 20.19.0
V8: 13.2.152.41-electron.0
OS: Darwin arm64 24.5.0
Additional Information
Tested manually using:
echo '{"jsonrpc":"2.0","method":"initialize","id":0,"params":{}}' | node stdio-bridge.js
→ MCP replies correctly with full JSON-RPC payload and protocol version
Confirmed output includes:
"protocolVersion": "2025-03-26""serverInfo"with name/version"capabilities.tools": true- Proper
idecho - JSON-RPC 2.0 formatting with newline separation
We’ve also implemented the following extensive debugging strategies:
- Delayed all non-initialize methods using a queue until after
initializewas received and parsed. - Cached the
serverInforesponse to ensure it was available to all follow-up methods. - Deliberately added
setTimeout()before flushing responses to simulate async safety. - Used
stdout.write(..., callback)with flush logic to avoid premature stream closure. - Wrapped the MCP startup in a shell script (
mcp-wrapper.sh) for stability. - Tried all known transport types:
stdio,http,sse,sdr— all failed at the same place. - Injected verbose logs on every inbound and outbound message, including timestamps and payloads.
All tests work perfectly when run manually.
Only Cursor’s internal MCP lifecycle fails — logs show it immediately discards the MCP client right after initialize, and proceeds to ListOfferings with no context, logging:
[info] user-sqlserver: Handling ListOfferings action
[error] user-sqlserver: No server info found
We are confident this is not a bug in our MCP logic — the problem seems to be how Cursor launches and wires stdio MCPs, possibly before the connection is ready or before the process fully initializes.
Does this stop you from using Cursor
Yes - Cursor is unusable
