A prompt in MCP is a reusable, parameterized message template a server defines once and a user triggers on purpose — usually surfaced as a slash command or a menu item in the client — rather than something a model decides to invoke mid-conversation the way it decides to call a tool. It is the least visible of the three primitives covered in tools, resources, and prompts, and the one most getting-started guides skip entirely. Here is what prompts/list and prompts/get actually return, and why a template is a genuinely different shape than a tool call.

What prompts/list and prompts/get return

prompts/list gives the client a catalog: each entry has a name, an optional human-readable description, and a list of arguments the prompt accepts, each with its own name, description, and a boolean required. That is the whole schema — there is no type system the way a tool’s inputSchema has one. Every argument is effectively a string the server interprets however it wants.

Once a user picks a prompt and fills in its arguments, the client calls prompts/get with the name and the argument values, and the server responds with a list of PromptMessage objects — each with a role (user or assistant) and content, ready to be dropped straight into the conversation. The server is handing back a fully assembled piece of conversation history, not a string to interpolate yourself.

Why a prompt can carry more than text

A PromptMessage’s content isn’t limited to plain text. It can also be an embedded resource, using the same shape a resources/read call would return. That means a prompt template can ship with a file’s actual contents baked into the conversation it hands back, not just an instruction that references one. A “review this PR using our house style” prompt, for instance, can embed the style guide itself as a resource inside the assistant turn it returns, instead of telling the model to go fetch it separately.

No type system means completion does more work here

Because a prompt argument is just a name and a description, a client has no schema to validate against before it sends a value. The one piece of help the spec offers is completion: a server that implements completion/complete can suggest valid values as the user types a prompt argument, the same mechanism it would use for a resource template placeholder. Most servers skip this too, which means most prompt arguments are free text with nothing guiding what goes in the box beyond the argument’s description.

Why this is user-controlled, not model-controlled

The distinction that matters is who decides. A tool call happens because the model, mid conversation, judged it was relevant and filled in the arguments itself. A prompt happens because a person went looking for it, picked it from a list, and typed in the arguments on purpose. That makes prompts a better fit than tools for a workflow you want to be repeatable and intentional — a release-note template, an incident-report format, a fixed review checklist — where you’d rather the exact same instructions run every time than trust a model to reconstruct them from a vague request.

The tradeoff is discoverability. A tool shows up automatically in a model’s decision-making the moment a server connects. A prompt only gets used if a user notices it exists and goes looking for it, and plenty of clients still render prompts as an afterthought compared to the tool list they lead with.

Why most servers still don’t ship prompts

The same forces that keep most servers tool-only, covered in our primitives overview, apply here even more strongly. Tools map directly onto API endpoints, which is how most servers get built in the first place, including ones generated from an OpenAPI spec. A prompt has no obvious endpoint to generate it from — it is a deliberate piece of authored content, closer to a canned response than a wrapped API call, and that extra step of actually writing good prompt templates is easy to skip when a tool list already does the job of exposing the underlying actions.

What this means for a gateway: a prompt template is server-declared content the client hands straight to the model, the same trust relationship as a tool description or a resource template — the server controls the wording, and a hostile or compromised one could use a prompt’s text or an embedded resource to carry the same kind of injected instruction a poisoned tool description would. gate’s free MCP security scanner checks a server’s declared surface before you connect it, and a gateway that logs and gates tool calls should apply the same scrutiny to what a prompt hands back, since it lands in the same context window either way.

If you’re building a server

Reach for a prompt when you have a workflow worth making repeatable and discoverable on purpose — something you’d otherwise be asking users to retype the same instructions for every time. Keep the argument list short and the descriptions specific, since there’s no schema to lean on if a description is vague. If you’re generating a server from an existing API with gate’s MCP server builder, prompts won’t show up in that draft at all — endpoints become tools, not templates — so adding a prompt is a deliberate step you take afterward, not something to expect out of an automatic conversion.

The bottom line

A prompt is a named, parameterized message template a user picks on purpose, returned as ready-made conversation turns that can embed a real resource alongside plain text. It carries no type system and, outside of optional completion support, no validation beyond whatever the server checks itself. It solves a real problem — making a workflow repeatable instead of re-explained every time — but needs a user to go looking for it, which is the main reason it stays the quietest of MCP’s three core primitives. See gate’s MCP server directory for how today’s servers actually use tools, resources, and prompts in practice.