The three primitives: tools, resources, and prompts
The three things a server can expose, who controls each, and when to reach for which.
An MCP server exposes capability through three primitives. The distinction between them isn't cosmetic — it's about who decides to use each one.
Tools — model-controlled. Tools are executable functions the model can choose to call: search_orders, send_email, run_query. The model decides when to invoke one based on the task. Tools have JSON Schema inputs (the current spec uses JSON Schema 2020-12), and the protocol methods are tools/list (discover) and tools/call (invoke). If you take one thing from this lesson: tools are where the action is, and because the model triggers them, they're also where the risk is.
Resources — application-controlled. Resources are read-only data addressed by a URI, like file:///logs/today.txt or db://customers/42. They're application-controlled: the host decides what to pull into context, not the model. Resources support URI templates with parameters, so one definition can serve a whole family of addresses. Methods: resources/list, resources/templates/list, resources/read.
Prompts — user-controlled. Prompts are reusable templates, often surfaced to the user as slash commands ("/summarize-thread"). The user chooses to invoke them. Methods: prompts/list, prompts/get.
The mental model: **tools do, resources provide, prompts *guide*** — controlled by model, app, and user respectively.
There's also a client-side primitive worth knowing: elicitation. When your server needs input mid-task — a confirmation, a missing parameter — it uses elicitation to ask the user through the client. It has a form mode (schema-driven UI) and a URL mode for sensitive flows like OAuth, where the data never passes through the client or the model. Form mode must never be used for passwords, tokens, or payment info.
Two primitives you'll see in old tutorials — sampling (server asks the model to generate) and roots (client shares directories) — are deprecated in the current spec. They still work during a 12-month window, but new servers should avoid them: pass files via tool params or resources, and call an LLM provider directly instead of sampling.
For a 'customer support' server, sort these into tool / resource / prompt: (a) look up an order by ID, (b) the returns policy document, (c) a 'draft an apology email' template. Justify each by who controls it.
Enjoying the free lessons? Get an email when we publish new courses and updates — no spam, unsubscribe anytime.
Discussion (0)
Ask a question or share what worked for you. Comments are reviewed before they appear.
No comments yet. Be the first to start the discussion!