Skip to content
AX Principles
AX-SYS-25Advanced

Ask for missing input instead of failing the call

Pide el dato que falta en lugar de hacer fallar la llamada

#all-industries#mcp#a2a

When a request is valid but incomplete, answer with exactly what you still need, in a small typed schema, and let the agent retry from where it stopped instead of starting over.

Why

Many requests fail for a reason that is not an error: the user did not say which of two accounts to use, a required choice is missing, or the action needs a confirmation. If the server answers with a generic 400, the attempt is over and the agent has to guess what went wrong, rebuild the request and hope. MCP's 2026-07-28 revision makes the alternative part of the protocol. With Multi Round-Trip Requests, a server returns an InputRequiredResult (resultType: "input_required") listing the inputs it needs, and the client retries the original request with the answers. If the answers are still incomplete, the specification says the server should ask again rather than return an error. The server can carry its progress in an opaque requestState that the client echoes back, so the retry does not depend on server memory; because that value passes through the client, the specification requires servers to treat it as attacker-controlled and to protect its integrity with an HMAC or AEAD when it affects authorization or business logic. A2A has the same idea at the task level: a task can stop in TASK_STATE_INPUT_REQUIRED or TASK_STATE_AUTH_REQUIRED and wait. One limit applies: this in-band channel is for choices and plain values, never secrets. MCP forbids servers from using form-mode elicitation to request passwords, API keys, access tokens or payment credentials.

Do

Return an input-required result that names each missing value with a schema, and sign any state you hand back to the client.

Don't

Turn a missing choice into an error that ends the attempt, or ask for a password or card number through this path.

Artifact

{
  "resultType": "input_required",
  "inputRequests": {
    "github_login": {
      "method": "elicitation/create",
      "params": {
        "mode": "form",
        "message": "Please provide your GitHub username",
        "requestedSchema": {
          "type": "object",
          "properties": { "name": { "type": "string" } },
          "required": ["name"]
        }
      }
    }
  },
  "requestState": "AEAD-protected blob"
}

The client retries the same tools/call with inputResponses ({"github_login": {"action": "accept", "content": {"name": "octocat"}}}) and the unchanged requestState.

Citations

  1. [01]
    MCP Specification 2026-07-28: Multi Round-Trip Requests ↗

    If the client fails to send all the information requested in a previous InputRequests, and the missing information is necessary for the server to process the request, the server SHOULD respond with a new InputRequiredResult requesting the missing information again, rather than returning an error. Servers MUST treat requestState as an attacker-controlled input and, if it influences authorization, resource access, or business logic, MUST protect its integrity (e.g. HMAC or AEAD)

  2. [02]
    MCP Specification 2026-07-28: Elicitation ↗

    Servers MUST NOT use form mode elicitation to request sensitive information such as passwords, API keys, access tokens, or payment credentials

  3. [03]
    A2A Protocol Specification ↗

    A blocking call waits until the task reaches a terminal state or an interrupted state (TASK_STATE_INPUT_REQUIRED, TASK_STATE_AUTH_REQUIRED) before returning