MCP's primitives split cleanly into two trios. The server side publishes capabilities the host can use. The client side publishes capabilities the server can ask for. The symmetry is intentional and worth holding in your head before you dive into any single primitive.
| Server features (server → host) | Client features (host → server) |
|---|---|
| Resources — read-only data the host can fetch | Sampling — server asks the host's LLM to think on its behalf |
| Prompts — templated workflows the user can invoke | Roots — server asks the host which directories/URIs are in scope |
| Tools — callable functions with side effects | Elicitation — server asks the host to ask the user for input |
The split keeps responsibility clear. Servers expose capabilities they own; clients expose capabilities only the host can fulfill. A server cannot run an LLM (it does not have one) so sampling has to be a client capability the server requests. A client cannot enumerate tables in a database it has never seen, so resources are a server capability the client fetches.
Memorize the trio split, then forget the table — what you actually want in your head is "if I have this functionality, where does it live?" Read-only data → Resource. User-invokable workflow → Prompt. Side-effectful action → Tool. LLM call requested by server → Sampling. Filesystem boundary → Roots. Pop a question to the user → Elicitation.