In MCP, how does completion/complete autocomplete a prompt argument value?
answer
- fills the gap left by a schemaless argument
- tagged reference says which thing
- what you typed so far goes in the request
- a hundred, and no cursor to go further
basics
~20 sThe client sends completion/complete with a ref of type ref/prompt naming the prompt, plus the argument name and the partial value typed so far. The server replies with a completion object holding up to 100 candidate values and optional total and hasMore fields.
solid answer
~50 s`completion/complete` is how a host offers a picker instead of a bare text box for a prompt argument. The request carries a `ref` — for prompts, `{ "type": "ref/prompt", "name": "<prompt name>" }` — an `argument` object with the argument's `name` and the partial `value` the user has typed, and optionally a `context.arguments` map of values already resolved for other arguments, so a server can narrow later suggestions by earlier choices. The result is a `completion` object with `values`, a string array **capped at 100 entries**, plus optional `total` (how many matches exist) and `hasMore` (whether more exist beyond what was returned). There is no cursor: completions are not paginated, so a user narrows the list by typing more rather than by paging. Servers that support this declare a `completions` capability; a client that sees none simply renders a free-text field. The same endpoint also completes resource-template variables via a `ref/resource` reference.
code
json · 14 lines{
"jsonrpc": "2.0",
"id": 31,
"method": "completion/complete",
"params": {
"ref": { "type": "ref/prompt", "name": "review_diff" },
"argument": { "name": "branch", "value": "rel" },
"context": { "arguments": { "repo": "katajob/backend" } },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}go deeper
Know that MCP has a dedicated endpoint for suggesting values as a user types a prompt argument, and that it returns a plain list of candidate strings rather than validating the input.
Describe the request precisely: a ref tagged ref/prompt with the prompt name, the argument name plus the partial value, and the result's values array with its 100-entry cap alongside total and hasMore.
Show operational thinking: rank candidates because there is no cursor to page past the cap, debounce and cancel per-keystroke calls, scope suggestions to the request's authorization, and rate-limit an endpoint that fires on every keypress.
Weigh whether server-side completion is worth its cost at all for your deployment — it adds a hot, enumeration-shaped endpoint to your attack and load surface — versus shipping coarser prompts whose arguments need no picker.
## Why the endpoint exists A `PromptArgument` declares only a name, optional display text and a `required` flag — no enum, no type, no allowed-values list. That keeps the declaration simple, but it leaves a host with nothing better than a free-text box to render. `completion/complete` fills that gap at request time: the client asks the server, as the user types, what values would be legal here. This is an IDE-style completion protocol rather than a validation protocol. Nothing forces the user to pick a returned value, and nothing obliges a server to reject a value it never suggested. Completion improves the interaction; `prompts/get` still validates. ## The request Three parts matter: - **`ref`** — which thing is being completed. For a prompt argument it is `{ "type": "ref/prompt", "name": "..." }`, where `name` is the prompt's programmatic name from `prompts/list`. The same endpoint serves resource templates through `{ "type": "ref/resource", "uri": "..." }`, which is why the reference is tagged at all. - **`argument`** — `{ "name": "...", "value": "..." }`: which argument, and the partial text typed so far. An empty `value` is legitimate and asks for the unfiltered head of the list. - **`context.arguments`** — optional, a map of other argument values the user has already chosen. This is what lets a repository argument narrow the branch suggestions that follow, and it exists precisely because the protocol is stateless: the server cannot remember what the user picked a moment ago, so the client must resend it. ## The result and the 100-value cap The result is a single `completion` object: - `values` — the candidate strings, **at most 100 per response**. - `total` — optional, the total number of matches the server knows about. - `hasMore` — optional, whether more matches exist beyond `values`. The cap is a hard ceiling on one response, and there is deliberately no continuation cursor. A server with ten thousand matching branch names returns its best hundred and sets `hasMore` to `true`; the user narrows by typing more characters. That design keeps the endpoint cheap enough to call on every keystroke, which is how hosts actually use it — usually with client-side debouncing, and with the previous in-flight request cancelled when the user types again. Because there is no paging, **ranking matters**. The server chooses what lands in those hundred values, so the most relevant candidates should come first. A server that returns an arbitrary hundred of ten thousand matches is technically conformant and practically useless. ## Capability and negotiation Support is advertised through the server's `completions` capability, which under revision 2026-07-28 appears in the capabilities the server reports from `server/discover` — the method that took over the role the removed `initialize` handshake used to play. A client that does not see the capability should not call the endpoint, and should render a plain input. Conversely, a server MUST NOT infer anything from earlier requests on the same connection: each `completion/complete` is self-contained and carries its own `_meta` with `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities`. ## Security and cost considerations Completion values are computed by the server and shown to a human, and they can leak. If the argument is a customer identifier or a file path, the returned candidates disclose what exists — so the set a server returns should be scoped to whatever authorization the request presented, exactly as a listing would be. The endpoint is also a rate-limiting target: it is called per keystroke, so a server that runs an expensive query per call will fall over under a fast typist long before its real workload does. ## Common mistakes Thinking the cap paginates — it does not; there is no cursor. Thinking completion enforces the value — it does not; it suggests. Thinking the server remembers the user's earlier choices — it does not; `context.arguments` is how they are resupplied. And confusing `ref/prompt` with `ref/resource`: the first names a prompt, the second a resource URI or template.
- If a server has thousands of matching values, how does the client see the ones past the first hundred?It does not page — there is no cursor on a completion result. The server returns at most 100 values and may set hasMore true and total to the real count; the user narrows by typing more characters, which produces a new completion/complete with a longer partial value. That puts the burden of ranking on the server.
- How can suggestions for one argument depend on the value already chosen for another?Through the optional context.arguments map in the request, which carries values the user has already resolved. Since MCP at 2026-07-28 is stateless and a server MUST NOT rely on prior requests over the same connection, the client resends those values on every call rather than expecting the server to remember them.
saying these in an interview costs you the question
- Believing the 100-value cap is a page size with a cursor
- Treating completion values as enforced validation of the argument
- Expecting the server to remember previously chosen arguments
- Calling completion/complete without checking the completions capability
- Confusing ref/prompt with ref/resource in the request