Most MCP material teaches one capability and mentions the rest. This page takes all five apart, because the difference between them is not what they do — it is who decides, and that turns out to be the thing that matters.
Part 1 · Sort them by who pulls the trigger
Three of them are things your side asks a server for. Two of them are a server asking you for something. Once you sort them that way they stop blurring together.
Here is the same thing as a table you can hold in your head:
| Who decides | On the wire | Costs you | |
|---|---|---|---|
| 🔧 tools | the model | tools/list, tools/call | tokens |
| 📄 resources | the host | resources/list, resources/read | tokens |
| 💬 prompts | the human | prompts/list, prompts/get | tokens |
| 🧠 sampling | the server asks; the host decides | an input_required retry | real money |
| 🙋 elicitation | the server asks; the user answers | an input_required retry | attention |
Part 2 · The three that point the ordinary way
tools
project #1A verb. The server does something, and the MODEL decides to invoke it.
On the wire: tools/list to see what exists, tools/call to run one.
This is 90% of the value and 100% of the tutorials. It is also the only capability projects #1 through #4 ever used.
The spec calls tools model-controlled — the model discovers and invokes
them based on its own reading of the situation. Which is exactly why the
description is the whole ballgame, and why
a human in the loop is a SHOULD:
For trust & safety and security, there SHOULD always be a human in the loop with the ability to deny tool invocations.
resources
project #5A noun. Something to read, with an address rather than arguments — and the HOST decides to show it.
On the wire: resources/list, then resources/read with a URI like
cookiejar://status. Mechanically it is tools/call with a URI instead of
arguments, which is why it took an afternoon to add.
The distinction that is easy to blur and worth keeping sharp:
A tool is something the model decides to invoke. A resource is something the host decides to show it.
Reading a resource is not an action the agent takes. It is context somebody put in front of it.
prompts
project #5A saved fill-in-the-blank instruction that a HUMAN picks off a menu.
On the wire: prompts/list, then prompts/get, which returns messages.
The least glamorous capability, and the one with the clearest ownership story: the server author knows how to ask their own service for things, and the user chooses when to use that knowledge. No model in the loop deciding anything.
Part 3 · The two that point back
Here is what makes these genuinely different, and it is structural rather than a matter of degree.
For tools, resources and prompts, the worst a server can do is give you a bad answer. You asked, it replied, you decide what to do with the reply.
For sampling and elicitation, the server is asking you to spend something — and the thing being spent is yours.
sampling
project #5The server asks YOUR host to run a model call. It has no API key and no model — it has yours.
Why would anyone want this? Because a small server can be smart without being expensive to run. Project #5's kitchen server can read the pantry's whole event log, but it has no language model and no reason to buy one. So it asks the thing that definitely has one — the host that just called it.
The data never leaves the server's control. The intelligence is borrowed.
That is a genuinely good idea. It just moves the cost onto somebody who did not choose it, which is why the host has to hold the ceiling. See A budget is not a gate.
elicitation
project #5The server asks YOUR user a question, mid-call, and waits for the answer.
Same shape as sampling, pointed at a person instead of a model. "What is your GitHub username?" mid-way through a tool call.
It needs no spend gate, because the scarce resource is attention, not money — which does not make it free. A server that elicits three times per call is expensive in exactly the way an over-eager approval gate is expensive.
If you build a host that supports it, the control you want is a rate limit, not a ceiling.
Part 4 · How a server asks, now that it cannot push
This is worth understanding here rather than saving for project #5, because it explains a shape you will see everywhere in the modern protocol.
A server has no way to speak first. There is no open connection to push down — each request is its own POST.
So the modern protocol inverts it. When a server needs something from you, it answers your request with a request:
round 1 → tools/call
← { "resultType": "input_required",
"inputRequests": { "summary": { "method": "sampling/createMessage", … } },
"requestState": "…" }
· you do the thing it asked for
round 2 → tools/call + params.inputResponses + params.requestState
← { "resultType": "complete", "content": [ … ] }This is called multi round-trip requests, and as of 2026-07-28 it is not
an alternative — it is the only way:
Servers MUST send server-to-client requests (such as
roots/list,sampling/createMessage, orelicitation/create) using the MRTR pattern. The previous pattern of server-initiated requests is no longer supported. This is a breaking change.
Part 5 · Only one of five, for four projects
Here is the honest scorecard as project #5 opened:
| Capability | Used in projects #1–#4 |
|---|---|
| tools | ✅ all four projects |
| resources | ❌ never |
| prompts | ❌ never |
| sampling | ❌ never |
| elicitation | ❌ never |
What you now know
- Sort the five by who pulls the trigger: model, host, human — then the two where the server asks.
- Resources are the underrated one, because most of what an agent needs is context rather than an action.
- A server-supplied prompt is an offer; splicing it into your model's conversation builds a prompt-injection channel.
- Sampling and elicitation spend your money and your user's attention.
- Servers cannot push any more. They answer with
input_requiredand you retry — and that is aMUSTas of2026-07-28. - Capabilities are declared per request, which makes the dangerous ones opt-in and selectable per server.