Skip to main content

MCP Resources: Engineering Contextual Knowledge for Production AI Agents

What Are MCP Resources

MCP Resources are a core primitive of the Model Context Protocol (MCP) that allow servers to expose read‑only, structured data to AI agents—data that provides context to language models, such as files, database schemas, application‑specific information, or real‑time system metrics. Each resource is uniquely identified by a URI and can contain either text or binary data.

Crucially, resources do not execute logic or generate dynamic outputs. Unlike tools (actions the agent can perform) or prompts (templated workflows), resources are simply retrieved by the client and used as static or semi‑static context. An agent reads a resource; it calls a tool.

The distinction has profound engineering implications: because resources are read‑only and side‑effect‑free, they can be aggressively cached, replicated across regions, and served with far lower latency than tools. They are the mechanism by which an agent grounds itself in your organisation’s knowledge without risk of unintended mutations.

Why MCP Resources Matter

In production AI systems, context is not a luxury—it is the difference between correct action and hallucination. MCP resources address three fundamental problems that plague ad‑hoc context injection:

ProblemWithout MCP ResourcesWith MCP Resources
Context bloatEvery prompt includes huge documentation blocks, straining token budgets.Agents discover and retrieve only what they need, on demand.
Stale informationHardcoded context quickly becomes outdated.Resources can be updated centrally; clients are notified of changes.
No discoverabilityThe agent has to guess what information exists.resources/list provides a dynamic catalogue.
Inconsistent deliveryDifferent agents embed context in incompatible ways.Standardised URI scheme and MIME types.
Security blind spotsContext flows through prompts; no audit trail of what was accessed.Every resources/read is logged and authenticated.

Practical impact: By serving documentation, policies, database schemas, and configuration as MCP resources, you give agents the data they need—on demand, with full user control, and without bloating prompt templates.

MCP Capability Model: Resources vs Tools vs Prompts

Understanding the MCP capability model is essential to designing a clean, maintainable server. These three primitives serve fundamentally different purposes:

ComponentPurposeDirectionSide EffectsWhen to Use
ToolsExecute actions, run functions, trigger workflowsAgent → External systemYes (write, delete, send)Real‑time queries, state changes, API calls
ResourcesProvide read‑only context, documentation, factsExternal system → AgentNo (read‑only)Static knowledge, configuration, reference data
PromptsGuide conversation with reusable templatesAgent internalNo (orchestration)Structured workflows, multi‑step tasks

Think of the relationship this way: Tools = Actions (what the agent does), Resources = Context (what the agent knows), Prompts = Instructions (how the agent should act).

For example, a customer support agent might:

  • Read a resource containing the company refund policy.
  • Call a tool to execute the refund.
  • Use a prompt to structure the manager approval request.

Mixing these responsibilities leads to brittle architectures. Do not expose a database record as a tool unless the agent must modify it. Do not embed static documentation in tool descriptions. Resources are for information, not action.

MCP Resources in the Agent Architecture

Resources sit at the intersection of the MCP server, the client, and the agent’s memory system.

In this architecture, the agent does not call resources directly in the way it calls tools. Instead:

  1. The agent’s planner identifies that certain knowledge is required to complete the task.
  2. The MCP client discovers available resources via resources/list and resources/templates/list.
  3. The client retrieves relevant resources with resources/read.
  4. Resource content is injected into the agent’s memory or directly into the LLM context.
  5. The agent reasons using that context.

Crucially, clients (Claude Desktop, LangGraph agents) decide how and when to use resources. The MCP specification does not mandate a specific user interaction model—different clients may expose resources through UI pickers, heuristic automatic inclusion, or allow the AI model to choose.

MCP Resource Lifecycle

Every MCP resource follows a well‑defined lifecycle from creation to eventual deprecation.

Stage Details

StagePurposeFailure Mode
Resource creationDefine URI, name, description, MIME type, and handler logic.Missing schema; handler not idempotent.
RegistrationAssociate resource with server capability.Duplicate URI; registration after connection.
DiscoveryClient calls resources/list after initialisation.Server doesn’t declare resources capability.
RetrievalClient calls resources/read with URI.Invalid URI; handler timeout; backend unavailable.
CachingClient caches resource list and content.Stale cache after server changes.
Update notificationServer sends notifications/resources/list_changed or notifications/resources/updated.Notifications not implemented; client misses updates.

