Summary
perplexity_research (Sonar Deep Research) reliably hits MCP error -32001: Request timed out in MCP clients with sub-2-min request timeouts (observed in Claude Desktop at ~60–90s), even though PERPLEXITY_TIMEOUT_MS default is 300000ms.
Root cause is in src/server.ts: streaming is enabled for sonar-deep-research, but consumeSSEStream() accumulates the entire response in memory and only returns at end-of-stream. Nothing is sent to the MCP client until the whole thing finishes. From the client's perspective the tool call is a single silent RPC, and Claude Desktop's default MCP request timeout kills it long before the deep research completes (deep research routinely spends 60+ seconds in the search/reasoning phase before yielding tokens).
PERPLEXITY_TIMEOUT_MS only governs the server→API timeout. The blocker is client→server.
Reproduction
Client: Claude Desktop, MCP server installed via npx -y @perplexity-ai/mcp-server.
{
"tool": "perplexity_research",
"arguments": {
"messages": [{"role": "user", "content": "<any non-trivial research prompt>"}],
"reasoning_effort": "medium"
}
}
Result after ~1m30s:
MCP error -32001: Request timed out
Server log shows the API call still in flight server-side. Lowering reasoning_effort to minimal works because the call finishes inside the client window. That's a workaround, not a fix.
Fix
Per MCP spec, notifications/progress resets the client's request timeout. The streaming code path already has per-chunk granularity — it just needs to emit progress notifications as deltas arrive (and a periodic heartbeat during the initial silent search phase).
Working patch in src/server.ts:
- Add an optional
onProgress callback to consumeSSEStream(response, onProgress?) — called once per delta chunk, plus a 10s heartbeat when the stream is silent.
- Thread it through
performChatCompletion(..., onProgress?).
- In the
perplexity_research tool handler, read extra._meta.progressToken and extra.sendNotification. When both are present, emit:
await sendNotification({
method: "notifications/progress",
params: {
progressToken,
progress: counter,
message: `Deep research running… ${chunkCount} chunks, ${totalChars} chars streamed`,
},
});
This keeps the client's request timer alive for the full duration of the research call (validated locally — medium-effort runs that previously timed out now complete cleanly).
Same fix could optionally be applied to perplexity_reason (sonar-reasoning-pro) although that model typically finishes inside the default window.
Happy to open a PR with the patch if useful — concentrated in src/server.ts (~30 lines).
Environment
@perplexity-ai/mcp-server 0.9.0
- Claude Desktop 1.7196.0
- Node 20.20.2 on macOS
Related
https://community.perplexity.ai/t/perplexity-sonar-deep-research-model-timeout-issue-seeking-solution/2094 — same model, different layer (HTTP client side).
Summary
perplexity_research(Sonar Deep Research) reliably hitsMCP error -32001: Request timed outin MCP clients with sub-2-min request timeouts (observed in Claude Desktop at ~60–90s), even thoughPERPLEXITY_TIMEOUT_MSdefault is 300000ms.Root cause is in
src/server.ts: streaming is enabled forsonar-deep-research, butconsumeSSEStream()accumulates the entire response in memory and only returns at end-of-stream. Nothing is sent to the MCP client until the whole thing finishes. From the client's perspective the tool call is a single silent RPC, and Claude Desktop's default MCP request timeout kills it long before the deep research completes (deep research routinely spends 60+ seconds in the search/reasoning phase before yielding tokens).PERPLEXITY_TIMEOUT_MSonly governs the server→API timeout. The blocker is client→server.Reproduction
Client: Claude Desktop, MCP server installed via
npx -y @perplexity-ai/mcp-server.{ "tool": "perplexity_research", "arguments": { "messages": [{"role": "user", "content": "<any non-trivial research prompt>"}], "reasoning_effort": "medium" } }Result after ~1m30s:
Server log shows the API call still in flight server-side. Lowering
reasoning_efforttominimalworks because the call finishes inside the client window. That's a workaround, not a fix.Fix
Per MCP spec,
notifications/progressresets the client's request timeout. The streaming code path already has per-chunk granularity — it just needs to emit progress notifications as deltas arrive (and a periodic heartbeat during the initial silent search phase).Working patch in
src/server.ts:onProgresscallback toconsumeSSEStream(response, onProgress?)— called once per delta chunk, plus a 10s heartbeat when the stream is silent.performChatCompletion(..., onProgress?).perplexity_researchtool handler, readextra._meta.progressTokenandextra.sendNotification. When both are present, emit:This keeps the client's request timer alive for the full duration of the research call (validated locally —
medium-effort runs that previously timed out now complete cleanly).Same fix could optionally be applied to
perplexity_reason(sonar-reasoning-pro) although that model typically finishes inside the default window.Happy to open a PR with the patch if useful — concentrated in
src/server.ts(~30 lines).Environment
@perplexity-ai/mcp-server0.9.0Related
https://community.perplexity.ai/t/perplexity-sonar-deep-research-model-timeout-issue-seeking-solution/2094 — same model, different layer (HTTP client side).