- Synchronous (
POST /agents/conversations/{id}/runs): HTTP 400 RFC 7807 withtypeURL pointing to this page. Triggered bytool_choice: { kind: "specific_tool", mcp_alias: "...", name: "..." }— the platform does a targetedtools/listagainst 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: failedwitherror.type = "AgentLoopMcpDiscoveryFailed". Triggered at workflow start when the load activity fans out onetools/listper 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’stools/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 themcp_servers[]entry has noconnection_id. - The MCP server host resolves to a blocked address — loopback, private, link-local
(including the
169.254.169.254metadata 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
A401 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_idIf 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-connectionsConnect 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 $URLwith 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
initializeandtools/listper the Model Context Protocol wire spec. - If the MCP server is permanently down, drop the entry from
mcp_servers(or override the conversation defaults viaconfig_override.mcp_serverson the affected run) — the agent loop can’t proceed without a working catalog for every registered server.
See also
tool_choicereference — 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.