Types of MCP Resources

Resources can be classified along two independent dimensions: static vs dynamic, and text vs binary.

By Mutability

TypeURI PatternDescriptionExample
Static resourcesFixed URIContent never changes; ideal for reference materials, schemas, documentation.file:///config/schema.json
Dynamic resourcesURI template with parametersContent generated on request based on URI parameters.logs://{service}/{date}
Subscribable resourcesAny URIClient can subscribe to be notified of changes.metrics://cpu/usage

Static resources are the simplest: a fixed URI, a handler that returns the same content every time. Dynamic resources use URI templates (RFC 6570), allowing clients to construct URIs with parameters. For example, a template file:///logs/{date}.log enables clients to request logs for any date.

By Content Type

TypeMIME TypeEncodingUse Case
Text resourcestext/plain, text/markdown, application/json, etc.UTF‑8 stringSource code, config files, API schemas, documentation
Binary resourcesimage/png, application/pdf, audio/mpeg, etc.Base64‑encoded blobScreenshots, PDFs, images, compiled assets

The MCP server declares the mimeType for each resource, and clients can choose how to handle different content formats—for example, rendering an image rather than sending raw binary to an LLM.

By Domain (Examples)

DomainResource Examples
Documentationdocs://api/reference, docs://getting-started, policy://security
Configurationconfig://database/schema, config://deployment/environment
Knowledge basekb://articles/{id}, faq://common-issues
Logs & metricslogs://{service}/{date}, metrics://cpu/{interval}
Organisational dataorg://directory/{username}, calendar://events/{date}

MCP Resource Design Principles

1. Bounded Contexts

Design each MCP server as a single, bounded context rather than a catch‑all host for disparate resources. MCP servers should expose well‑defined tools, resources, and prompts that serve a coherent domain—not act as one‑to‑one API wrappers. A single server focused on “order management” (resources: order schemas, status definitions; tools: get_order, update_order) is far more maintainable than a monolithic server that mixes orders, customers, inventory, and shipping.

2. Discoverability First

Every resource must be discoverable via resources/list or resources/templates/list. Clients cannot call resources/read on a URI that was never advertised. Use clear, descriptive resource names and include helpful descriptions to guide LLM understanding.

3. Consistency in URI Design

Use a consistent, hierarchical URI scheme:

[scheme]://[namespace]/[category]/[identifier]

Examples: docs://api/authentication, logs://payment-service/2026-06-01, kb://policies/security.

The protocol and path structure are defined by the MCP server implementation—servers can define their own custom URI schemes. However, consistency within a server is critical for client usability.

4. Idempotent and Pure Handlers

Resource handlers MUST be idempotent: the same URI must always return the same content (given the same underlying data). Resource handlers SHOULD be pure—no side effects, no modifications to external state. If a resource access triggers a mutation, it should be a tool, not a resource.

5. Appropriate MIME Types

Always set the mimeType field. Clients use this to decide how to render or process the content. Common types: text/plain, text/markdown, application/json, image/png, application/pdf.

Resource URI Design

Every resource is uniquely identified by a URI in the format: [protocol]://[host]/[path].

Static URIs

For resources that represent a single, fixed piece of content:

file:///home/user/documents/report.pdf
postgres://database/customers/schema
screen://localhost/display1

The server maintains a mapping from URI to content. When the client requests resources/read with that exact URI, the server returns the content.

URI Templates (Dynamic Resources)

For resources that represent parameterised content, servers expose URI templates using RFC 6570 syntax.

Template example:

"uriTemplate": "file:///logs/{date}.log"

The client can then construct a concrete URI: file:///logs/2026-06-01.log.

Template with multiple parameters:

"uriTemplate": "https://api.example.com/users/{user_id}/orders/{order_id}"

Template Metadata

When exposing templates, servers must provide:

  • uriTemplate: The RFC 6570 template string.
  • name: Human‑readable name for this type of resource.
  • description: Optional description.
  • mimeType: Optional MIME type for all matching resources.

Practical Example: File System Resource

{
"uriTemplate": "file:///{path*}",
"name": "Project Files",
"description": "Access files in the project directory",
"mimeType": "application/octet-stream"
}

The client can then request file:///src/main.rs or file:///config/settings.json.

