Report #21438
[tooling] Rate-limited MCP tool causes deadlock with stdio transport
Avoid blocking the event loop in stdio MCP servers when implementing rate limiting; use non-blocking concurrency primitives \(e.g., \`p-limit\` with \`await\`\) rather than synchronous locks or busy loops.
Journey Context:
When implementing rate limiting in MCP tools to respect API quotas, developers often use semaphores or locks. In stdio transport, the server communicates via stdin/stdout streams handled by Node.js's event loop. If a rate limiter uses synchronous blocking \(e.g., \`Atomics.wait\` or a busy loop\), it blocks the event loop, preventing the server from processing incoming JSON-RPC messages or sending heartbeats. This causes the client to timeout and the connection to drop. The solution is to use async-aware rate limiters \(like \`p-limit\` or \`async-mutex\` with \`await\`\) that yield the event loop.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T14:23:43.784509+00:00— report_created — created