skip to content

Server Primitives

Tools the model calls, resources the app pulls in by URI, and prompts the user invokes. Interviewers probe the control distinction because data on the wrong side makes a server awkward to use.

part ofAPI stylesoverview, primer and where to startread it →
on this pageshow

explore

questions

17

In MCP, what do prompts/list and prompts/get return, and who invokes a prompt?

level: juniorimportance: must knowfreq 65%

answer

  1. three primitives, three initiators
  2. the user picks this one
  3. one call lists, one call fills
  4. name plus string arguments in, messages out

basics

~20 s

prompts/list returns the server's prompt templates with their names, descriptions and declared arguments. prompts/get takes one name plus argument values and returns the filled-in, role-tagged messages. Prompts are user-controlled: a person picks one, the model does not.

solid answer

~40 s

Prompts are the third server primitive in MCP, alongside tools and resources, and the distinguishing property is who initiates them. A tool is model-controlled and a resource is application-controlled, but a prompt is **user-controlled**: the host surfaces the server's prompts as slash commands, menu items or buttons, and a human deliberately picks one. `prompts/list` returns a `prompts` array — each entry has a `name`, an optional `title` and `description`, and an optional `arguments` array — plus an optional `nextCursor` for pagination. `prompts/get` takes `name` and an optional `arguments` map of string values, and returns an optional `description` plus a `messages` array, where each message has a `role` and one content block. Under revision 2026-07-28 every result also carries a required `resultType`, and `prompts/list` is cacheable, so it additionally carries `ttlMs` and `cacheScope`.

code