Resource Discovery

Clients discover resources in two ways: static listing and template listing.

Static Resource Discovery

Servers expose a concrete list of resources via the resources/list endpoint. This operation supports pagination for large resource sets.

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": { "cursor": "optional-cursor-value" }
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resources": [
{
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"title": "Rust Software Application Main File",
"description": "Primary application entry point",
"mimeType": "text/x-rust"
}
],
"nextCursor": "next-page-cursor"
}
}

Each resource entry includes:

  • uri (required): Unique identifier.
  • name (required): Human‑readable name.
  • description (optional): Longer description for LLM understanding.
  • mimeType (optional): Helps client handle content correctly.
  • title (optional): Display title for UI presentation.

Resource Template Discovery

Servers expose URI templates via resources/templates/list:

{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/templates/list"
}

Response includes an array of resourceTemplates, each with uriTemplate, name, description, and mimeType.

List Change Notifications

When the list of available resources changes, servers that declared the listChanged capability SHOULD send a notifications/resources/list_changed notification. This notifies clients to re‑fetch the resource list, keeping their cache fresh. Without this, clients may operate with stale resource metadata.

Resource Subscriptions

Servers may support resource subscriptions, allowing clients to be notified of changes to individual resources. If the server declares the subscribe capability, clients can:

  1. Send resources/subscribe with a resource URI.
  2. Receive notifications/resources/updated when content changes.
  3. Fetch fresh content via resources/read.
  4. Unsubscribe with resources/unsubscribe.

Resource Retrieval Patterns

Once discovered, agents retrieve resource content using the resources/read method.

Direct Retrieval

The simplest pattern: client calls resources/read with a concrete URI:

Request:

{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": { "uri": "file:///project/src/main.rs" }
}

Response (text resource):

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"contents": [
{
"uri": "file:///project/src/main.rs",
"mimeType": "text/x-rust",
"text": "fn main() { println!(\"Hello world!\"); }"
}
]
}
}

Response (binary resource):

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"contents": [
{
"uri": "screen://localhost/display1",
"mimeType": "image/png",
"blob": "iVBORw0KGgoAAAANSUhEUgAAA..."
}
]
}
}

Batch Retrieval

Servers may return multiple resources in one resources/read response. This is useful when a URI represents a directory or collection:

{
"result": {
"contents": [
{ "uri": "dir://src/main.rs", "text": "..." },
{ "uri": "dir://src/lib.rs", "text": "..." }
]
}
}

Proactive Injection (Application‑Driven)

Resources in MCP are designed to be application‑driven, meaning the host application determines how to incorporate context. Different clients may handle this differently: Claude Desktop currently requires users to explicitly select resources before they can be used; other clients might automatically select resources based on heuristics; some implementations may even allow the AI model itself to determine which resources to use.

For automatic data exposure to models, server authors should use tools, not resources—tools are model‑controlled, resources are application‑controlled.

Retrieval as a Discovery Aid

Agents can use resources as a discovery aid. For example, instead of searching or guessing, the agent can list available resources, read a documentation resource, learn correct usage, and then succeed on the first tool call.

MCP Resources and RAG

A common source of confusion: how do MCP resources relate to Retrieval‑Augmented Generation (RAG)? The simplest answer is that they address different problems at different layers of the stack.

AspectRAGMCP Resources
PurposeRetrieves relevant information from a static knowledge base (documents, manuals, policies) to ground LLM responses.Provides on‑demand, read‑only access to any data source (files, DB records, API responses, real‑time metrics) via a standardised protocol.
Data sourceVectorised document corpus (PDFs, Confluence, helpdesk articles).Any data: databases, logs, configuration, APIs, screenshots, live system status.
Retrieval triggerAutomatic embedding‑based search before each LLM call.Explicit request from client or agent.
FreshnessDepends on re‑indexing frequency (minutes to days).Can be real‑time, with subscription notifications for updates.
StandardisationImplementation‑specific (LangChain, LlamaIndex).Standardised protocol across all MCP‑compatible clients and servers.

They are not competitors—they are complementary. RAG solves the “knowledge gap” problem (the model was not trained on your internal documents). MCP solves the “live data and action” problem (connecting the model to external systems in real time).

