Prompts
Purpose and Scope
A prompt is a named message template that a connected MCP client invokes on behalf of a person. In this SDK, prompts are intentionally separate from tools: hosts usually surface prompts as slash commands, menu entries, or other direct user choices, while models select tools during a reasoning loop. That distinction affects how you design the server surface. A prompt should describe a reusable conversational starting point, gather any required arguments from the user, and return messages that a host can insert into the conversation without inventing additional template logic. Sources: docs/servers/prompts.md
Prompt registration is both a discovery contract and an execution contract. The discovery contract is what clients see through the prompt list: a stable name, display copy, and argument descriptions. The execution contract is the callback that receives validated argument values and returns the final message sequence. Treat these two parts as one product surface. If the metadata is vague, users will not know when to choose the prompt; if the callback returns ambiguous context, the model receives a weak starting point even though the protocol call succeeded. Sources: docs/servers/prompts.md
Relevant Source Files
docs/servers/prompts.md— primary guide for registering prompts, declaring prompt argument schemas, retrieving prompts with a client, validating invalid arguments, and returning message arrays.docs/servers/completion.md— explains server-side autocomplete for prompt arguments throughcompletable, including async suggestions and context from other arguments.docs/servers/elicitation.md— documents the older push-style user-input mechanism throughctx.mcpReq.elicitInput, which is relevant when comparing prompt argument collection with mid-call questions.docs/servers/errors.md— distinguishes tool-visible errors from protocol errors, which matters because prompt callbacks do not have a tool-styleisErrorresult channel.docs/servers/input-required.md— describes the newerinput_requiredresult shape forprompts/get,tools/call, andresources/readwhen a handler needs more user input mid-call.docs/servers/logging-progress-cancellation.md— documents request context helpers such as progress notifications, logging, request metadata, and cancellation behavior for long-running server handlers.
System-to-Code Mapping
The prompt lifecycle has three stages. First, the server registers a prompt with a stable protocol name and a configuration object. Second, a connected client lists prompts and renders the advertised metadata, including arguments derived from the schema. Third, when a person selects the prompt, the client requests that prompt by name with an arguments object, and the server executes the callback to materialize messages. The guide uses an in-memory client for examples, but the same call shape is what a real MCP host uses after someone chooses a prompt in its interface. Sources: docs/servers/prompts.md
This mapping is useful when debugging. If a prompt never appears in a host, focus on registration and list-time metadata. If the prompt appears but fails when selected, inspect the arguments sent to the server and the resulting protocol error. If the prompt succeeds but produces poor model behavior, revise the generated messages rather than treating the issue like a failed tool call. Prompt output is context, not an operational status result, so its quality depends on the clarity of the message roles, text, and sequencing. Sources: docs/servers/prompts.md, docs/servers/errors.md
Registering and Advertising Prompts
Register a prompt with server.registerPrompt(name, config, callback). The documented example creates a review server and registers a prompt named review-code with a title, description, and a Zod object for arguments. The argument schema contains a required code string, and its field description is preserved when the SDK converts the schema for prompt listing. That preservation matters because client interfaces can show the description beside the input field, making the schema part of the user experience rather than only a runtime validator. Sources: docs/servers/prompts.md
server.registerPrompt(
'review-code',
{
title: 'Code Review',
description: 'Review code for best practices and potential issues',
argsSchema: z.object({
code: z.string().describe('The code to review')
})
},
({ code }) => ({
messages: [
{
role: 'user' as const,
content: { type: 'text' as const, text: `Review this code: ${code}` }
}
]
})
);The registered name is the identifier clients send back later, so choose it for stability rather than presentation. The title and description can evolve as host-facing copy, but renaming the protocol identifier can break saved host configuration or documentation. The callback receives values that already passed schema validation, so most prompt code can focus on transforming those values into messages. In migrations from the earlier API, the guide states that registerPrompt replaces the older prompt() helper, making the new registration shape the v2 surface to use for fresh code. Sources: docs/servers/prompts.md
Retrieval and Validation Flow
Clients retrieve prompts with client.getPrompt({ name, arguments }). The server does not return an unfilled template for the client to render; it runs the registered callback and returns the resulting messages with the submitted arguments already incorporated. In the guide, retrieving the review prompt with a small code snippet returns a single user message that asks for a review of that exact snippet. This is a good pattern for tests: wire an in-memory client to the server, call the prompt, and assert on the message payload that a real host would receive. Sources: docs/servers/prompts.md
Argument validation happens before the prompt callback runs. When the required code argument is omitted, the SDK rejects the request with a protocol error carrying the JSON-RPC invalid-params code. This differs from tool argument rejection, which is returned as a successful tool result marked as an error so the model can read and recover. Prompt authors should therefore put recovery guidance in descriptions and host-visible metadata. Once prompt retrieval fails validation, there is no model-visible prompt body to explain what went wrong. Sources: docs/servers/prompts.md, docs/servers/errors.md
try {
await client.getPrompt({ name: 'review-code', arguments: {} });
} catch (error) {
const { code, message } = error as ProtocolError;
console.log(code, message);
}Building Messages and Argument UX
A prompt callback returns an object containing messages. Each message declares a role, usually user or assistant, and one content block such as text content. A simple prompt may return only a user message, but the guide also shows adding an assistant message after the user message to seed how the reply should begin. Use that pattern carefully: an assistant seed can guide tone or structure, while the user message should carry the task, the validated arguments, and enough context for the host and model to proceed without hidden server state. Sources: docs/servers/prompts.md
Prompt arguments can be made easier to fill with server-side completion. The completion guide defines completion as autocomplete for prompt arguments and resource template variables. Wrap a schema field with completable(schema, callback) and the field validates exactly as before while also serving suggestions for partially typed input. The first completable field registers the server completion handler and advertises the completions capability automatically. Completion callbacks may be synchronous or asynchronous, and the optional context can include other arguments the client has already collected, enabling dependent fields such as repository then branch. Sources: docs/servers/completion.md
Interactive Input, Errors, and Handler Context
Most prompts should collect required information up front through the argument schema, but some workflows need more information during execution. The newer input_required flow applies to prompt retrieval as well as tool calls and resource reads: a handler returns embedded input requests, the client answers them, and the original call is retried with responses. The older elicitation guide describes ctx.mcpReq.elicitInput as a push-style request to the client, but it also notes that this push channel throws on a 2026-07-28 connection. Use the negotiated protocol pattern consistently. Sources: docs/servers/input-required.md, docs/servers/elicitation.md
Prompt, resource, and completion callbacks do not have the tool-only error channel that returns a model-readable result. If a prompt request is invalid beyond schema validation, throw an appropriate protocol error rather than returning an invented message payload that looks like usable conversation context. For longer-running prompt callbacks, the same handler context concepts apply: request-scoped helpers live on ctx.mcpReq, progress should only be sent when the client supplied a progress token, cancellation should be respected, and MCP logging is documented as deprecated for the newer protocol revision. Sources: docs/servers/errors.md, docs/servers/logging-progress-cancellation.md
Compact API Reference
| Component | Contract | Notes |
|---|---|---|
server.registerPrompt(name, config, callback) | Registers a named prompt and message-producing callback. | Use this v2 API instead of the older prompt() helper. |
config.title | Optional display title. | Useful for host menus and command palettes. |
config.description | Human-readable prompt description. | Write this for the person choosing the prompt. |
config.argsSchema | Object schema for prompt arguments. | Drives listing metadata, request validation, and callback typing. |
z.string().describe(...) | Field-level argument description. | Preserved in advertised prompt argument metadata. |
callback(args) | Returns an object with messages. | Messages declare roles and content blocks. |
client.getPrompt({ name, arguments }) | Retrieves a materialized prompt from a connected server. | Rejects with a protocol error when prompt arguments are invalid. |
completable(schema, complete) | Adds autocomplete behavior to a prompt argument. | Suggestions may be synchronous, asynchronous, or context-aware. |
inputRequired(spec) | Returns an input-required result for supported handlers. | Applies to prompt retrieval in the documented newer flow. |
Practical Next Steps
Design prompt names as stable protocol identifiers and descriptions as user-interface copy. Put every required user choice in the schema, describe fields that a person must fill, and add completion for values with known or searchable domains. During debugging, separate discovery failures from retrieval failures and message-quality issues. After implementing a prompt, test it through a connected client with getPrompt, then exercise invalid arguments, completion behavior, and any interactive input path. For surrounding behavior, read the client calling guide, completion guide, input-required guide, and server error guide next.