json · 13 lines
json
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "prompts/get",
  "params": {
    "name": "review_diff",
    "arguments": { "path": "src/main.kt", "style": "strict" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

go deeper

for a junior

Be able to name the three server primitives and say which one a user picks. Know that prompts/list enumerates templates and prompts/get returns the finished messages for one of them.

for a middle

Explain the shapes: name, title, description and arguments on the list side; name plus a string argument map in, description and role-tagged messages out on the get side. Mention the required resultType.

for a senior

Show that you design around statelessness: each call is self-contained, prompts/get may arrive without a preceding prompts/list, and the list result's ttlMs and cacheScope drive how often a host refreshes its command menu.

for a principal

Own the modelling call. Decide deliberately which capability belongs on the user-controlled surface versus the model-controlled one, because that choice determines whether a human reviews every invocation or an agent loop can fire it unattended.

## The third server primitive An MCP server can expose three kinds of things, and the specification separates them by **who initiates the use**. Tools are model-controlled: the language model decides to call one. Resources are application-controlled: the host application decides which URIs to pull into context. Prompts are user-controlled: they are message templates the server publishes so that a *person* can deliberately choose one and have it dropped into the conversation. That distinction is the whole reason prompts exist as a separate primitive instead of being modelled as "a tool that returns some text". A prompt is meant to appear in the host's user interface — a slash-command menu, a command palette, a button, a template picker — and be selected by a human. Nothing in the protocol forces a host to render them that way, but that is the intended control flow, and interviewers use the tools/resources/prompts control triangle as a quick check that a candidate has actually read the specification. ## prompts/list `prompts/list` is an ordinary JSON-RPC request. Its params may carry an opaque `cursor` for pagination; the result may carry `nextCursor` when more pages exist. The substance is the `prompts` array. Each `Prompt` object has: - `name` — the programmatic identifier used later in `prompts/get`. - `title` — an optional human-friendly display name. - `description` — optional prose explaining what the prompt is for; this is what a user reads in the picker. - `arguments` — an optional array of `PromptArgument` objects describing the values the prompt expects. Under revision 2026-07-28 the result is a `CacheableResult`, so it carries the required `ttlMs` and `cacheScope` fields alongside the required `resultType`, which is `"complete"` for an ordinary answer. A client that respects those fields can serve its prompt menu from cache instead of re-listing on every interaction. ## prompts/get `prompts/get` takes two params: the `name` of the prompt, and an optional `arguments` object mapping argument names to **string** values. The result contains an optional `description` and a required `messages` array. Each element is a `PromptMessage` with a `role` and a single content block. The server performs the templating — substitution, formatting, and any lookups it wants to do — so the client receives finished messages it can hand to the model, usually after the user has had a chance to see or edit them. Because the server does the work, a prompt can do far more than string interpolation: it can read a file, query a database, and return the result embedded in the messages. That is what makes prompts more than a client-side snippet feature. ## Statelessness changes how the pair is used MCP at 2026-07-28 is a stateless protocol. The `initialize` handshake and `notifications/initialized` that earlier revisions used were removed; every request instead carries `_meta` with `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities`, and a server MUST NOT rely on a prior request over the same connection to establish context. For prompts that means `prompts/list` and `prompts/get` are fully independent calls. A client MAY call `prompts/get` without ever having called `prompts/list` — for instance because it cached the list earlier, or because a user typed a known command. A server that only fills its prompt table after seeing a `prompts/list` from the same connection is broken. ## Errors and the non-complete result A request for an unknown prompt name, or one missing a required argument, is answered with the standard `-32602` invalid-params error. Separately, `prompts/get` is one of only three methods — with `tools/call` and `resources/read` — that may answer with `resultType: "input_required"` rather than `"complete"`. A robust client therefore branches on `resultType` instead of assuming `messages` is present. If an older server omits `resultType` entirely, the client must treat the result as `"complete"`. ## Common mistakes The most frequent error is describing prompts as something the model invokes; that is a tool. The second is assuming prompts are static text — they are server-computed messages. The third is assuming a prompt takes typed JSON arguments the way a tool takes an `inputSchema`; prompt argument values arrive as strings.

  • Why model something as a prompt rather than as a tool that returns text?
    Because the initiator differs. A tool is exposed to the model, which may call it autonomously inside a loop; a prompt is exposed to the user, who picks it deliberately and can review or edit the result before it reaches the model. If the intended trigger is a human choosing a workflow, a prompt puts it in the right surface; if the model should decide, it is a tool.
  • Must a client call prompts/list before prompts/get?
    No. MCP at 2026-07-28 is stateless, so each request is self-contained and a server MUST NOT rely on prior requests over the same connection. A client may call prompts/get directly using a name it cached or a command the user typed. The server must resolve the name on its own; if it does not recognise it, it answers -32602.

saying these in an interview costs you the question

  • Saying the model chooses which prompt to invoke
  • Calling prompts static text the client interpolates itself
  • Claiming prompts/get requires a prior initialize handshake
  • Assuming prompt arguments are typed JSON objects
  • Thinking prompts/list must precede prompts/get on the same connection

context

open as a page

In MCP, what do resources/list and resources/read return, and how is a resource identified?

level: juniorimportance: must knowfreq 70%

basics

~20 s

A resource is identified by its URI. resources/list returns descriptors — uri, name, optional description and mimeType — while resources/read takes one uri and returns a contents array carrying the data itself. Both results carry the required resultType field in MCP 2026-07-28.

open as a page

In MCP, what is a tool's inputSchema and how is it used by client and server?

level: juniorimportance: must knowfreq 72%

basics

~20 s

inputSchema is the JSON Schema object in a tool's tools/list entry that describes the arguments the tool accepts. The host uses it to shape and check the arguments object sent in tools/call, and the server validates against it again.

open as a page

How does an MCP prompt declare its arguments, and what does required mean?

level: middleimportance: must knowfreq 55%

basics

~20 s

Each entry in a prompt's arguments array is a PromptArgument with a name, an optional title and description, and an optional required boolean. Callers pass values as a flat name-to-string map on prompts/get; omitting a required argument earns a -32602 invalid-params error.

open as a page

In MCP, when does a tools/call use isError instead of a JSON-RPC error?

level: middleimportance: must knowfreq 74%

basics

~20 s

Failures of the tool's own work — an upstream 500, a missing file, a rejected input value — come back as a successful result with isError set to true, so the model can read them. Protocol-level failures such as an unknown tool or invalid params are JSON-RPC error objects.

open as a page

What does an MCP tools/call return, and when is structuredContent required?

level: middleimportance: must knowfreq 62%

basics

~20 s

A tools/call result carries a content array of blocks — text, image, audio, resource_link or embedded resource — plus an optional isError flag. If the tool declares an outputSchema, the result must also carry structuredContent conforming to that schema.

open as a page

In MCP, how does completion/complete autocomplete a prompt argument value?

level: middleimportance: should knowfreq 33%

basics

~20 s

The 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.

open as a page

In MCP, when should a prompt message embed a resource instead of a resource_link?

level: middleimportance: should knowfreq 36%

basics

~20 s

Embed the resource when the prompt is meaningless without that content already in the message — the server inlines a snapshot of the bytes. Send a resource_link when the client should decide whether, and when, to read it.

open as a page

What does an MCP prompts/get messages array contain, and which roles are allowed?

level: middleimportance: should knowfreq 45%

basics

~20 s

prompts/get returns a messages array of PromptMessage objects. Each has a role of either user or assistant — there is no system role — and exactly one content block: text, image, audio, a resource_link pointing at a resource, or an embedded resource carrying the data inline.

open as a page

In MCP 2026-07-28, what must a server return when resources/read names a missing resource?

level: middleimportance: should knowfreq 38%

basics

~20 s

A JSON-RPC error with code -32602, invalid params. Revision 2026-07-28 folded resource-not-found into the standard invalid-params code; clients still accept -32002 from older servers. A server MUST NOT answer with a success result carrying an empty contents array.

open as a page

What is an MCP resource template, and when do you publish one instead of a resource?

level: middleimportance: should knowfreq 45%

basics

~20 s

A resource template is a parameterized URI published by resources/templates/list: a uriTemplate such as git://repo/{path} written in RFC 6570 syntax. Publish one when the resource space is too large or too dynamic to enumerate with resources/list.

open as a page

In MCP, how does resources/read return binary data such as a PDF or an image?

level: middleimportance: should knowfreq 48%

basics

~20 s

Binary data travels as a base64 string in the blob field of a contents entry, while textual data uses the text field. An entry carries one or the other, never both, and mimeType tells the host how to interpret it.

open as a page

What are MCP's four ToolAnnotations and what does each default to?

level: middleimportance: should knowfreq 52%

basics

~20 s

ToolAnnotations are readOnlyHint (default false), destructiveHint (default true), idempotentHint (default false) and openWorldHint (default true). Omitting them therefore describes the most dangerous tool: one that writes, destroys, is unsafe to repeat, and touches the outside world.

open as a page

In MCP, when should data be exposed as a resource rather than behind a tool?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Expose data as a resource when it is addressable by a stable URI, read without side effects, and something the application or user chooses to pull into context. Anything needing real parameters, a query, or a state change belongs behind a tool instead.

open as a page

How does an MCP client keep a cached tools/list fresh in revision 2026-07-28?

level: seniorimportance: should knowfreq 44%

basics

~20 s

ListToolsResult is a cacheable result carrying required ttlMs and cacheScope, so a client caches the tool list for that lifetime. For push updates it must open a subscriptions/listen stream with toolsListChanged set; notifications/tools/list_changed arrives nowhere else.

open as a page

Why must an MCP server's tool set not vary per connection, and what may it vary by?

level: seniorimportance: should knowfreq 38%

basics

~20 s

MCP 2026-07-28 is stateless, so a server MUST expose the same tool set regardless of which connection a request arrives on. The one permitted variation is the authorization presented with the request: different credentials may legitimately see different tools.

open as a page

When should an MCP server expose a capability as a prompt rather than a tool?

level: principalimportance: should knowfreq 32%

basics

~20 s

Ship it as a prompt when a person deliberately starts it and the server's job is to hand back well-shaped messages that seed the conversation. Ship it as a tool when the model must reach for it mid-conversation and something actually executes.

open as a page