Tool, resource or prompt? Choosing the right MCP primitive

Tool, resource or prompt? Choosing the right MCP primitive

Most early Model Context Protocol (MCP) servers made everything a tool. That handed the model decisions that belonged to the user or the application, and made those servers harder to use and harder to secure. The way out starts with one question for every capability: who decides when it’s used?

This is part 12 of my series on what an MCP server does under the 2026-07-28 specification. Part 11 covered prompts, the last of the three primitives a server offers. This part puts them side by side with the other mechanisms a server has, and gives a procedure for choosing between them. The facts are as I read them in October 2026.

In brief

  1. Tools, resources and prompts differ mainly in who decides when they’re used: the model calls a tool, the application attaches a resource, and the user picks a prompt.
  2. Four more mechanisms sit beside them: server instructions, and the Skills, MCP Apps and Tasks extensions, each with its own trigger and its own point at which it loads.
  3. Two of those four depend on the host: whether server instructions reach the model is up to it, and a skill loads when it’s selected, after an approval step the host may add and must add in a few cases, such as running code.
  4. A short run of yes-or-no questions, asked in order, tells you where a new capability belongs: the first asks whether the model must always know it, the last whether the result needs interaction to be useful.
  5. Build in layers, because host support is uneven: the core value in tools with good text output, the guidance in instructions and prompts, and the richer experience in extensions that degrade cleanly.

Who decides when

Each of the three primitives has a different party deciding when it’s used:

  • A tool is a function with a schema. The model calls it with tools/call while it reasons. Part 8 covers how to define one.
  • A resource is context identified by a Uniform Resource Identifier (URI). The application reads it with resources/read, and the host attaches it as context. Part 10 covers resources.
  • A prompt is a reusable template. The user usually runs it as a slash command or picks it from a menu, and the host fetches it with prompts/get.
Model decides: Tools functions with schemas, tools/call, Model calls it while reasoning; Application decides: Resources context by URI, resources/read, Host attaches it as context; User decides: Prompts reusable templates, prompts/get, User runs a slash command; Tools functions with schemas → tools/call; tools/call → Model calls it while reasoning; Resources context by URI → resources/read; resources/read → Host attaches it as context; Prompts reusable templates → prompts/get; prompts/get → User runs a slash commandModel decidesApplication decidesUser decidesToolsfunctions with schemastools/callModel calls itwhile reasoningResourcescontext by URIresources/readHost attaches itas contextPromptsreusable templatesprompts/getUser runsa slash command

Some utilities sit underneath all three: pagination, caching hints and list_changed notifications. Completion is narrower: it suggests values for prompt arguments and resource-template arguments.

My advice, when you design a new server: list its capabilities first and put each one in the column of whoever decides. That question, who decides, drives most of the design choices that follow.

Seven mechanisms side by side

Server instructions and three extensions add further options. Here they are with the three primitives:

MechanismWho triggers itLoaded whenSide effectsTypical use
ToolModelWhen the model calls itYes, potentiallyQueries, actions, computations
ResourceApplication or userWhen attached or readNo (read-only)Documents, schemas, records, large outputs
PromptUserWhen the user picks itNo (it produces messages)Workflow starters, expert templates
Server instructionsThe host, with no model or user actionWhen the host connects, if it loads themNoOrientation and rules for using the tools together
Skill (extension)Model or userWhen selected; the host may ask for approval firstOnly through the tools it usesMulti-step procedures with reference files
MCP App (extension)Model, through a toolWhen the linked tool returnsThrough tools the app can callInteractive user interface: charts, forms, viewers
Task (extension)Server, per requestWhen work is long-runningYes, potentiallyBatch jobs, long research, jobs handed to an external application programming interface

Two rows need care.

Server instructions are an optional field of the server/discover result, and calling server/discover is itself optional for a client. Hosts that support instructions load them when they connect (Claude Code loads them at session start, as of October 2026), but that’s host behaviour, not a protocol guarantee. Part 4 covers what to write in them.

A skill loads when the model or the user selects it. The Skills overview lets a host ask for the user’s approval first, and makes approval mandatory only for running code, allowed-tools grants, reads across servers and activating nested skills.

A decision procedure

When a new capability comes along, I ask these questions in order:

