Zuplo
Model Context Protocol

What Are MCP Resources? Model Context Protocol Explained

Martyn DaviesMartyn Davies
October 17, 2025
7 min read

MCP Resources provide read-only, application-controlled context for AI agents. Learn how they differ from MCP Tools and when to use each.

MCP Resources are a core feature of the Model Context Protocol (MCP) that let you expose data and content for LLM interactions. If you’re new to MCP, start with our guide on what an MCP server is before diving in.

Unlike MCP Tools, which perform actions, Resources provide read-only access to structured data. Think of them as the “files” your AI can read, while Tools are the “functions” it can execute.

Use this approach if you're:
  • Building MCP servers that expose data to AI agents
  • Need application-controlled context for LLM interactions
  • Working with OpenAI Apps SDK or similar AI platforms

Resources vs Tools: Understanding the Difference

The key distinction is about control:

Resources are application-controlled: The client application decides when and how resources are used. For example, in an application like Claude Desktop, users explicitly select which resources to include before starting a conversation.

Tools are model-controlled: The AI model itself determines when to invoke tools based on the conversation context and available capabilities.

Here is a quick side-by-side breakdown:

MCP Resources

  • Control: Application-controlled — the host app or user decides when to load them
  • Access: Read-only access to data and content
  • Addressing: Identified by URIs (e.g., file:///path, config://app/settings)
  • Best for: Documentation, configuration, schemas, and reference materials

MCP Tools

  • Control: Model-controlled — the AI model decides when to invoke them
  • Access: Can perform actions, writes, and side effects
  • Addressing: Called by function name with structured parameters
  • Best for: API calls, data mutations, calculations, and automated workflows

This difference matters in practice. If you want data to be automatically available to the model, use a Tool. If you want the application or user to control what context gets loaded, use a Resource.

What Makes an MCP Resource

Resources are identified by URIs following the format protocol://host/path, such as:

  • file:///home/user/documents/report.pdf
  • postgres://database/customers/schema
  • config://app/settings

Resources support both text content (UTF-8 encoded) and binary content (base64 encoded), making them work for everything from source code and logs to images and PDFs.

How Resources are Discovered

Clients discover resources through two main methods: direct resource lists via the resources/list endpoint, and URI templates for dynamic resources. Resource templates allow servers to define patterns like file:///{path} that clients can use to construct valid URIs on demand.

Build it

Expose API data as MCP Resources today

Zuplo's MCP handler implements the full Resources spec. Pull data from any backend with one config.

  • Full Resources + Tools spec
  • Per-tenant access control
  • Any upstream API

Implement MCP Resources in an MCP Server

To illustrate how that works in code, we’ll use a basic example of returning some HTML content as an MCP Resource.

It all begins in your OpenAPI document, where you can define the Resource route you want to expose. Resources must use the GET method, and you add MCP metadata via the mcp property inside x-zuplo-route:

Define the Resource Route

JSONjson
{
  "/html": {
    "get": {
      "operationId": "html",
      "description": "Returns the AI applet's HTML",
      "x-zuplo-route": {
        "corsPolicy": "none",
        "handler": {
          "export": "default",
          "module": "$import(./modules/html)"
        },
        "mcp": {
          "type": "resource",
          "name": "html_doc",
          "description": "The HTML document for the AI applet",
          "uri": "ui://html",
          "mimeType": "text/html"
        }
      }
    }
  }
}

The mcp property within x-zuplo-route tells the MCP Server Handler to expose this route as a resource rather than a tool. Set type to "resource" (the default is "tool"), and provide a descriptive name, description, uri, and mimeType so clients understand how to use it.

Connect to the MCP Server Handler

Next, wire the resource into the MCP Server Handler by referencing the operation in the operations array:

JSONjson
{
  "paths": {
    "/mcp": {
      "post": {
        "x-zuplo-route": {
          "handler": {
            "export": "mcpServerHandler",
            "module": "$import(@zuplo/runtime)",
            "options": {
              "name": "example-mcp-server",
              "version": "1.0.0",
              "operations": [
                {
                  "file": "./config/routes.oas.json",
                  "id": "html"
                }
              ]
            }
          }
        }
      }
    }
  }
}

MCP Server Handler

Transform any API into a remote MCP server with Zuplo's MCP Server Handler.

Remote MCP hostingBuilt-in authenticationOpenAPI-native config

MCP Server Resources

Learn how to implement MCP Resources in Zuplo, exposing data and content for AI interactions through standard API routes.

Resource URI patternsText and binary contentOpenAPI integration

This is all great but where are Resources being used right now?

MCP Resources in the Wild

While Resources are often discussed in abstract terms like “reading files” or “exposing documentation,” one of the most recent implementations can be found in OpenAI’s Apps SDK, which uses embedded resources to power custom UI components in ChatGPT.

In the Apps SDK, Resources serve static UI code that agents can retrieve and render, for example:

plaintext
ui://widget/kanban-board.html
ui://widget/styles.css
ui://widget/app.js

When a tool is invoked that requires this UI the agent fetches the HTML, CSS, and JavaScript from the resource, hydrates it with structured data from the tool response, and renders it in an iframe in ChatGPT.

This embedded resource pattern demonstrates a practical, production-ready use of MCP Resources that goes beyond basic file reading. It shows how Resources can enable rich, interactive experiences while maintaining the application-controlled nature that defines them.

Best Practices for Resources

Just as with tool implementation, design is key to success with Resources:

Naming and Documentation

  • Use clear, descriptive resource names and URIs that indicate what they do
  • Include helpful descriptions that guide LLM understanding of when to use the resource
  • Ensure you set the appropriate MIME types to help clients process content correctly

URI Design

  • Implement custom URI schemes that reflect the domain of the content you are working with (e.g., docs://, config://, db://)
  • Consider using the default mcp://resources/{name} format for simple resources
  • Keep URIs consistent and predictable across related resources

Performance and Scale

  • Cache resource contents when appropriate to reduce latency
  • Consider pagination for large resource lists
  • Be mindful of resource size, extremely large resources may impact performance

Security

  • Expose read-only content that provides useful context to AI systems
  • Validate all resource URIs to prevent directory traversal or injection attacks
  • Implement appropriate access controls for sensitive data
  • Sanitize file paths and user inputs

Common Use Cases for MCP Resources

Resources sound great and, hopefully, how they should be implemented and why is clear at this point. What kind of things should Resources be used for, though?

Documentation Resources

Expose API documentation, guides, or reference materials that AI systems can use to answer questions about your platform. When users ask “How do I authenticate with the API?” or “What API endpoints are available?”, the AI can read your actual documentation and provide accurate answers.

Here’s how the above example would be configured as an MCP Resource in Zuplo’s MCP Server handler using the mcp property inside x-zuplo-route:

JSONjson
"mcp": {
  "type": "resource",
  "name": "api_guide",
  "description": "API usage guide and best practices",
  "uri": "docs://api-guide",
  "mimeType": "text/markdown"
}

Configuration Resources

Provide access to current configuration, feature flags, or schema information that helps AI understand your system state. This is valuable for questions like “What features are enabled?” or “What’s the current API version?”

JSONjson
"mcp": {
  "type": "resource",
  "name": "api_config",
  "description": "Current API configuration and settings",
  "uri": "config://api",
  "mimeType": "application/json"
}

UI Component Resources

Share reusable UI components, templates, or design system elements that AI can reference when helping users build interfaces. AI assistants can read your CSS, HTML templates, or component libraries to provide consistent guidance aligned with your design system.

JSONjson
"mcp": {
  "type": "resource",
  "name": "component_library",
  "description": "Available UI components and their usage",
  "uri": "ui://components",
  "mimeType": "text/html"
}

These patterns let AI agents or local LLM based applications provide accurate, contextually relevant help by accessing your system’s documentation, configuration, and resources on demand.

Choosing Between MCP Resources and Tools

Choose Resources rather than Tools when you want the user or application to control what data the AI can access, not the AI model itself. This is important for:

  • User-driven context: When users should explicitly choose what information to share (like selecting specific documentation or logs to include in a conversation)
  • Sensitive data: When you need users to opt-in before exposing certain information to the AI
  • Large reference materials: When you have extensive documentation or data that shouldn’t be automatically loaded but should be available on demand
  • Compliance requirements: When regulations or policies require explicit user consent before data access

Resources work well for:

  • Documentation and guides that users might reference during conversations
  • Configuration and state that changes infrequently but provides important context
  • Reference materials like schemas, templates, or style guides
  • Historical data like logs or records that users explicitly want to analyze

Choose Tools instead when you want the AI model to automatically decide when to access data or perform actions based on the conversation. You can also pair Resources with MCP prompt templates to give AI agents both the context and the instructions they need.

For example, if you want the AI to automatically fetch current weather data when a user asks about the weather, that would be a Tool use scenario. If you want the user to explicitly load weather data before the conversation starts, use a Resource.

Why MCP Resources Matter

The application-controlled nature makes Resources ideal when you want explicit control over what context gets loaded, rather than having the model automatically access data. This gives users and applications the power to choose what information the AI can see, making interactions more predictable and controllable.

If you’re building AI-powered products that consume multiple APIs and MCP servers, an MCP gateway can help you centralize authentication, access control, and observability across all your MCP connections. For a broader look at the AI infrastructure landscape, see our AI gateway comparison and buyer’s guide to AI gateways.

Try it yourself

Remote MCP Server Example

A complete working example of a remote MCP server with tools, resources, and security policies.

DeployView on GitHub

Ready to implement MCP Resources?

Learn More:Official MCP Resources Documentation Zuplo Docs:MCP Resources in Zuplo