Understanding MCP: Tools, Resources, and Prompts
The Model Context Protocol, or MCP, is an open protocol for connecting AI models to external tools, data, and services.
Before MCP, every integration between a model and an external system was custom work, wired by hand for one client and one backend at a time.
MCP replaces that one-off wiring with a shared contract, so a single server implementation can expose its capabilities to any MCP-compatible client without rewriting the integration each time.
That contract is built from three primitives, and understanding what each one is for is the first step toward designing a good MCP server.
Summary
- Core Idea: MCP standardizes how an AI model discovers and uses external capabilities through three primitives: Tools, Resources, and Prompts.
- Why It Matters: Without a shared protocol, every model-to-system integration is bespoke, brittle, and locked to one client.
- Key Concepts: Tools (callable functions), Resources (readable, URI-addressed data), Prompts (reusable parameterized templates), client-agnostic design, discovery.
- When to Use: Reach for MCP when a capability needs to be usable across more than one AI client, when you want a stable contract between your systems and any model, or when you are building a server meant to outlive a single integration.
- Limitations / Trade-offs: MCP adds a layer of schema and protocol overhead compared to hardwiring a function call directly into one application.
- Related Topics: function calling, tool schemas, resource URIs, prompt templates, transport selection.
Foundations
At its center, MCP defines a client-server relationship.
An MCP client, such as Claude Code, Claude Desktop, Cowork, or a custom application built on the Agent SDK, connects to an MCP server.
The server advertises what it can do, and the client (and the model behind it) decides when and how to use those capabilities.
What the server advertises falls into exactly three categories.
Tools are callable functions.
A tool has a name, a description, and a schema describing its inputs, and when the model decides to use it, the client sends a call and the server returns a result.
This is conceptually the same idea as function calling in a typical LLM API, just standardized so any MCP client can discover and invoke it the same way.
Resources are readable data, not actions.
A resource is anything addressable by a URI: a file on disk, a row in a database, the response from an internal API, a configuration value.
Instead of the model calling a function to fetch data, the client can read a resource directly, similar to how a browser fetches a URL.
Prompts are reusable, parameterized prompt templates.
A prompt template packages up instructions, perhaps with placeholders for arguments, so that multiple clients can invoke the exact same well-tested prompt instead of each one improvising its own phrasing.
Think of prompts as the server's way of saying "here is the correct way to ask for this," shared once and reused everywhere.
A simple mental anchor: Tools are verbs, Resources are nouns, and Prompts are scripts.
Mechanics & Interactions
The relationship between these three primitives becomes clearer once you consider how a client actually uses a server during a session.
When a client connects, it asks the server what it offers, and the server responds with lists of its tools, resources, and prompts, each with metadata the client can present to the model or a user.
For tools, that metadata is a schema: the tool's name, a natural-language description, and a structured definition of its expected arguments.
The model reads these descriptions and schemas to decide, during a conversation, whether calling a particular tool would help answer the current request.
For resources, the client can list available URIs and read their contents, either because the model requested it or because the surrounding application chose to attach that context directly.
For prompts, the client (or a user) selects a named prompt, optionally supplies arguments, and receives back a fully formed set of messages ready to send to the model.
A single server usually mixes all three.
A documentation server, for example, might expose a search_docs tool, a docs://page/{id} resource for reading an individual page, and a summarize_page prompt that always asks the model to summarize a page the same well-tuned way.
# Illustrative shape only - see the "Defining Callable Tools" and
# "Exposing Readable Data as MCP Resources" pages for full server code.
server.tool("search_docs", handler=search_docs_handler)
server.resource("docs://page/{id}", handler=read_page_handler)
server.prompt("summarize_page", handler=summarize_prompt_handler)The important mechanical distinction is who initiates the exchange and what kind of result comes back.
A tool call is model-initiated and returns a result that becomes part of the conversation.
A resource read can be model-initiated or client-initiated, and it returns data, not a computed outcome.
A prompt invocation is typically user- or client-initiated and returns message content meant to seed or steer a conversation, not raw data or a side effect.
Advanced Considerations & Applications
The reason MCP defines three primitives instead of just "functions the model can call" is that ordinary function calling only covers the Tools case, and it does so in a way that is tightly bound to one API and one client.
If you have used function calling directly against a model API, you have already built something like an MCP tool, just without the standardized schema format, without discovery, and without portability to other clients.
MCP takes that same idea and adds a protocol envelope around it, plus two more primitives that function calling alone does not address well: bulk or structured data access (Resources) and shared, versioned instructions (Prompts).
This distinction matters most once a server needs to serve more than one client.
A tool implemented as a one-off function inside a single application has to be reimplemented, and can drift out of sync, if a second application wants the same capability.
An MCP tool defined once in a server is immediately available, with the same schema and behavior, to any client that connects to that server, whether that is Claude Code on a developer's machine or a custom Agent SDK application in production.
| Approach | Strength | Weakness | Best Fit |
|---|---|---|---|
| Ordinary function calling | Simple, no extra layer, fastest to prototype | Bound to one client and one API integration | A single application that will never share the capability |
| MCP Tool | Reusable across any MCP client, standardized schema and discovery | Requires running or connecting to a server, more moving parts | Capabilities multiple clients or teams need |
| MCP Resource | Clean separation of "read data" from "take action," cacheable | Not suited to anything that has side effects | Files, database rows, API responses the model should read |
| MCP Prompt | Consistent, versioned instructions across clients | Another artifact to design and maintain | Shared workflows where wording quality matters |
Choosing the right primitive for a given capability is itself a design decision worth taking seriously.
Exposing a read-only data source as a tool instead of a resource works, but it hides from the client that the operation is safe to cache and has no side effects.
Conversely, exposing something with side effects, like sending an email, as a resource would be misleading, since resources are meant to be read, not executed.
Getting this classification right up front makes a server's behavior predictable to any client that connects to it later, including clients you did not build yourself.
Common Misconceptions
- "MCP tools are just function calling with extra steps." The underlying call-and-respond mechanic is similar, but the protocol layer is what makes a tool usable by any compatible client rather than one hardwired integration.
- "Resources and tools are interchangeable if a tool can just return data." A tool that only reads data still carries the implication of an action; a resource is explicitly addressable and cacheable in a way a tool call is not.
- "Prompts are optional extras that most servers skip." Prompts matter most exactly when consistency across clients matters, such as a shared support workflow or a standardized code review instruction.
- "An MCP server has to expose all three primitives." A server can expose only tools, only resources, only prompts, or any combination; nothing requires all three.
- "MCP is a Claude-specific feature." MCP is an open protocol; it happens to be well supported by Claude Code, Claude Desktop, and the Agent SDK, but any MCP-compatible client can use a conforming server.
FAQs
What problem does MCP actually solve that function calling doesn't?
- Function calling ties one model integration to one set of hand-written functions in one application.
- MCP standardizes the contract (schemas, discovery, invocation) so the same server works across any compatible client without rewriting the integration.
Are MCP tools the same thing as function calling?
Conceptually yes, tools are the MCP equivalent of function calling. The difference is that a tool's schema and behavior are defined once in a server and discoverable by any client, rather than hardcoded into a single application's integration code.
When should something be a Resource instead of a Tool?
- Use a Resource when the operation is a read with no side effects, like fetching a file, a database row, or an API response.
- Use a Tool when the model needs to take an action or perform a computation, even if that action also returns data.
What exactly is a Prompt in MCP terms?
A Prompt is a reusable, parameterized template that produces a set of messages ready to send to a model. It lets a server package a well-tested instruction once so every client that invokes it gets the same consistent wording.
Does every MCP server need to define all three primitives?
No. A server can expose only tools, only resources, only prompts, or any mix of the three, depending on what capabilities it needs to share.
Who initiates a resource read versus a tool call?
- A tool call is initiated by the model during a conversation, based on the tool's description and schema.
- A resource read can be initiated by the model or directly by the client application attaching context.
Can the same MCP server serve both Claude Code and a custom application?
Yes. That client-agnostic design is a core goal of MCP: a single server implementation can serve Claude Code, Claude Desktop, Cowork, and custom Agent SDK applications without changes.
What happens if I expose a side-effecting operation as a Resource?
It works mechanically, but it misleads any client that assumes resources are safe to read repeatedly or cache, since resources are meant to represent readable data, not actions with consequences.
Is a Prompt the same as a system prompt?
Not quite. An MCP Prompt is a named, parameterized template a client explicitly selects and invokes, often with arguments, rather than a fixed instruction silently prepended to every conversation.
Why does discovery matter for MCP tools?
- Discovery lets a client ask a server what capabilities it offers before using them.
- Without discovery, a client would need hardcoded knowledge of every tool, resource, and prompt a server supports, defeating the point of a shared protocol.
Is MCP only useful for local development tools?
No. MCP servers can run locally over stdio for local tools, or remotely over HTTP/SSE for hosted, shared servers; the protocol itself does not assume one deployment style.
How do I decide whether a new capability belongs in my MCP server at all?
- Ask whether more than one client or workflow will need it; if so, an MCP primitive is a good fit.
- Ask whether it fits cleanly as an action (Tool), readable data (Resource), or a reusable instruction (Prompt); if it fits none of the three, it may not belong in this server.
Related
- MCP Core Concepts Basics - a hands-on walkthrough defining a single tool and connecting a client over stdio.
- Defining Callable Tools in an MCP Server - how to write tool schemas and handlers in depth.
- Exposing Readable Data as MCP Resources - how to serve files, rows, and API responses as resource URIs.
- MCP Tools vs Resources vs Prompts Comparison - a side-by-side comparison for choosing the right primitive.
- Building Reusable Prompt Templates with MCP Prompts - packaging parameterized prompts for multiple clients.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the current Model Context Protocol specification. Model names, SDK versions, and the MCP spec move quickly - verify current specifics at platform.claude.com/docs and modelcontextprotocol.io before relying on them.