In MCP, what does the error -32021 MissingRequiredClientCapabilityError mean?
answer
- Well-formed metadata, insufficient declaration
- Named in the error, not guessed
- Per-request failure, nothing torn down
- data.requiredCapabilities tells the client what to add
- Specification-reserved -32020 to -32099 band
basics
~20 sError -32021 means the MCP server cannot serve the request without a client capability that the request's _meta never declared. Its data.requiredCapabilities lists exactly which capabilities the client would have to declare for the request to succeed.
solid answer
~50 sIn revision 2026-07-28 a client declares `io.modelcontextprotocol/clientCapabilities` on every request. `-32021` `MissingRequiredClientCapabilityError` is the server's way of saying the metadata was well-formed but insufficient: serving this particular call needs a capability the request did not declare — for example a tool that would have to come back asking the user a question when the request declared no elicitation support. The error's `data.requiredCapabilities` names what was missing, which makes it actionable rather than a bare failure. A client that actually has the capability can re-issue the same call with it declared in `_meta`; a client that does not must surface the failure. This is a per-request error, not a connection-level one — nothing is torn down, because there is no session to tear down. The code sits in the `-32020` to `-32099` band the specification reserves for itself.
go deeper
Know that -32021 is about the client's declared capabilities being insufficient for the request, and that the error names what was missing rather than leaving you to guess.
Draw the line between -32602 for a malformed _meta block and -32021 for a valid but insufficient declaration, and explain what a client does with data.requiredCapabilities.
Show the handling policy you would ship: classify it as retryable-with-changes, retry once with the capability declared if you truly support it, otherwise fail loudly with the server's list — never a blind retry loop.
Be ready to discuss where the capability check belongs in server design: gate before expensive work, keep requirements per request rather than per connection, and decide how much your platform exposes about why a call was refused.
## The problem it solves Since revision 2026-07-28, MCP has no handshake. A client states its capabilities in `io.modelcontextprotocol/clientCapabilities` inside `params._meta` on **every** request, and the server evaluates that declaration per request. That creates a failure mode the handshake era did not have in the same shape: a request can be perfectly well-formed and still be unservable, because the work the server would have to do requires something of the client that this request did not offer. `-32021` `MissingRequiredClientCapabilityError` is the error for exactly that case. ## Well-formed but insufficient It is worth separating three distinct failures, because interviewers like to see the distinction drawn cleanly: - **Malformed metadata** — a required `_meta` key such as `clientCapabilities` is absent entirely. That is `-32602` invalid params (HTTP 400 over Streamable HTTP). - **Well-formed but insufficient** — the capability object is present and valid, but does not contain what this request needs. That is `-32021`. - **Method does not exist** — `-32601`, with HTTP 404 on the HTTP transport. So `-32021` is not a schema-validation error. The client sent a legal declaration; it simply declared too little for what it then asked for. ## What the error carries The error's `data` object carries `requiredCapabilities`. That field is what makes the error useful: rather than the client guessing, the server names the capabilities the request would have needed. A client can compare that list against what it actually supports and decide, mechanically, whether a retry can possibly succeed. ## The client's options There are only two sensible reactions: 1. **The client does support the named capability but did not declare it on this call** — perhaps a code path built `_meta` from a narrower template, or the client suppresses interactive capabilities on background work. It re-issues the request with the capability declared. Because the request carries a new JSON-RPC id, this is an ordinary new request; nothing about the first attempt is remembered on the server. 2. **The client genuinely does not support it** — retrying is pointless. The right move is to surface the failure to the user or the calling agent with the server's `requiredCapabilities` in the message, so the human sees "this tool needs to be able to ask you questions and this client cannot". What is *not* a correct reaction is tearing down the transport. There is no session to reset, and reconnecting changes nothing: the next request would carry the same insufficient declaration. ## Why it exists in a stateless world Under the old handshake model a server learned client capabilities once and could refuse to expose incompatible functionality up front. Statelessness removes that vantage point — the server does not know, when it lists tools, what a future call will declare. So the check moves to call time, and the protocol needs a specific, machine-readable way to say "not with these capabilities". A generic invalid-params error would force clients to parse prose. A useful design consequence: capability requirements are a property of the *request*, not of the connection. The same client may legitimately declare interactive capabilities on a user-facing call and none at all on a background one, and the server evaluates each on its own terms. ## The reserved code band JSON-RPC leaves the `-32000` to `-32099` range to the application. MCP claims `-32020` through `-32099` for the specification itself, so implementations should not mint private errors in that band. Neighbouring specification codes include `-32020` for a header mismatch on the HTTP transport and `-32022` for an unsupported protocol revision. Grouping them makes the band easy to recognise: an error in the low `-320xx` range is the protocol talking, not the tool. ## Implementation guidance On the server side, check capability requirements before doing expensive work — you do not want to run half a tool and then discover the client cannot answer the question you need to ask. Populate `requiredCapabilities` accurately; a server that returns the error with an empty or vague `data` block gives the client nothing to act on. On the client side, treat `-32021` as a retryable-with-changes error in your error taxonomy, distinct from both hard failures and transient ones. Log the `requiredCapabilities` list, because in practice it is the fastest way to spot that some code path is building `_meta` incorrectly. And do not retry blindly in a loop: if the capability is one you do not implement, the second attempt will fail exactly like the first.
- How does -32021 differ from the -32602 a server returns for a malformed _meta block?`-32602` is a schema failure: a required key such as `clientCapabilities` is absent, so the request is invalid params (HTTP 400 on Streamable HTTP). `-32021` says the declaration was present and valid but did not include what this particular call needs. One is "you did not fill in the form", the other is "the form says no".
- Should a client tear down the connection after receiving -32021?No. It is a per-request error and there is no session to reset — reconnecting would send the same insufficient declaration again. The client either re-issues the request with the named capability declared in `_meta`, or reports the failure with `data.requiredCapabilities` so a human can see what the server needed.
- Why did this error become necessary once the handshake was removed?With a handshake the server learned capabilities once and could shape what it exposed. In revision 2026-07-28 it cannot know, at listing time, what a later call will declare, so the check moves to call time. A machine-readable error naming the missing capabilities lets the client react programmatically instead of parsing an error string.
saying these in an interview costs you the question
- Says -32021 means the server lacks a capability
- Treats it as a fatal connection-level error
- Confuses it with -32602 invalid params
- Retries the identical request unchanged in a loop
- Thinks capability requirements are fixed per connection