Define and validate arguments for MCP prompts
Define each prompt argument with a stable name, a useful description, and an explicit required flag. On every prompts/get call, validate the final argument map before rendering. Completion may suggest valid values and improve data entry, but direct callers can bypass it, so it cannot enforce the prompt’s contract.
Prerequisites
Your server needs a prompt template and a clear contract for every value inserted into it: which values must be present, which may be omitted, and what makes a supplied string acceptable. If the server exposes prompts, it must declare the prompts capability during initialization. Treat that declaration as part of capability negotiation between MCP clients and servers, not as proof that any particular client will render your preferred form.
Steps
-
Describe the arguments in the prompt definition
Return an
argumentsarray with the prompt fromprompts/list. The MCP prompt specification dated 2025-11-25 defines prompts as user-controlled templates that clients can list and retrieve. Each argument has a programmaticname, an optional human-readabledescription, and an optionalrequiredflag.In practice, supply all three. The name gives the client the key it must place in
params.arguments. The description tells the user what value belongs under that key. The required flag tells the client whether it should collect a value before requesting the prompt. Without those fields, a client may still invoke the prompt, but it has less information for building a useful entry form.{ "name": "review_deployment", "description": "Review a deployment against its target environment", "arguments": [ { "name": "environment", "description": "Target environment, such as staging or production", "required": true }, { "name": "service", "description": "Service to focus on; omit to review the whole deployment", "required": false } ] }Keep names stable once clients depend on them. A renamed argument is a changed request contract even if the visible description remains the same. Descriptions should state the condition the value must satisfy, not merely repeat the name.
-
Make requiredness match the template’s real dependency
Mark an argument required when the server cannot produce the intended prompt without it. Leave it optional only when the renderer has defined behaviour for its absence. Do not mark a value optional because one client happens to remember or prefill it.
The 2025-11-25 MCP schema reference makes
PromptArgument.namemandatory whiledescriptionandrequiredare optional. It also definesGetPromptRequestParams.argumentsas an optional map whose values are strings. That wire-level shape does not express application rules such as an allowed set of environment names, a maximum useful length, or whether an empty string is acceptable. Record those rules in the server’s validation logic.There is a concrete tradeoff. Requiring too much makes clients collect values that the renderer could have defaulted or omitted. Requiring too little moves failure from data entry into prompt rendering, where the error is harder to explain. The right test is whether omission has an intentional result.
-
Validate the final
prompts/getrequest on the serverRun validation when the server receives
prompts/get, before interpolating values or reading resources selected by those values. Prompt metadata helps a client collect arguments; it is not an enforcement boundary. MCP does not require clients to use a server’s preferred user interface, and a client can construct the JSON-RPC request directly.At minimum, validation should check the prompt name, the presence of every required argument, and every value constraint on which the renderer relies. Decide explicitly how the server handles undeclared argument names and empty strings. The protocol specifies
-32602(Invalid params) for an invalid prompt name or missing required arguments; internal failures use-32603instead. A caller error should not be disguised as a rendering failure.function validateReviewDeployment(args: Record<string, string> | undefined) { if (!args || !args.environment) { throw invalidParams('environment is required') } const environments = new Set(['staging', 'production']) if (!environments.has(args.environment)) { throw invalidParams('environment must be staging or production') } return { environment: args.environment, service: args.service } }The allowed values in this example belong to the example server, not to MCP. The important mechanism is that the server owns the rule and applies it to the received map. Client-side checks can reduce mistakes, but they cannot protect the renderer from another client, a script, or an older cached interface.
-
Render only from validated values
Pass the validator’s result—not the original request object—to the prompt renderer. This creates a narrow boundary: request parsing produces untrusted strings, validation produces the values the template is allowed to use, and rendering produces the returned prompt messages.
Do not let a fallback silently contradict the advertised required flag. If
environmentis required, substitutingproductionwhen it is absent makes the published contract false and can produce a materially different prompt from the one the caller requested. If a default is legitimate, make the argument optional and define that default as part of the server’s behaviour.Validation also has to happen before an argument selects a server-side resource. The prompt specification requires implementations to validate inputs and outputs to prevent injection or unauthorized resource access. A descriptive argument field cannot constrain what a direct caller sends.
-
Add completion only where suggestions improve entry
If an argument has a discoverable or context-dependent value set, support
completion/completeand declare thecompletionscapability. The MCP completion specification dated 2025-11-25 lets a client send a prompt reference, an argument name, and the value typed so far. For prompts with several arguments, the client can also include previously resolved arguments as context.Completion is useful for values such as a service name filtered by the selected environment. It can rank suggestions and return up to 100 values, with optional
totalandhasMorefields. Implement the full interaction as argument completion for MCP prompts and resource templates when users would otherwise need to recall identifiers exactly.Do not add completion to a free-text field merely to duplicate its description. It creates extra requests, rate-limiting work, and another input surface to validate without narrowing the final contract.
-
Keep completion and final validation separate
Validate inputs to
completion/complete, including the prompt reference, argument name, partial value, and any contextual arguments. Suggestions can expose sensitive identifiers if access checks are weaker on completion than onprompts/get.Then validate the completed value again when it arrives in
prompts/get. A completion response is a suggestion, not a reservation or proof. The underlying data may change between the two requests, the user may edit a suggested value, and the client may skip completion entirely. Argument completion can improve entry, but it does not replace validation of the final get request. -
Test through the protocol boundary
Exercise
prompts/getdirectly rather than testing only through the client interface you expect users to see. Cover a valid request, each missing required argument, each rejected value class, omission of every optional argument, and the server’s chosen treatment of undeclared names. Verify that caller errors return-32602and that invalid values never reach rendering.If completion is enabled, test it separately with partial and contextual values. Also send a valid final value without calling completion first. That last case proves the server accepts protocol-valid direct callers while still enforcing its own prompt contract.
Expected result
A completed implementation advertises named, described, explicitly required or optional prompt arguments; clients can collect values from that metadata; and every prompts/get request is validated before rendering. Completion may make valid values easier to enter, while the server remains the authority that accepts or rejects the final argument map.
Sources
- MCP prompt specification dated 2025-11-25modelcontextprotocol.io
- 2025-11-25 MCP schema referencemodelcontextprotocol.io
- MCP completion specification dated 2025-11-25modelcontextprotocol.io
See also
How MCP clients discover server-provided prompts, supply arguments, and receive role-tagged messages without invoking tools or selecting context.
Trace initialization, verify the HTTP version header, and stop cleanly when client and server share no supported MCP protocol version.
Implement bidirectional MCP cancellation, stop costly work, suppress cancelled responses, and handle completion races without protocol errors.
Negotiate support, reread resources after update notifications, and remove subscription state when interest or the MCP session ends.