New capability → Must the model always know it, on every turn?; Must the model always know it, on every turn? → Server instructions: yes; Must the model always know it, on every turn? → Is it a workflow the user starts on purpose?: no; Is it a workflow the user starts on purpose? → Does it need supporting files or several steps the model could also pick on its own?: yes; Does it need supporting files or several steps the model could also pick on its own? → Prompt: no; Does it need supporting files or several steps the model could also pick on its own? → Skill and a prompt as fallback: yes; Is it a workflow the user starts on purpose? → Is it read-only context identified by a URI?: no; Is it read-only context identified by a URI? → Resource + template, + subscription if live: yes; Is it read-only context identified by a URI? → Should the model decide when to do it?: no; Should the model decide when to do it? → Rethink: maybe a resource the host attaches: no; Should the model decide when to do it? → Tool: yes; Tool → Can it take longer than about a minute?; Can it take longer than about a minute? → Tool returning a Task: yes; Can it take longer than about a minute? → Does the result need interaction to be useful?: no; Does the result need interaction to be useful? → Tool + MCP App with text fallback: yes; Does the result need interaction to be useful? → Plain tool: noNew capabilityMust the modelalways know it,on every turn?Server instructionsIs it a workflowthe user startson purpose?Is it read-onlycontext identifiedby a URI?Does it needsupporting filesor several stepsthe model could alsopick on its own?Resource+ template,+ subscription if liveShould the modeldecide whento do it?PromptSkilland a prompt as fallbackRethink:maybe a resourcethe host attachesToolCan it takelonger thanabout a minute?Tool returning a TaskDoes the resultneed interactionto be useful?Tool + MCP Appwith text fallbackPlain toolyesnoyesnoyesnoyesnonoyesyesnoyesno

Put as rules, the branches come to this:

  • Server instructions are for guidance the model needs every time, in the hosts that load them.
  • A prompt is for a workflow the user starts on purpose and that benefits from your server’s expertise. It can also be a reliable entry point into a workflow of several tools: “call search with these filters, then fetch the top three, then summarize as a table”.
  • A skill is for a procedure of several steps, with supporting files, that the model may also pick on its own. A prompt can stand in for it where skills aren’t supported.
  • A resource is for read-only context identified by a URI, with a template, and a subscription if it’s live.
  • A tool is for anything the model should decide to do, and for anything with side effects.

If a capability isn’t a workflow the user starts, isn’t read-only context and isn’t something the model should decide, take a second look at it: it may be a resource the host attaches after all.

The one-minute question is my rule of thumb, not the specification’s. The Tasks overview speaks of long-running operations that take minutes or hours. It also warns that many clients and transport intermediaries impose timeouts that make blocking impractical beyond a few seconds, which suggests a lower bar than a minute.

The last question adds an MCP App on top of a tool when the result only becomes useful through interaction. The tool still returns text, so a host without Apps gets something it can show.

Worked example: an engineering-docs server

Here is the procedure applied to a server for internal engineering documentation, the same kind of server as the instructions example in part 4:

CapabilityMechanismWhy
“Use search_docs before fetch_doc; content refreshes nightly”Server instructionsAlways relevant, short
Search the docsTool search_docs (read-only)The model decides when to search
Read a full documentTool fetch_doc, plus a resource_link / docs:// resourceThe model can fetch, and hosts can attach
Browse documents by areaResource template docs://{area}/{slug}Host-driven browsing with completion
“Write an architecture decision record (ADR) from this discussion”Prompt write_adrThe user starts it deliberately
Incident-response runbook with checklists and scriptsSkill incident-runbookMulti-step procedure with supporting files
Visual dependency graph of servicesTool + MCP AppInteractive exploration
Re-index the whole corpusTool returning a TaskTakes many minutes

One capability can use two mechanisms, as reading a full document does.

My advice is to expect uneven host support and build in layers. Tools work everywhere, prompts and resources in most hosts that behave like an integrated development environment, and Skills, Apps and Tasks only where they’re negotiated. So the core value goes into tools with good text output, the workflow guidance into instructions and prompts, and the richer experience into extensions that degrade cleanly. A host that supports only tools still gets the core value, and each layer it supports adds to it.

Method and caveats

  • Built from chapter 12 of my guide to MCP servers, with the advice on when to use prompts from chapter 11 and the control model from chapter 3, written against the 2026-07-28 specification. Product facts are as of October 2026.
  • The order of the questions, the time threshold for a Task and the layering are my own advice, not the specification’s. Skills, MCP Apps and Tasks are opt-in extensions, and each is covered later in this series.
  • Where the specification and the extension documentation are more precise than my notes (whether instructions reach the model, and when a skill needs approval), this article follows the server/discover page and the Skills overview.
Series What an MCP server actually does in 2026 Part 12 of 35
  1. What an MCP server does in 2026: much more than a list of tools
  2. MCP goes stateless: what changed in the 2026-07-28 specification
  3. server/discover: the one method every MCP server must implement
  4. Server instructions: the paragraph every model reads first
  5. Stateless MCP requests: _meta, resultType and explicit handles
  6. Caching hints and pagination in MCP
  7. MCP transports in 2026: stdio and Streamable HTTP
  8. Designing an MCP tool: the definition and the result
  9. MCP tool errors, and tools that models use well
  10. MCP resources: context the application decides to use
  11. MCP prompts: slash commands your server ships
  12. Tool, resource or prompt? Choosing the right MCP primitive

I’m Amir Pournasserian. I build AI and platform systems for a living, maintain FluentCMS and YeSvelte, and write here about what I find along the way.