What is Prompt?
A Prompt in MCP is a server-declared, user-controlled message template — the key word being "user-controlled." Unlike Tools, which the model calls autonomously during inference, Prompts are surfaced to the human operator as selectable entries: slash commands, palette items, or pre-built conversation starters. The server registers them once during the session (via prompts/list), and the host exposes them in its UI. Only when the user deliberately picks one does the client fire a prompts/get request, passing any argument values the user supplied. The server then renders the template and returns a structured GetPromptResult containing an array of PromptMessages that the host injects verbatim into the conversation history. \n\n The API surface is intentionally thin. A Prompt has a machine-readable name (used as the identifier in prompts/get calls), an optional human-facing title for display, an optional description that hosts typically show as tooltip text, and an optional arguments array of PromptArgument objects. Arguments are always simple string slots — there is no JSON Schema support here. If you need structured or typed input, that workflow belongs in a Tool. The host may support completion/complete to power type-ahead suggestions for each argument slot while the user types. \n\n Prompts were present from the earliest MCP drafts but the title field was added later (2024-11 spec revision) to cleanly separate the programmatic name from the display label. Servers must declare the prompts capability in their ServerCapabilities for clients to call prompts/list at all. Dynamic rosters are supported: when the server's available prompts change it emits a notifications/prompts/list_changed notification, signalling clients to re-fetch the list. There is no built-in versioning or schema evolution mechanism for individual prompts — if you change a prompt's arguments in a breaking way, update the name.
When to use
For repeatable workflows the user invokes intentionally (e.g., /summarize, /code-review).
When NOT to use
For dynamic, model-driven actions — use Tools.
Notes
Prompts vs Tools: control plane differs
The defining distinction is who triggers execution. Tools are invoked by the model (application-controlled in MCP terminology) during agentic inference. Prompts are invoked by the user or application layer, never by the model itself. Mixing the two — for example, having a Tool that calls prompts/get to seed its own context — is an anti-pattern and breaks the intended trust model.
Arguments are flat strings only
PromptArgument values are always string-typed; there is no JSON Schema or type coercion layer. If a workflow requires a number, date, or nested object as input, model it as a Tool with an inputSchema instead. Attempting to pass JSON-encoded strings through prompt arguments works but creates a parsing obligation on the server side that erodes reliability.
Capability declaration is required
A client will not call prompts/list unless the server's ServerCapabilities.prompts field is present (even as an empty object). Forgetting this during initialization silently disables the entire prompts surface — the host simply won't discover or render any prompt entries. Similarly, to support dynamic updates, ServerCapabilities.prompts.listChanged must be set to true.
name field is the stable identifier
The name field is the key used in prompts/get, stored in user preferences, and potentially serialized in scripts. Treat it like a function name in a public API: use snake_case or kebab-case, keep it stable across releases, and document any renames. The title field is purely cosmetic and can be localized freely without breaking anything.
No built-in pagination for argument completions
The completion/complete endpoint returns at most 100 suggestions per request with a hasMore flag, but there is no cursor-based pagination for completions. For prompts with arguments that map to large datasets (e.g., all project names in a workspace), you should either filter server-side based on the partial string the user has typed, or limit the suggestion set to the most relevant N items to stay within the 100-item cap.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| name | string | yes | Programmatic name (e.g., 'summarize'). |
| title | string? | no | Display name. |
| description | string? | no | What the prompt does. |
| arguments | PromptArgument[]? | no | Argument schema. |
Examples
A vacation planner prompt
{
"name": "plan_vacation",
"title": "Plan a vacation",
"description": "Generate a structured itinerary for a destination.",
"arguments": [
{ "name": "destination", "required": true },
{ "name": "days", "required": false }
]
}
Common mistakes
❌ Using prompts for model-driven actions
✅ Prompts are user-controlled — model-driven calls belong in Tools.