Skip to content

fix(mcp): treat server timeout as infra, not a diagnostic (#346)#348

Merged
fdaviddpt merged 2 commits into
masterfrom
fix/mcp-infra-timeout-not-diagnostic
Jun 26, 2026
Merged

fix(mcp): treat server timeout as infra, not a diagnostic (#346)#348
fdaviddpt merged 2 commits into
masterfrom
fix/mcp-infra-timeout-not-diagnostic

Conversation

@fdaviddpt

Copy link
Copy Markdown
Contributor

Problem

After an edit, lsp-diag reported a 0 → 1 count where the single "diag" was actually orchestrator timeout after 3s — an infrastructure condition, not a code finding (phpstan already covered the same file clean). It read like the edit introduced a regression.

Root cause

cclsp swallows its internal LSP-orchestrator timeout and hands it back as a normal MCP text result with the isError flag unset. So it flowed through the shared dispatch as a real result, and the lsp-diag adapter counted it as a +1 advisory. This is not our MCPTimeout exception path (that was already prefix-guarded).

Fix

Detection moved to the shared _mcp_call_or_message — so every MCP-backed op (diag/hover/rename) benefits, not just lsp-diag — with two signals:

  1. Structural — the MCP isError flag (spec-standard, any server, zero config).
  2. Textual — a configurable per-server infra_patterns substring list (default ["orchestrator timeout", "timed out", "timeout after"]) for servers that report timeouts as plain text.

A matched result is returned prefixed op: … — the same shape as supertool's own MCP errors — so the adapter's existing op:-prefix guard drops it instead of counting it. No count delta, no false regression. The timeout value stays per-server configurable via mcp.<name>.timeout (unchanged).

Tests

TestMcpInfraSkip — 8 pure-helper tests + 2 end-to-end via _stub_server (proved red → green). Full suite: 3480 passed, 34 skipped.

Docs

infra_patterns documented in both config-key lists in docs/mcp-integration.md; CHANGELOG.md Fixed entry.

Closes #346.

cclsp returns its internal LSP-orchestrator timeout ("orchestrator timeout
after 3s") as a normal MCP text result with isError unset, so it flowed
through dispatch as a real result and lsp-diag counted it as a phantom +1
diagnostic — reading like the edit caused a regression.

Detect infra conditions in the shared _mcp_call_or_message (covers
diag/hover/rename) via two signals: the structural MCP isError flag and a
configurable per-server infra_patterns list (default orchestrator timeout /
timed out / timeout after). Matched results are returned prefixed `op: …`
so the adapter's existing op-prefix guard drops them. No count delta.

Tests: TestMcpInfraSkip (8 pure + 2 end-to-end). Docs + CHANGELOG.

Co-Authored-By: Max <noreply>
Drop bare "timed out"/"timeout after" from the default infra_patterns —
they match against the whole diag result, so one real diagnostic containing
the phrase would drop every diagnostic in that result. Default is now
("orchestrator timeout", "timed out after") — both require word-pairing.
The cclsp bug is caught by "orchestrator timeout"; the daemon variant is
already handled by the exception path.

Also: chr(10) -> "\\n" for file convention, add an end-to-end test for the
structural isError path, sync the default list in docs + CHANGELOG.

Co-Authored-By: Max <noreply>
@fdaviddpt fdaviddpt merged commit 409bcff into master Jun 26, 2026
12 checks passed
@fdaviddpt fdaviddpt deleted the fix/mcp-infra-timeout-not-diagnostic branch June 26, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lsp-diag: don't surface orchestrator timeout as a diagnostic (+1)

1 participant