Chapter 17

Model Extra Input and Long Work Explicitly

Modern MCP distinguishes two kinds of "incompleteness". When an operation lacks data, it uses resultType: input_required - a Multi Round-Trip Request. When the work is genuinely long and asynchronous, it's moved into the official tasks extension. Both mechanisms look, on the outside, like the A2A lifecycle, but they stay a capability-oriented contract, not a delegation.

The Multi Round-Trip round itself is a short sequence.

  1. tools/call
  2. input_required
  3. User input
  4. Retry (new id)
  5. Result

The server signals that it needs input with a separate result that describes the shape of that input.

JSON
{
  "jsonrpc": "2.0",
  "id": 20,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "approval": {
        "method": "elicitation/create",
        "params": {
          "mode": "form",
          "message": "Confirm the release window",
          "requestedSchema": {
            "type": "object",
            "properties": {
              "window": {
                "type": "string"
              }
            },
            "required": [
              "window"
            ]
          }
        }
      }
    },
    "requestState": "opaque-signed-state"
  }
}

The client completes the original operation with the user's answer and repeats it - now with a new JSON-RPC id.

JSON
{
  "jsonrpc": "2.0",
  "id": 21,
  "method": "tools/call",
  "params": {
    "name": "schedule_release",
    "arguments": {
      "service": "web-portal"
    },
    "inputResponses": {
      "approval": {
        "action": "accept",
        "content": {
          "window": "2026-08-02T02:00:00Z"
        }
      }
    },
    "requestState": "opaque-signed-state",
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28"
    }
  }
}

This cycle has a few invariants whose violation breaks security.

  • The retry gets a new JSON-RPC id.
  • requestState is opaque to the client, tied to the original arguments, and protected from tampering.
  • The client declares supported input modes in its capabilities.
  • A user's refusal is a normal outcome, not an infrastructure error.
  • Don't request a password or a long-lived secret through an arbitrary form.

The tasks extension is needed when a capability starts work that must be polled, updated, or continued after a request breaks. But here runs an important boundary: if the public contract is already a delegation to an independent agent with an Agent Card, multimodal messages, and artifacts - it's probably more honest to express that boundary through A2A than to stretch MCP tasks over it.

Don't copy the old sampling flow. Roots, sampling, and the former server-initiated patterns are marked deprecated in 2026-07-28. Check the deprecated registry and the migration guide before implementing client capabilities - otherwise you risk building on what's already leaving.

The remote MCP functionality is assembled. Before releasing it to the network, we need to close the main question - who is allowed to do what.

Links