At the core of the Model Context Protocol is the mechanism for grounding Large Language Models in specific, external data. While the architecture defines how components connect, Resources define what those components know. A Resource represents a specific item of data that an MCP server exposes to a client. This data serves as the context window content that enables an LLM to answer questions about your specific codebase, database, or internal documentation.In standard software engineering terms, you can view a Resource similarly to a GET endpoint in a REST API. It is a read-only interface designed to be consumed by the client application. However, unlike a typical API designed for programmatic consumption, MCP Resources are specifically structured to be consumed by LLMs, providing metadata and content formats that models can easily ingest and reason about.The Anatomy of a ResourceA Resource in MCP is not merely a raw string of text. It is a structured object containing three primary components that allow the client to identify, retrieve, and interpret the data.URI (Uniform Resource Identifier): This is the unique address of the resource. It follows standard URI syntax and serves as the primary identifier for accessing data. The scheme of the URI often indicates the nature of the data source, such as file:///logs/error.txt or postgres://users/schema.Name: A human-readable identifier that describes the resource. This is particularly important for the User Interface of the client, allowing users to select which context they wish to attach to a conversation.MIME Type: This indicates the format of the content, such as text/plain, application/json, or image/png. The MIME type informs the client how to process or render the data before feeding it to the model.Formally, we can define a resource $R$ as a tuple containing these elements, along with the actual data payload when read:$$R = (u, n, m, c)$$Where $u$ is the URI, $n$ is the name, $m$ is the MIME type, and $c$ is the content blob. The server is responsible for maintaining the mapping between the URI $u$ and the content $c$.The Resource LifecycleThe interaction between a client (such as Claude Desktop or an IDE) and an MCP server regarding resources follows a specific discovery and retrieval pattern. The client does not automatically ingest all data available on the server, as this would overwhelm the context window. Instead, the protocol dictates a "list then read" workflow.First, the client requests a list of available resources. The server responds with a directory of what it exposes, including URIs and names, but excluding the heavy content. The user or the LLM then selects specific resources relevant to the current task. Finally, the client issues a read request for those specific URIs to retrieve the full content.digraph G { rankdir=TB; bgcolor="#ffffff"; node [shape=rect, style="filled,rounded", fontname="Arial", fontsize=10, margin=0.2]; edge [fontname="Arial", fontsize=9, color="#868e96"]; subgraph cluster_0 { label=""; style=invis; Client [label="MCP Client\n(Host Process)", fillcolor="#a5d8ff", color="#1c7ed6", penwidth=2]; } subgraph cluster_1 { label=""; style=invis; Server [label="MCP Server\n(Resource Provider)", fillcolor="#b2f2bb", color="#37b24d", penwidth=2]; } Data [label="Underlying Data\n(Files/DB/API)", fillcolor="#fcc2d7", color="#d6336c", shape=cylinder]; Client -> Server [label="1. resources/list request", color="#4dabf7"]; Server -> Client [label="2. List of Resource Templates", color="#40c057"]; Client -> Server [label="3. resources/read(uri)", color="#4dabf7"]; Server -> Data [label="4. Fetch", style="dashed", color="#adb5bd"]; Data -> Server [label="5. Raw Content", style="dashed", color="#adb5bd"]; Server -> Client [label="6. ResourceContent (Text/Binary)", color="#40c057"]; }The sequence diagram demonstrates the separation between discovery (listing) and retrieval (reading). This lazy-loading approach optimizes bandwidth and context window usage.Static vs Dynamic ResourcesResources in MCP are versatile. They can represent static files on a disk, or they can represent dynamic data generated on demand.Static Resources maps directly to fixed data. An example is a server exposing a log file or a configuration document. When the client reads file:///project/config.json, the server opens the file, reads the bytes, and sends them back. The content only changes if the file on the disk changes.Dynamic Resources are computed or fetched at the moment of the request. A resource with the URI weather://current/sf does not point to a file. Instead, when the client requests this URI, the server's internal logic triggers an API call to a weather provider, formats the result, and returns it as the resource content. To the client and the LLM, there is no functional difference between reading a file and reading a dynamic system state; both are simply text returned from a URI.Differentiating Resources from ToolsA common point of confusion for developers new to MCP is the distinction between Resources and Tools. Both involve data transfer, but their intent is fundamentally different.Resources are passive. They represent a "read" operation. Reading a resource should be idempotent, meaning that reading it multiple times does not change the state of the system (aside from perhaps logging access). Resources provide context to help the LLM understand the context.Tools are active. They represent executable functions that can perform "write" operations or complex logic that requires parameters. A Tool might be execute_sql_query(query) or send_slack_message(channel, text). These are actions the LLM decides to take based on the context provided by the Resources.You should define data as a Resource when:The data is read-only.The data acts as reference material (code, logs, documentation).The data does not require complex arguments to retrieve (it is addressable by a single URI).You should define functionality as a Tool when:The operation has side effects (modifies a database, sends an email).The operation requires multiple arguments (e.g., searching a database with specific filters).The output is a result of an action rather than the state of an object.Resource TemplatesIn many scenarios, a server may contain thousands of similar items, such as rows in a database table or tickets in a support system. Listing every single item individually in the resources/list response is inefficient and often impossible.MCP solves this with Resource Templates. Instead of listing static URIs, the server exposes a URI pattern containing variables, such as postgres://users/{id}/profile. This informs the client that it can construct a valid URI by substituting {id} with a specific user ID. While the LLM cannot "browse" these as a list, it can hallucinate (construct) a valid URI based on the pattern if it knows the ID from a previous context, enabling direct access to granular data without directory bloat.By standardizing how data is identified and retrieved, Resources allow developers to create a universal context layer. Whether the data comes from a local file system, a cloud database, or a live API, the MCP Resource primitive normalizes it into a format that enhances the intelligence and utility of the connected AI model.