# AX-SYS-25: Ask for missing input instead of failing the call

> Orchestration and handoff · advanced · AX-SYS-25

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

```json
{
  "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. [MCP Specification 2026-07-28: Multi Round-Trip Requests](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr): 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. [MCP Specification 2026-07-28: Elicitation](https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation): Servers MUST NOT use form mode elicitation to request sensitive information such as passwords, API keys, access tokens, or payment credentials
3. [A2A Protocol Specification](https://github.com/a2aproject/A2A/blob/main/docs/specification.md): 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

---
Source: Agent Experience Principles (axprinciples.com)