ChangeGamer

← All resources

MCP Primitives: Resources, Prompts, Sampling, and Elicitation

Reference · updated 2026-06-16 · Markdown variant

Deep reference on the six MCP capability primitives beyond tools — who controls each, the exact JSON-RPC method names, and when to use Resources vs Tools — verified against the 2025-06-18 and 2025-11-25 spec revisions.


MCP defines six capability primitives in two groups: server-side (Tools, Resources, Prompts) and client-side (Sampling, Roots, Elicitation). Each primitive has a designated controlling party — model, application, or user — which determines how it is invoked and why the separation matters for safety. This page goes deep on the five primitives beyond Tools, which are covered separately in /resources/mcp-vs-a2a and /resources/mcp-server-discovery.

Control model overview

Primitive Side Controlled by Who decides to invoke it
Tools Server Model The LLM autonomously decides to call a tool
Resources Server Application The host app decides what context to expose and inject
Prompts Server User The user explicitly selects a prompt template
Sampling Client Server (asks client) The server requests an LLM call from the host
Roots Client Application The client app declares filesystem/URI boundaries
Elicitation Client Server (asks user via client) The server requests structured user input mid-session

The three-way split (model / app / user) is not cosmetic. It maps directly to who bears responsibility for an action and what approval is required before it executes. See /resources/agentic-security-checklist and /resources/mcp-server-authentication for the security implications.

Server-side primitives

Resources (application-controlled)

Resources are read-only data that the host application exposes to the model as context. Unlike tools, the model never decides to fetch a resource on its own — the application controls what is offered and when it is injected into context.

A resource has a URI (e.g. file:///workspace/README.md, db://customers/42) and returns either text or binary blob content.

JSON-RPC methods (verified against 2025-11-25 schema):

Clients receive a notifications/resources/updated notification when subscribed resource content changes, and a notifications/resources/list_changed notification when the available resource list itself changes.

Concrete example: A coding assistant server exposes the current open file as file:///current-file. The host app calls resources/read when the user opens the file; the model sees the content as context, never having "requested" it.

Prompts (user-controlled)

Prompts are reusable, parameterized message templates that a server exposes. The user explicitly selects one — typically via a slash command or UI affordance in the host client. The model does not invoke prompts autonomously.

JSON-RPC methods:

A notifications/prompts/list_changed notification signals when the prompt catalog updates.

Concrete example: A code-review server exposes a review_pr prompt with a pr_url argument. The user types /review_pr pr_url=https://github.com/…; the client calls prompts/get and inserts the rendered messages into the conversation.

Tools (model-controlled, brief)

Tools are executable actions the model invokes autonomously based on context. Listed via tools/list, called via tools/call. This is the most-used primitive; see /resources/mcp-vs-a2a for the full protocol context.

Client-side primitives

These primitives invert the direction: the server calls into the client rather than the client calling the server.

Sampling (server calls client for an LLM completion)

Sampling lets a server request an LLM completion from the host client on its behalf. The server sends a sampling/createMessage request containing a message list, an optional system prompt, and optional model preferences (cost/speed/intelligence hints). The client — subject to user approval — forwards the request to its connected LLM and returns the result.

JSON-RPC method: sampling/createMessage (server → client)

The human-in-the-loop design is deliberate. The spec requires clients to let users review and modify sampling requests before sending them to the model, and to review model responses before returning them to the server. This ensures the server cannot silently use the model to exfiltrate context or generate content the user has not sanctioned.

Note: Sampling is marked deprecated in the draft 2026-07-28 spec revision (SEP-2577). Per the MCP feature lifecycle policy it remains in the 2025-11-25 stable spec and will not be eligible for removal for at least twelve months after that draft ships.

Concrete example: A database MCP server receives a resources/read call for a large schema blob. Rather than hard-coding a summary, it calls sampling/createMessage asking the LLM to condense the schema into a two-sentence description, then returns that summary as the resource content.

Roots (client declares filesystem/URI boundaries)

Roots are URIs (commonly file:// paths) that the client declares to tell the server which parts of the filesystem or resource space it is permitted to access. This is a coordination mechanism, not a hard security enforcement: the spec requires servers to respect root boundaries, but cannot enforce it because servers run code outside the client's control.

JSON-RPC methods:

Roots update dynamically: when a user opens a new project folder, the client sends notifications/roots/list_changed and the server can call roots/list to refresh its scope — no server restart required.

Concrete example: A filesystem MCP server starts with roots [file:///projects/alpha]. The user opens a second project; the client sends notifications/roots/list_changed; the server calls roots/list and now has [file:///projects/alpha, file:///projects/beta].

Note: like Sampling, Roots is marked deprecated in the draft 2026-07-28 spec revision (SEP-2577, which deprecates roots, sampling, and logging). It remains in the 2025-11-25 stable spec and stays usable for at least twelve months after that draft ships.

Elicitation (server requests structured user input)

Elicitation was introduced in the 2025-06-18 spec revision. It lets a server request additional structured input from the user mid-session, without the server needing to implement its own UI.

JSON-RPC method: elicitation/create (server → client)

The request carries a human-readable message and an optional requestedSchema — a restricted JSON Schema subset (flat object with primitive-type properties only; no nested objects or arrays). The client renders the schema as a form, the user fills it in (or declines), and the client returns one of three actions:

Servers are explicitly prohibited from using elicitation to request sensitive data (passwords, tokens, credentials). The user can always reject an elicitation request.

Concrete example: A CI/CD MCP server is about to deploy to production. It calls elicitation/create with message: "Confirm deployment target" and a schema requiring { env: string, confirm: boolean }. The user fills in the form; the server proceeds only on action: accept with confirm: true.

Resources vs Tools: the key design question

The most common MCP server design question is whether to expose something as a Resource or a Tool. The spec's control-model distinction gives a clean answer:

Use a Resource when... Use a Tool when...
The data is read-only context the app injects The model needs to trigger an action or side effect
The app (not the model) decides what to include The model decides whether and when to call
The content is stable or subscribable The content depends on model-chosen arguments
Example: open file, DB row, live feed Example: search API, code executor, write operation

A file viewer is a Resource. A file writer is a Tool. A search endpoint that takes a query the model chooses is a Tool. A configuration blob the app always injects is a Resource.

Verified sources

#mcp #protocols #resources #prompts #sampling #elicitation #roots #agents

Category: Reference