DevLearningTools

LEARN · AI CONCEPTS

Tools vs Resources

The three things an MCP server can actually expose, tools, resources, and prompts, what each one is genuinely for, and how to tell which one a given feature should actually be.

An MCP server can expose three distinct kinds of things, each meant for a different purpose. Getting the choice right matters: exposing a side-effecting action as a resource, or read-only data as a tool, works against the protocol's own design rather than with it.

Learning Objectives

  • Define tools, resources, and prompts precisely, per the specification.
  • Give a concrete example of each from a real reference server.
  • Decide which primitive a new server feature should actually be.

The Three Primitives

PrimitiveDefinitionWho typically triggers it
ToolsFunctions the AI model can execute, with real side effectsThe model, deciding a call is needed
ResourcesContext and data made available for the user or the model to useThe application, surfacing it as available context
PromptsTemplated messages and workflows for usersThe user, selecting a pre-built prompt

Tools

actions, model decides

Resources

data, for context

Prompts

reusable templates

Tool Example: Creating a GitHub Issue

A tool call
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "create_issue",
    "arguments": {
      "repo": "devlearningtools/site",
      "title": "Footer link broken on mobile",
      "body": "Reported by a user, needs triage."
    }
  }
}
NOTE

This has a real side effect, a new issue actually gets created in the repository. That's exactly what marks it as a tool rather than a resource, tools do something; they don't just describe something.

Resource Example: Reading a File's Content

A resource read
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/read",
  "params": { "uri": "file:///logs/error.log" }
}
NOTE

This has no side effect, it just retrieves data (the file's current content) to be used as context. Reading the same resource twice in a row causes no harm and produces the same result, assuming the file hasn't changed.

Prompt Example: A Reusable Template

A prompt definition
{
  "name": "summarize_pr",
  "description": "Summarize a pull request for a team update",
  "arguments": [{ "name": "pr_number", "required": true }]
}
NOTE

A user might select this prompt from a menu in the host application, fill in a PR number, and the host expands it into a full, well-structured message. It's a convenience for the user, not something the model decides to invoke mid-task the way it does with a tool.

Common Beginner Mistakes

  • Exposing a side-effecting action (sending an email, deleting a record) as a resource, when anything that changes real state belongs as a tool.
  • Exposing static, read-only reference data as a tool when it would fit more naturally as a resource, adding unnecessary decision-making overhead for the model.
  • Assuming prompts are for the model, they're specifically templated workflows meant for the user to select, not something the model calls on its own.
  • Forgetting that tool descriptions from an untrusted server should be treated cautiously, the specification explicitly calls this out as a real security consideration.

FAQ

Can a single server expose all three primitives at once?

Yes, a server isn't limited to just one kind, a GitHub server, for example, could expose tools (create_issue), resources (a specific file's content), and prompts (a summarize_pr template) all at once.

What's the deciding factor between making something a tool versus a resource?

Whether it causes a side effect. An action that changes real state (creates, updates, deletes, sends) should be a tool. Data that's simply read, with no side effect from reading it, fits as a resource.

Do prompts require the model to do anything special?

No, they're primarily a user-facing convenience, a template the host application surfaces for a user to select and fill in, rather than something the model autonomously decides to invoke during a task.

Interview Questions

Define tools, resources, and prompts as MCP defines them.

Tools are functions the AI model can execute, with real side effects. Resources are context and data made available for the user or model to use, without side effects. Prompts are templated messages and workflows meant for users to select.

You're adding a feature that deletes a stale cache entry. Should it be a tool or a resource, and why?

A tool, since deleting something is a side-effecting action that changes real state, exactly what tools are meant to represent. A resource should be safe to read repeatedly with no consequence.

Why does the specification specifically warn about tool descriptions from untrusted servers?

A tool represents arbitrary code execution once invoked, so a malicious or careless description could mislead a model (or a user approving the call) about what the tool actually does. The spec treats tool descriptions from untrusted servers as inherently unreliable unless they come from a trusted source.

Give a concrete example of each primitive from a single real server.

A GitHub server could expose create_issue as a tool (a real side effect), a specific file's content as a resource (safe, repeatable read), and a summarize_pr template as a prompt (a user-selected workflow).

Summary

An MCP server exposes up to three kinds of things: tools (side-effecting actions the model can execute), resources (read-only data and context), and prompts (user-selected templated workflows). The deciding factor between a tool and a resource is whether it causes a real side effect, not how complex it is to implement.

What's Next?

The next lesson puts everything together: a complete, realistic MCP workflow from a user's request to a tool actually executing and returning a result.