The five capabilities sorted them by who pulls the trigger. This page is the verdict after building all of them.
π§ tools β 90% of the value and 100% of the tutorials
Everything in projects #1 through #4 is tools. Four projects, an approval gate, a crew of sub-agents, a whole cost-measurement apparatus β one capability.
That ratio is not a criticism. Tools genuinely are where the value is, and the tutorials are right to concentrate on them.
π resources β what you'll actually reach for, and nobody demos it
The boring one. resources/list, then resources/read with a URI. It is
tools/call with an address instead of arguments, and it took an afternoon.
A tool is something the model decides to invoke. A resource is something the host decides to show it.
And that is why it matters more than its reputation: most of what an agent needs is not an action. It is context β the current config, the schema, the open tickets, the file you are looking at. Making that a tool means the model has to decide to go and get it, spend an iteration doing so, and pay for the round trip. Making it a resource means the host just puts it in front of the model.
π¬ prompts β the least glamorous and the most sensible
prompts/list, prompts/get, returns some messages. A saved fill-in-the-blank
instruction that a human picks off a menu.
It is the capability least likely to appear in a demo, and it is 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.
π§ sampling β it changes the relationship
This is the one that is genuinely different, and it is the reason project #5 exists.
Every server in the first four projects was a vending machine: request in, result out, and it costs you exactly what you put in. Sampling makes the server a contractor with your account number. It has no API key and no model. It has yours.
Two things to carry, if you implement it:
The naive version does not work on serverless. Every tutorial shows
server.createMessage(), a serverβclient push. A push needs a connection; a
serverless function has a request and then it doesn't. The modern protocol era
replaced it with a retry. See The finding.
The danger is opt-in, and one line wide. The host declares
capabilities: { sampling: {} }. Delete it and every sampling request from
every server fails at the protocol layer β before your gate, your estimate or
your ledger is involved.
The safest configuration is one character shorter than the useful one.
π elicitation β costs nothing, needs no gate
The server asks your user a question, mid-call, and waits. Same multi-round-trip shape as sampling, pointed at a person instead of a model.
It is the only capability that needs no spend gate, and the reason is worth stating precisely: the scarce resource here is attention, not money.
Project #5 built the plumbing and one tool that uses it (discard_batch).
Only the browser UI is missing, which is the honest status: the protocol half
works, and nobody has designed the interruption yet.
The summary table
| Capability | Reach for it when | Watch out for |
|---|---|---|
| π§ tools | the model should decide to act | the description is the whole ballgame |
| π resources | the host knows what context is needed | nobody demos it, so you will forget it exists |
| π¬ prompts | a human should pick a saved recipe | it is an offer, not an instruction |
| π§ sampling | a server needs intelligence it cannot afford | the push doesn't work; gate on the estimate |
| π elicitation | the server needs a human decision mid-call | attention is the budget |