Skip to main content
HTTP / status: Surfaces on two paths.
  • Synchronous (POST /agents/conversations/{id}/runs): HTTP 400 RFC 7807 with type URL pointing to this page. Triggered by tool_choice: { kind: "specific_tool", mcp_alias: "...", name: "..." } — the platform does a targeted tools/list against the named server to confirm the tool exists before accepting the run. The 400 (not 5xx) reflects that the failure is caller-actionable: the MCP server you registered isn’t responding, and fixing it is on you.
  • Asynchronous (run-time): the run lands in status: failed with error.type = "AgentLoopMcpDiscoveryFailed". Triggered at workflow start when the load activity fans out one tools/list per registered MCP server to build the inference catalog.

When this error occurs

The Agent Conversations API doesn’t keep a cached MCP catalog. Every run rediscovers each registered server’s tools/list, and tool_choice with an mcp_alias re-discovers that single server synchronously. Common failure modes:
  • The MCP server URL is unreachable (DNS, firewall, TLS handshake failure).
  • The MCP server returns 5xx (transient outage or unhandled exception server-side).
  • The MCP server responds, but the body isn’t a well-formed JSON-RPC envelope.
  • The MCP server doesn’t implement tools/list (responds with -32601 method not found).
  • The MCP server requires authorization and responds 401, but the mcp_servers[] entry has no connection_id.
  • The MCP server host resolves to a blocked address — loopback, private, link-local (including the 169.254.169.254 metadata IP), IPv6 unique-local, unspecified, or multicast. The egress guard refuses the request to prevent SSRF against internal targets. The server must be publicly reachable on the internet.
URL syntax validation (absolute https URL with a host) happens up front at conversation/run create — a malformed or non-https URL is rejected there with Invalid MCP Server URL, not here.

Server requires authorization

A 401 is reported as an authorization problem, not a generic discovery failure. The detail tells you how to connect the server:
MCP server requires authorization: connect it via POST /mcp-connections and set connection_id
If you have already connected that server (a connection you own for the same URL), the detail names it so you can reference it directly:
MCP server requires authorization: reference your existing connection as connection_id, or (re)connect it via POST /mcp-connections
Connect an external server once via POST /mcp-connections, then set the returned id as connection_id on the mcp_servers[] entry — the platform resolves and refreshes that connection’s bearer server-side at call time. Servers that genuinely need no auth never hit this.

How to fix

  • Verify the MCP server URL is reachable from the platform’s outbound workers. For public servers, try curl -X POST $URL with a minimal initialize JSON-RPC body. For private/VPC-only servers, confirm the network path from the data plane.
  • Check the server’s logs for crashes or rate-limit errors around the failure timestamp.
  • Confirm the server exposes both initialize and tools/list per the Model Context Protocol wire spec.
  • If the MCP server is permanently down, drop the entry from mcp_servers (or override the conversation defaults via config_override.mcp_servers on the affected run) — the agent loop can’t proceed without a working catalog for every registered server.

See also

  • tool_choice reference — the API field that drives the synchronous discovery hop.
  • Unknown Tool Choice Name — discovery succeeded but the named tool wasn’t in the returned catalog.
  • Invalid MCP Server URL — the up-front 400 for a URL that fails syntax validation before it ever reaches discovery.
  • MCP Connections — how to attach an OAuth connection to an external MCP server that requires user authorization.