microsoft/autogen · error · Error

Failed to list MCP tools

Error message

Failed to list MCP tools

What it means

Thrown by McpAPI.listTools when the POST to /mcp/tools/list returns a non-2xx status. The server response body is parsed as JSON and its message field is surfaced; the literal string 'Failed to list MCP tools' only appears when the body has no message field (e.g. empty or HTML error body). This is a plain fetch wrapper with no timeout, no retry, and no check for network-vs-HTTP failure.

Source

Thrown at python/packages/autogen-studio/frontend/src/components/views/mcp/api.ts:209

    const data = await response.json();
    if (!response.ok) {
      throw new Error(data.message || "Failed to get MCP capabilities");
    }

    return data;
  }

  async listTools(serverParams: McpServerParams): Promise<ListToolsResponse> {
    const response = await fetch(`${this.getBaseUrl()}/mcp/tools/list`, {
      method: "POST",
      headers: this.getHeaders(),
      body: JSON.stringify({ server_params: serverParams }),
    });

    const data = await response.json();
    if (!response.ok) {
      throw new Error(data.message || "Failed to list MCP tools");
    }

    return data;
  }

  async callTool(
    serverParams: McpServerParams,
    toolName: string,
    toolArguments: Record<string, any>
  ): Promise<CallToolResponse> {
    const response = await fetch(`${this.getBaseUrl()}/mcp/tools/call`, {
      method: "POST",
      headers: this.getHeaders(),
      body: JSON.stringify({
        server_params: serverParams,
        tool_name: toolName,
        arguments: toolArguments,
      }),

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Check the browser Network tab for the actual status code and response body of the POST to /mcp/tools/list — the body's message field names the real cause
  2. Validate server_params before calling: for stdio ensure command is on the backend PATH; for SSE/HTTP ensure the URL is reachable from the backend process, not the browser
  3. Verify the Authorization header is present and the token valid (clear localStorage auth_token and re-login if 401)
  4. Confirm the backend actually mounts the /mcp/tools/list route (curl POST it directly against the backend port)
  5. If data.message is empty because the body is HTML, log await response.text() instead of relying on response.json()

Example fix

// before
const data = await response.json();
if (!response.ok) {
  throw new Error(data.message || "Failed to list MCP tools");
}
// after
const text = await response.text();
let data: any = {};
try { data = JSON.parse(text); } catch { /* HTML/plain error body */ }
if (!response.ok) {
  throw new Error(data.message || `Failed to list MCP tools (HTTP ${response.status}): ${text.slice(0, 200)}`);
}
Defensive patterns

Strategy: validation

Validate before calling

function hasValidServerParams(p: McpServerParams): boolean {
  if (!p || typeof p !== "object") return false;
  if ((p as any).command != null) {
    return typeof (p as any).command === "string" && (p as any).command.length > 0;
  }
  if ((p as any).url != null) {
    try { new URL((p as any).url); return true; } catch { return false; }
  }
  return false;
}

Type guard

function isStdioParams(p: McpServerParams): p is McpServerParams & { command: string; args?: string[] } {
  return typeof (p as any).command === "string";
}

Try / catch

try {
  const res = await mcpAPI.listTools(serverParams);
  return res.data?.tools ?? [];
} catch (e) {
  reportError(e instanceof Error ? e.message : String(e), { scope: "mcp.listTools" });
  return []; // treat as no tools; never surface raw error to render tree
}

Prevention

When it happens

Trigger: POST {base}/mcp/tools/list with {server_params} returning 4xx/5xx: invalid server_params (bad command, missing env vars for a stdio server), unreachable SSE/HTTP MCP server URL, unauthenticated request (missing/expired Bearer token so the backend returns 401/403), or the backend MCP route not mounted.

Common situations: Misconfigured stdio server_params (wrong command path), MCP server URL not reachable from the backend container, running frontend against a backend on a different port without the /api proxy forwarding /mcp, expired auth_token in localStorage, backend version where the /mcp route is not registered.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/7042bb0c3770eeab. Report an issue: GitHub.