In practice, an AI agent might:

  • Use RAG to retrieve relevant policy documents from a vector store.
  • Use MCP Resources to read a live configuration value or fetch a database record.
  • Use MCP Tools to perform an action based on that context.

RAG fills the context window with relevant information from static documents before the model reasons; MCP connects the model to live systems.

MCP Resources and Agent Memory

Resources are not memory—but they work closely with memory systems.

AspectMCP ResourcesAgent Memory (Short/Long‑Term)
LifetimePersistent on server; client caches may have TTL.Per‑session (short‑term) or per‑user (long‑term).
MutabilityServer‑controlled updates; clients are notified.Agent‑controlled writes (memory updates).
Source of truthServer is authoritative.Agent state is authoritative (for its own session).
Typical contentDocumentation, schemas, configuration, logs.Conversation history, user preferences, task outcomes.

Integration patterns:

  1. Resource as memory seed – The agent can read a resource containing a user’s long‑term preferences from an external store, then populate its in‑memory state.
  2. Resource as memory persistence – The agent can write updated memory back via a tool (not a resource—resources are read‑only). The server then updates the underlying resource representation if appropriate.
  3. Resource versioning for memory consistency – Use resource templates with version parameters (e.g., user://{id}/preferences?v=2) to manage memory schema evolution.

Versioned memory for AI agents—exposed as an MCP server—can store facts, detect conflicts, and track how decisions change over time.

MCP Resources in Multi‑Agent Systems

In a multi‑agent system, resources provide a shared, consistent source of truth across agents.

Benefits:

  • Consistency – All agents read the same resource definitions. No divergence.
  • Single source of truth – Update the resource once; all agents see the change (via list_changed notifications).
  • Reduced redundancy – Documentation, schemas, and policies are not duplicated across agent configurations.

Challenge: Resource changes must be coordinated. When a resource is updated, all subscribed clients receive notifications/resources/updated. The multi‑agent system must handle the timing of these updates—some agents may be in the middle of a workflow when the resource changes.

MCP Resource Security

Security for MCP resources is not optional. Every resource exposed by an MCP server is a potential data exfiltration point. As of the June 2025 specification update, MCP servers are formally classified as OAuth 2.0 Resource Servers.

OAuth 2.1 with Resource Indicators

The MCP specification now requires OAuth 2.1 with PKCE for remote servers. Resource Indicators (RFC 8707) prevent token misuse by ensuring the access token is bound to a specific resource server. The MCP server publishes a /.well-known/oauth-protected-resource document that tells clients which authorisation server to use, what scopes are available, and how to request tokens.

Practical implications:

  • Every MCP server must validate bearer tokens on every request (not just at session establishment).
  • Tokens must be short‑lived (minutes, not hours).
  • Resource access is scoped—different resources may require different OAuth scopes.

Least Privilege for Resource Access

Not every resource should be accessible to every client. Implement resource‑level authorisation:

Resource TypeExampleAccess Level
Public documentationdocs://getting-startedAny authenticated client.
User‑specific datauser://{id}/profileOnly the authenticated user (same id).
Administrative configurationconfig://deployment/secretsRestricted to admin clients.
Compliance‑sensitive logslogs://audit/{date}Read‑only access for compliance officers.

Path Traversal Prevention

When exposing file system resources (e.g., file:///{path*}), validate all URIs. Do not allow arbitrary path traversal—whitelist paths or endpoints for file access. A request for file:///etc/passwd should be rejected.

Gateway‑Enforced Security

For enterprise deployments, a security gateway provides a single place to enforce access control, rate limiting, and audit logging across every MCP server. Stacklok’s gateway uses Cedar and Open Policy Agent (OPA), meaning access rules are declarative, version‑controlled, and auditable—not buried in per‑server configuration files.

Audit Logging

Every resources/read request MUST be logged with:

  • timestamp
  • user_id (from authenticated token)
  • resource_uri
  • client_id
  • session_id
  • outcome (success/error)

This creates an immutable record of what information was provided to which agent—essential for compliance and security investigations.

MCP Resource Scalability

Resources introduce scalability challenges because they can be large, numerous, and frequently accessed.

Caching Strategy

Cache LevelContentsTTLInvalidation
Client‑side (list)Resource listSessionlist_changed notification
Client‑side (content)Retrieved resource contentConfigurable (30s–1hr)Content TTL or subscription update
Server‑sideExpensive resource computationsMinutesBackend change events

Implement caching for compiled prompt templates and frequently read resources, with TTL and invalidation hooks.

Content Distribution

For globally distributed agents, resource content should be served from edge locations. Streamable HTTP transport with CDN caching reduces latency for static resources (documentation, schemas, configuration) from hundreds of milliseconds to single‑digit milliseconds.

Pagination

Resource lists can become extremely large. The resources/list endpoint MUST support pagination using the cursor parameter. Servers should cap the page size (e.g., 50 resources per page) to avoid overwhelming the client.

Resource Partitioning

Instead of a single monolithic resource list, partition resources by domain:

  • docs:// for documentation resources
  • metrics:// for performance metrics
  • config:// for configuration

Each partition can be scaled independently. Some partitions (documentation) may be served from a CDN; others (real‑time metrics) may require direct connection.

Connection Management for Large Resources

When returning large resources (multi‑megabyte JSON, high‑resolution images), consider streaming the response rather than loading the entire content into memory. Streamable HTTP is well‑suited for this use case.

MCP Resource Observability

MCP servers have no built‑in observability. Without instrumentation, resource access patterns, latency, and errors remain invisible.

Metrics to Track

MetricTypeTags
mcp.resource.read.callsCounterresource_uri, mime_type, success
mcp.resource.read.durationHistogramresource_uri, outcome
mcp.resource.list.sizeGaugeNone
mcp.resource.template.callsCountertemplate_uri
mcp.resource.cache.hit_rateGaugeNone

Structured Logging

Each resource handler should log:

{
"level": "info",
"timestamp": "2026-06-09T14:32:01Z",
"request_id": "req_123",
"resource_uri": "postgres://database/customers/schema",
"user_id": "[email protected]",
"content_size_bytes": 15234,
"duration_ms": 47,
"cache_status": "miss"
}

Distributed Tracing

Add OpenTelemetry spans around:

  • resources/list processing
  • resources/templates/list processing
  • Each resources/read execution

Propagate trace IDs from client to server. This allows tracing a resource access from the agent’s decision through the MCP stack to the backend data source.

Real‑Time Analytics with Elastic APM

The Elastic APM Agent Builder MCP enables the same Claude Desktop session that produced the traces to query them back—the agent analyses its own resource access patterns, identifies slow resources, and explains failures without leaving the chat.

Resource Management Best Practices

  1. Design each MCP server as a single, bounded context – Focus resources around one domain (e.g., “order management”, “documentation”, “metrics”).

  2. Keep resources focused – Each resource should represent one coherent piece of information. Avoid merging multiple unrelated documents into a single resource.

  3. Use URI templates for parameterised access – Instead of creating hundreds of static resources for log files, use a template logs://{date}/{service}.

  4. Set appropriate MIME types – Always declare mimeType. Clients rely on this to handle content correctly.

  5. Implement listChanged notifications – When the resource list changes (new files added, schemas updated), send notifications/resources/list_changed. Clients depend on this to stay fresh.

  6. Cache resource lists and content – Reduce network round trips by caching discovery results. Invalidate cache on change notifications.

  7. Validate URIs before handler execution – Never trust client‑supplied URIs. Validate path traversal, parameter bounds, and authorisation.

  8. Implement resource subscriptions for volatile data – If resources change frequently (log files, metrics, live status), support resources/subscribe and send notifications/resources/updated.

  9. Version your resources – Use URI templates with version parameters (config://deployment/environment?v=2) to support backward‑compatible evolution.

  10. Log every resource access – Record user_id, resource_uri, timestamp, and outcome. This is your audit trail.

  11. Monitor resource latency – A slow resource (resources/read > 100ms) will directly impact agent responsiveness. Alert on anomalies.

  12. Test resource handlers in isolation – Mock the backend data source. Verify that the correct content is returned for each URI and that error cases are handled gracefully.

Common Resource Design Mistakes

MistakeConsequenceFix
Using tools for read‑only dataUnnecessary token cost, added latency, no caching.Expose read‑only data as resources, not tools.
No listChanged notificationsClients operate with stale resource lists; new resources are invisible.Implement and send notifications/resources/list_changed when resources change.
Poor URI namingClients cannot guess correct URIs; discovery becomes useless.Use clear, hierarchical, consistent URI schemes.
Missing MIME typesClients mishandle content (e.g., sending binary PDF directly to LLM).Always declare the mimeType field.
Overly large resourcesBlows agent context window; slow to transfer.Paginate, summarise, or split into multiple resources.
No authenticationSensitive resources exposed to unauthorised clients.Implement OAuth 2.1 with per‑resource scopes.
Path traversal vulnerabilitiesAttacker reads /etc/passwd via file:/// resource.Whitelist allowed paths; sanitise all URI parameters.
Static resources that changeClients cache stale content; no update notifications.Use dynamic resources with templates or implement subscriptions.
Too many static resourcesDiscovery list is huge; clients never browse it.Use URI templates to reduce static list size.
Ignoring resource orderClients may retrieve resources sequentially, adding latency.Design resource templates to support batch retrieval where possible.

Case Study: Enterprise Knowledge MCP Server

Scenario: A multinational company deploys an MCP server that exposes its internal knowledge base—technical documentation, company policies, API schemas, and project wikis—to AI agents used by engineering, support, and compliance teams.

Resource Architecture

Resource Catalogue

URI TemplateTypeMIME TypeDescriptionCache TTL
docs://api/{service}Statictext/markdownAPI documentation for each service24h
policies://security/{name}Statictext/markdownSecurity policies by name12h
schema://database/{table}Staticapplication/jsonDatabase table schemas6h
logs://{service}/{date}Dynamictext/plainService logs for a specific date5min
config://deployment/{environment}Dynamicapplication/jsonLive configuration by environment30s

Resource Template Examples

Log retrieval template:

{
"uriTemplate": "logs://{service}/{date}",
"name": "Service Logs by Date",
"description": "Retrieve application logs for a specific service and date (format: YYYY-MM-DD)",
"mimeType": "text/plain"
}

Configuration template:

{
"uriTemplate": "config://deployment/{environment}",
"name": "Environment Configuration",
"description": "Live configuration for a deployment environment (dev, staging, prod)",
"mimeType": "application/json"
}

Security Controls

  • OAuth 2.1 with PKCE – Every client authenticates via corporate IdP (Okta).
  • Resource scopes:
    • docs:read – Access to documentation resources.
    • policies:read – Access to security policies.
    • logs:read – Access to operational logs (restricted).
    • config:read – Access to deployment configuration (admin only).
  • Per‑request validation – Token is validated on every resources/read request; scope claim is checked against the requested resource.
  • Path validation – For dynamic templates, parameters are validated against an allowlist before querying backend systems.
  • Audit log – Every resource access is logged to a central SIEM with user_id, resource_uri, timestamp, and http_status.

Monitoring Strategy

  • Latency SLIs – P95 < 100ms for documentation resources; P95 < 500ms for logs.
  • Cache hit ratio – Target > 80% for static resources.
  • Error rate – Alert if > 1% of resources/read requests return 5xx.
  • Auth failure rate – Alert if > 5% of requests fail token validation.

Result

After deployment, engineering agents resolved documentation lookup time from 45 seconds (manual search) to 2 seconds (automated resource retrieval). Support agents achieved 92% first‑contact resolution by referencing up‑to‑date policy resources. Compliance audits that previously took days were reduced to hours, thanks to the complete audit trail of resource accesses.

FAQ

1. What is the difference between a Tool and a Resource in MCP?
Tools are actions the agent can execute—they have side effects, modify state, call APIs, and require user approval. Resources are read‑only data sources—they provide context without modifying state. Tools are model‑controlled (the LLM decides when to call them); resources are application‑controlled (the client decides how to present them).

2. When should information be a Resource instead of a Tool?
Use a resource when: the data is read‑only, the agent needs to browse or discover it, side effects are not allowed, caching is desirable, and the same data will be read multiple times. Use a tool when: an action must be performed, the operation has side effects, real‑time processing is required, or the output depends on parameters that change per call.

3. How should resources be organised in a server?
By bounded context—one server per domain (e.g., “order management”, “documentation”, “metrics”). Within a server, use hierarchical URI schemes: domain://category/identifier. Use URI templates for parameterised access rather than hundreds of static URIs.

4. Can resources replace RAG?
No. RAG automatically retrieves relevant information from a vectorised corpus using embeddings. Resources require explicit requests from the client or agent. They serve different purposes: RAG for semantic document retrieval, resources for precise, on‑demand data access. Most production systems use both.

5. How should resources be secured?
Implement OAuth 2.1 with PKCE for remote servers. Use Resource Indicators (RFC 8707) to bind tokens to specific servers. Validate tokens on every resources/read request. Enforce resource‑level authorisation (different scopes for different resources). Never expose sensitive data without authentication.

6. How do resources scale to thousands of entries?
Use pagination on resources/list (cursors). Implement URI templates to avoid enumerating every possible resource. Cache resource lists and content aggressively. Partition resources by category into separate namespaces. Use a gateway for federated discovery across multiple servers.

7. What is resources/templates/list used for?
It exposes URI templates (RFC 6570) that clients can use to construct concrete URIs for dynamic resources. For example, a template logs://{date}/{service} allows the client to request any log file without the server pre‑listing every possible date and service.

8. How do resources interact with agent memory?
Resources provide external data that can be loaded into short‑term memory. The agent’s planner may trigger resource reads to gather context. Resource content can be stored in the agent’s memory cache with TTL. Long‑term user preferences exposed as resources can be retrieved across sessions.

9. What are resource subscriptions?
Subscriptions allow clients to be notified when a specific resource changes. The client sends resources/subscribe; the server sends notifications/resources/updated when the content changes; the client then fetches fresh content with resources/read. Useful for live metrics, logs, and rapidly changing data.

10. Can a resource be binary (image, PDF)?
Yes. Binary resources are encoded in base64 and returned in the blob field. The client should inspect the mimeType to determine how to handle the content (e.g., display an image rather than sending raw binary to the LLM).

11. How do I version resources?
Include a version parameter in the URI template: scheme://domain/resource?v={version} or embed the version in the path: docs://api/v2/authentication. Keep multiple versions active during migration. Deprecate old versions with a warning.

12. What is the difference between resources/list and resources/templates/list?
resources/list returns concrete URIs for static resources. resources/templates/list returns URI templates for dynamic resources where the set of valid URIs is too large to enumerate.

13. How do I test MCP resources?
Unit test resource handlers with mocked backend dependencies. Integration test the full MCP JSON‑RPC flow using a test client. Use resources/list to verify discovery. Use resources/read to verify content. Mock listChanged and updated notifications to test subscription behaviour.

14. What is the typical latency for resources/read?
The MCP protocol itself adds minimal overhead (< 1ms). Most latency comes from: network round trip (5–100ms), handler execution (database query, file read), and content serialisation. Static resources can be cached to achieve < 5ms P95 latency.

15. Can a resource access another resource?
Not directly. A resource handler may internally call other services or databases, but it should not call another MCP resource’s endpoint. That would create a dependency graph invisible to the client. Design resource handlers as self‑contained units.

16. How do I handle large resource responses?
Implement pagination using the contents array to return resources in chunks. Use streaming for very large binary resources. Set reasonable size limits per resource (e.g., 1MB for text, 10MB for binary) and reject requests beyond them.

17. What is the difference between MCP Resources and Roots?
Resources are individual data items identified by URIs. Roots are a list of URIs that the client provides to the server as a hint about where the server should operate. Roots tell the server the location of project files; resources are the actual files. Roots are optional; resources are a core primitive.

18. Do MCP servers need to implement resources?
No. Resources are optional. A server may expose only tools and prompts. However, servers that provide read‑only context should implement resources rather than overloading tools.

19. How do I handle resource update notifications in a client?
After receiving notifications/resources/updated, the client should invalidate the cached content for that URI and optionally re‑fetch it immediately. The next time the agent requests that resource, the client can decide whether to use the stale cached version or fetch fresh content.

20. What is the difference between static and dynamic resources?
Static resources have a fixed URI and return the same content each time (modulo backend changes). Dynamic resources use URI templates with parameters—the content varies based on the parameters provided.

Continue Your Journey

Now that you understand how MCP Resources provide contextual knowledge to AI agents, explore the rest of the MCP ecosystem:

Or return to the Agent Learning Path to see where MCP Resources fit in your overall agent engineering roadmap.


This article is part of the AgentDevPro Production Agent Engineering Handbook. Updated for Q2 2026.