can1357/oh-my-pi · error · Error

MCP request failed: ${response.status} ${response.statusText

Error message

MCP request failed: ${response.status} ${response.statusText}

What it means

callMCP() sends a JSON-RPC request (initialize, tools/list, tools/call, etc.) over HTTP/SSE to an MCP server and throws this error when the HTTP response status is not OK (response.ok false). The message carries the numeric status and statusText; the URL is redacted before logging. It surfaces transport-level problems before any JSON-RPC parsing happens.

Source

Thrown at packages/coding-agent/src/mcp/json-rpc.ts:106

		id: Math.random().toString(36).slice(2),
		method,
		params: params ?? {},
	};

	const response = await fetch(url, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
			Accept: "application/json, text/event-stream",
		},
		body: JSON.stringify(body),
		signal: options?.signal ?? AbortSignal.timeout(MCP_DEFAULT_TIMEOUT_MS),
	});

	if (!response.ok) {
		const errorMsg = `MCP request failed: ${response.status} ${response.statusText}`;
		logger.error(errorMsg, { url: redactUrlForLog(url), method, params });
		throw new Error(errorMsg);
	}

	const text = await response.text();
	const result = parseSSE(text) as JsonRpcResponse<T> | null;

	if (!result) {
		logger.error("Failed to parse MCP response", {
			url: redactUrlForLog(url),
			method,
			responseText: text.slice(0, 500),
		});
		throw new Error("Failed to parse MCP response");
	}

	return result;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the status code: 401/403 -> re-authenticate with /mcp reauth or re-run OAuth; 404 -> fix the URL; 429 -> back off and retry later; 5xx -> check server health.
  2. Verify the server's URL in the MCP config (correct host, port, and path).
  3. For OAuth servers, clear stale credentials and re-authorize.
  4. Retry transient statuses (429, 500, 502, 503) with exponential backoff.
  5. Check the omp log file for the logged request details (url is redacted, method and params included).

Example fix

// before
const tools = await manager.listTools("remote"); // throws on 401
// after
try {
  const tools = await manager.listTools("remote");
} catch (e) {
  if (e instanceof Error && e.message.includes("401")) {
    await reauthorizeServer("remote");
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight reachability check before relying on the server
const res = await fetch(serverUrl, { method: "HEAD", signal: AbortSignal.timeout(5000) });
if (!res.ok && res.status !== 405) throw new Error(`MCP endpoint unhealthy: ${res.status}`);

Type guard

function isTransientHttpFailure(message: string): boolean {
  return /MCP request failed: (429|500|502|503|504)\b/.test(message);
}

Try / catch

try {
  return await callMCP(url, method, params);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("MCP request failed:")) {
    if (isTransientHttpFailure(e.message)) return withRetry(() => callMCP(url, method, params));
    if (/MCP request failed: 40[13]/.test(e.message)) await reauthorize(url); // then retry once
  }
  throw e;
}

Prevention

When it happens

Trigger: Any callMCP() request to an http/sse MCP server where the server (or an intermediate proxy/gateway) returns a non-2xx status: 401/403 (missing or expired OAuth token), 404 (wrong path), 429 (rate limited), 5xx (server crash), or DNS/proxy errors surfaced as gateway responses.

Common situations: OAuth token expired and refresh hasn't run (401); server endpoint URL changed or includes a wrong base path (404); remote MCP provider rate-limiting (429); server down or deploying (502/503); corporate proxy rejecting the request.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/ffab4f872aa2e4d8. Report an issue: GitHub.