musistudio/claude-code-router · error · Error

MCP HTTP request failed (${this.server.name}): ${response.st

Error message

MCP HTTP request failed (${this.server.name}): ${response.status} ${text.slice(0, 300)}

What it means

Thrown when the underlying HTTP request to an MCP server completes but returns a non-2xx status. The message includes the server name, the HTTP status code, and up to 300 characters of the response body to aid diagnosis. This is the transport-level counterpart to the JSON-RPC error (error 200).

Source

Thrown at packages/core/src/mcp/toolhub-mcp.ts:1208

      if (apiKey && !headers.has("authorization")) {
        headers.set("authorization", `Bearer ${apiKey}`);
      }
      if (this.sessionId) {
        headers.set("mcp-session-id", this.sessionId);
      }
      const response = await fetch(this.server.url, {
        body: JSON.stringify(request),
        headers,
        method: "POST",
        signal: controller.signal
      });
      this.sessionId = response.headers.get("mcp-session-id") || response.headers.get("x-mcp-session-id") || this.sessionId;
      if (notification && response.status === 204) {
        return undefined;
      }
      const text = await response.text();
      if (!response.ok) {
        throw new Error(`MCP HTTP request failed (${this.server.name}): ${response.status} ${text.slice(0, 300)}`);
      }
      if (!text.trim()) {
        return undefined;
      }
      return parseHttpJsonRpcResponse(text);
    } finally {
      clearTimeout(timer);
    }
  }
}

class StdioMcpClient implements McpClient {
  private child: ChildProcessWithoutNullStreams | undefined;
  private initialized = false;
  private nextId = 1;
  private readonly pending = new Map<string, PendingRequest>();
  private stdoutBuffer = Buffer.alloc(0);

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Check the status code in the message: 401/403 → fix credentials; 404 → fix the endpoint URL; 5xx → server-side issue, retry later
  2. Read the sliced response body in the message for the server's own error detail
  3. Verify any session id is still valid; re-initialize to obtain a fresh mcp-session-id
  4. If behind a proxy, ensure it supports POST + SSE streaming to the MCP path

Example fix

// before
const client = new ToolHubMcpClient({ url: "https://mcp.example.com" });

// after
const client = new ToolHubMcpClient({ url: "https://mcp.example.com/mcp", headers: { Authorization: `Bearer ${token}` } });
Defensive patterns

Strategy: retry

Validate before calling

// Verify the endpoint is reachable and returns 2xx before wiring the client
const res = await fetch(new URL("/mcp", baseUrl), { method: "POST" });
if (res.status >= 400) throw new Error(`Bad MCP endpoint: ${res.status}`);

Type guard

const isHttpTransportError = (e: unknown): boolean =>
  e instanceof Error && e.message.includes("MCP HTTP request failed");

Try / catch

try {
  await client.callTool(name, args);
} catch (e) {
  if (isHttpTransportError(e) && /5\d\d|429/.test(e.message)) {
    await backoff(); await client.callTool(name, args); // retry transient
  } else throw e;
}

Prevention

When it happens

Trigger: The MCP HTTP endpoint returns 4xx/5xx: 404 wrong endpoint path, 401/403 missing or expired auth token, 400 malformed JSON-RPC body, 502/503 gateway unavailable, or a proxy rejecting the streamable-HTTP request.

Common situations: Misconfigured server URL (missing /mcp path suffix); expired API key or bearer token; MCP server behind a reverse proxy that buffers/blocks SSE; server restart mid-session with stale mcp-session-id; rate limiting from the provider.

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 musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/713ffd195e40f42b. Report an issue: GitHub.