fix(mcp): classify unresolvable and egress-refused server URLs in discovery
Merged
WA
6d ago+50+50+01234567890123456789-6-6-0123456789
Summary
- An MCP server whose hostname no longer resolves (e.g. an expired tunnel URL) made
/api/mcp/tools/discoveranswer 500 and log at error:McpDnsResolutionErrorfrom the SSRF pre-check fell throughisMcpServerUnavailableErrorandcategorizeError isMcpServerUnavailableErrornow treats it as server-unavailable: discover answers 422 + warn, v2GET /api/v2/mcp-servers/{id}/toolsanswers its documented 503categorizeErrormaps it to 502 (Server hostname could not be resolved) andMcpSsrfError/McpDomainNotAllowedErrorto 403, matching test-connection and server lifecycle; reaches discover refresh,servers/[id]/refresh, and MCP tool execution- Messages stay generic constants; no hostname or address reaches the caller. Failure status, negative cache, and the discovery retry predicate are unchanged (they never keyed on these helpers)
Type of Change
- Bug fix
Testing
- Regression cases in
discover/route.test.ts(DNS → 422, SSRF and domain refusal → 403) andv2/mcp-servers/[mcpServerId]/tools/route.test.ts(DNS → 503); all four fail on the pre-fix code (500) and pass with the fix - Targeted vitest:
app/api/mcp/tools,app/api/mcp/servers/[id]/refresh,app/api/v2/mcp-servers,lib/internal/mcp,lib/mcp/utils.test.ts - biome,
check:api-validation:strict,check:comment-hygiene,check:test-patterns; full suite, type-check, and audits run in CI
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing (new tests pass the
test-auditauthoring gate) - No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)