{
  "slug": "mcp-primitives",
  "title": "MCP Primitives: Resources, Prompts, Sampling, and Elicitation",
  "description": "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.",
  "category": "Reference",
  "tags": [
    "mcp",
    "protocols",
    "resources",
    "prompts",
    "sampling",
    "elicitation",
    "roots",
    "agents"
  ],
  "updated": "2026-07-31",
  "premium": false,
  "canonical": "https://changegamer.ai/resources/mcp-primitives",
  "markdown": "https://changegamer.ai/resources/mcp-primitives.md",
  "outline": [
    {
      "depth": 2,
      "text": "Key facts",
      "anchor": "key-facts"
    },
    {
      "depth": 2,
      "text": "Control model overview",
      "anchor": "control-model-overview"
    },
    {
      "depth": 2,
      "text": "Server-side primitives",
      "anchor": "server-side-primitives"
    },
    {
      "depth": 3,
      "text": "Resources (application-controlled)",
      "anchor": "resources-application-controlled"
    },
    {
      "depth": 3,
      "text": "Prompts (user-controlled)",
      "anchor": "prompts-user-controlled"
    },
    {
      "depth": 3,
      "text": "Tools (model-controlled, brief)",
      "anchor": "tools-model-controlled-brief"
    },
    {
      "depth": 2,
      "text": "Client-side primitives",
      "anchor": "client-side-primitives"
    },
    {
      "depth": 3,
      "text": "Sampling (server calls client for an LLM completion)",
      "anchor": "sampling-server-calls-client-for-an-llm-completion"
    },
    {
      "depth": 3,
      "text": "Roots (client declares filesystem/URI boundaries)",
      "anchor": "roots-client-declares-filesystem-uri-boundaries"
    },
    {
      "depth": 3,
      "text": "Elicitation (server requests structured user input)",
      "anchor": "elicitation-server-requests-structured-user-input"
    },
    {
      "depth": 2,
      "text": "Resources vs Tools: the key design question",
      "anchor": "resources-vs-tools-the-key-design-question"
    },
    {
      "depth": 2,
      "text": "Verified sources",
      "anchor": "verified-sources"
    }
  ],
  "related": [
    {
      "slug": "mcp-apps-explained",
      "title": "MCP Apps Explained: The Official Interactive-UI Extension for MCP",
      "description": "What MCP Apps (SEP-1865) is: the ui:// resource scheme and sandboxed-iframe/JSON-RPC bridge it defines for MCP tools to return rendered UI instead of plain text, how it relates to the community MCP-UI project and OpenAI's Apps SDK, and which hosts support it.",
      "url": "https://changegamer.ai/resources/mcp-apps-explained"
    },
    {
      "slug": "mcp-2026-spec-revision",
      "title": "MCP Goes Stateless: The 2026-07-28 Spec Revision Explained",
      "description": "What changes in MCP's largest revision since launch: SEP-2575/SEP-2567 remove the session handshake and Mcp-Session-Id header for explicit state handles, new Mcp-Method/Mcp-Name routing headers, full JSON Schema 2020-12 tool schemas, and six authorization-hardening SEPs — shipped as final, on schedule, on 2026-07-28.",
      "url": "https://changegamer.ai/resources/mcp-2026-spec-revision"
    },
    {
      "slug": "mcp-server-authentication",
      "title": "MCP Server Authentication: OAuth 2.1 for Remote Servers",
      "description": "How OAuth 2.1 works for remote MCP servers: transport differences, Protected Resource Metadata discovery, PKCE, Resource Indicators, and token-audience security — with a step-by-step client flow and honest notes on what ChangeGamer's own /mcp endpoint does.",
      "url": "https://changegamer.ai/resources/mcp-server-authentication"
    },
    {
      "slug": "mcp-vs-function-calling",
      "title": "MCP vs Function Calling: When to Use Which",
      "description": "Direct comparison of provider-native function/tool calling and the Model Context Protocol — architecture, decision criteria, and how they compose.",
      "url": "https://changegamer.ai/resources/mcp-vs-function-calling"
    }
  ],
  "furtherReading": [
    {
      "slug": "mcp-oauth-implementation",
      "title": "How to Implement OAuth 2.1 for an MCP Server",
      "description": "A wire-level implementation walkthrough for OAuth 2.1 on a remote MCP server: what the discovery documents actually contain, CIMD vs. Dynamic Client Registration in your server code, per-SEP detail from the 2026-07-28 hardening set, and token-validation mechanics.",
      "url": "https://changegamer.ai/articles/mcp-oauth-implementation"
    },
    {
      "slug": "mcp-server-in-production",
      "title": "MCP Server in Production: How to Build, Ship and Run One",
      "description": "The operator playbook for taking an MCP server past the quickstart: transport choice, OAuth 2.1 auth, tool design, versioning against a moving spec, testing across clients, distribution, observability, cost and the failure modes that show up once real clients connect.",
      "url": "https://changegamer.ai/articles/mcp-server-in-production"
    }
  ],
  "body": "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.\n\n## Key facts\n\n- Six primitives split by control: Tools/Resources/Prompts run server-side while Sampling/Roots/Elicitation run client-side, each with a designated controller (model, app, or user).\n- Resources are read-only, application-controlled context — the model itself never decides to fetch one; the host app decides both the content and the timing of what reaches the model.\n- Prompts are message templates the user picks explicitly, typically through a slash command; the model cannot invoke a prompt template on its own.\n- Sampling lets a server ask the connected client to run an LLM completion on its behalf, but the spec requires human review of both the outgoing request and the returned response before either reaches the model or the server.\n- Roots tell a server which filesystem or URI scope the client permits — described as a coordination mechanism rather than an enforced boundary, given servers execute outside anything the client can directly police.\n- Elicitation, added in the 2025-06-18 revision, lets a server collect structured mid-session input from the user through a restricted schema, and servers are barred from using it to request passwords or other credentials.\n- Under SEP-2577, the 2026-07-28 spec revision — which shipped as final, on schedule, on that date — marks Sampling, Roots, and Logging deprecated. This is an annotation-only deprecation: all three keep working, with removal barred for at least twelve months from 2026-07-28.\n\n## Control model overview\n\n| Primitive | Side | Controlled by | Who decides to invoke it |\n|---|---|---|---|\n| Tools | Server | Model | The LLM autonomously decides to call a tool |\n| Resources | Server | Application | The host app decides what context to expose and inject |\n| Prompts | Server | User | The user explicitly selects a prompt template |\n| Sampling | Client | Server (asks client) | The server requests an LLM call from the host |\n| Roots | Client | Application | The client app declares filesystem/URI boundaries |\n| Elicitation | Client | Server (asks user via client) | The server requests structured user input mid-session |\n\nThe 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.\n\n## Server-side primitives\n\n### Resources (application-controlled)\n\nResources 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.\n\nA resource has a URI (e.g. `file:///workspace/README.md`, `db://customers/42`) and returns either text or binary blob content.\n\n**JSON-RPC methods (verified against 2025-11-25 schema):**\n\n- `resources/list` — enumerate all available resources\n- `resources/read` — fetch the content of a specific resource by URI\n- `resources/templates/list` — list URI templates (parameterized patterns like `file:///{path}` that clients expand to concrete URIs)\n- `resources/subscribe` — subscribe to change notifications for a specific resource URI\n- `resources/unsubscribe` — cancel a subscription\n\nClients 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.\n\n**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.\n\n### Prompts (user-controlled)\n\nPrompts 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.\n\n**JSON-RPC methods:**\n\n- `prompts/list` — enumerate available prompt templates (name, description, argument list)\n- `prompts/get` — retrieve a rendered prompt for a given name and argument values\n\nA `notifications/prompts/list_changed` notification signals when the prompt catalog updates.\n\n**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.\n\n### Tools (model-controlled, brief)\n\nTools 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.\n\n## Client-side primitives\n\nThese primitives invert the direction: the server calls into the client rather than the client calling the server.\n\n### Sampling (server calls client for an LLM completion)\n\nSampling 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.\n\n**JSON-RPC method:** `sampling/createMessage` (server → client)\n\nThe 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.\n\nNote: Sampling was marked deprecated in the final 2026-07-28 spec revision (SEP-2577), which shipped as scheduled with no delay. Per the MCP feature lifecycle policy this is an annotation-only deprecation — the method continues to work and will not be eligible for removal for at least twelve months after 2026-07-28.\n\n**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.\n\n### Roots (client declares filesystem/URI boundaries)\n\nRoots 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.\n\n**JSON-RPC methods:**\n\n- `roots/list` — server requests the current list of roots from the client\n- `notifications/roots/list_changed` — client notifies the server when the root list changes\n\nRoots 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.\n\n**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]`.\n\nNote: like Sampling, Roots was marked deprecated in the final 2026-07-28 spec revision (SEP-2577, which deprecates roots, sampling, and logging), which shipped as scheduled. This is an annotation-only deprecation — Roots keeps working and stays usable for at least twelve months after 2026-07-28.\n\n### Elicitation (server requests structured user input)\n\nElicitation 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.\n\n**JSON-RPC method:** `elicitation/create` (server → client)\n\nThe 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:\n\n- `accept` — user submitted the form; response includes the filled content object\n- `reject` — user explicitly declined to provide the information\n- `cancel` — user dismissed the dialog without taking action\n\nServers are explicitly prohibited from using elicitation to request sensitive data (passwords, tokens, credentials). The user can always reject an elicitation request.\n\n**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`.\n\n## Resources vs Tools: the key design question\n\nThe 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:\n\n| Use a Resource when... | Use a Tool when... |\n|---|---|\n| The data is read-only context the app injects | The model needs to trigger an action or side effect |\n| The app (not the model) decides what to include | The model decides whether and when to call |\n| The content is stable or subscribable | The content depends on model-chosen arguments |\n| Example: open file, DB row, live feed | Example: search API, code executor, write operation |\n\nA 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.\n\n## Verified sources\n\n- MCP schema 2025-11-25 (method names verified directly): https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts\n- MCP elicitation spec 2025-06-18 (introduction revision confirmed): https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation\n- IBM mcp-context-forge issue #234 (elicitation/create confirmed in 2025-06-18): https://github.com/IBM/mcp-context-forge/issues/234\n- MCP resources spec (resources/list, resources/read, resources/subscribe confirmed): https://spec.modelcontextprotocol.io/specification/server/resources/\n- Speakeasy MCP roots reference (roots/list, notifications/roots/list_changed): https://www.speakeasy.com/mcp/core-concepts/roots\n- MCP sampling spec (sampling/createMessage): https://spec.modelcontextprotocol.io/specification/2025-03-26/client/sampling/\n- MCP vs A2A protocol comparison: /resources/mcp-vs-a2a\n- MCP server discovery guide: /resources/mcp-server-discovery",
  "sources": [
    "https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts",
    "https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation",
    "https://github.com/IBM/mcp-context-forge/issues/234",
    "https://spec.modelcontextprotocol.io/specification/server/resources/",
    "https://www.speakeasy.com/mcp/core-concepts/roots",
    "https://spec.modelcontextprotocol.io/specification/2025-03-26/client/sampling/"
  ]
}