Lesson 6 - Step 1 of 5

What are MCP Resources?

Understand application-controlled data and URI schemes in MCP.

What You'll Build

In this lesson, you'll build resources.py — a reusable resource registry module, plus file_example.py to demonstrate it. By the end, your server will:

  • Scan a directory for files with allowed extensions
  • Handle resources/list to advertise available files
  • Handle resources/read to return file contents
  • Return text content for readable files, base64 for binary
  • Include security checks to prevent directory traversal

Each step builds on the previous one, and you'll test your server with curl commands.

Resources: Application-Controlled Data

Resources are one of the three core primitives in MCP, alongside Tools and Prompts. While tools let the AI do things, resources let the AI read things — they expose data that can be attached to the conversation context.

Key Difference: Application-Controlled

Unlike tools (which the AI decides when to call), resources are application-controlled. The client application decides which resources to attach to the conversation — for example, when a user opens a file in an IDE, the IDE might automatically attach that file as a resource.

How Resources Fit In

diagram
┌─────────────────────────────────────────────────────────────┐
│                     MCP Server                              │
│                                                             │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐   │
│  │    TOOLS      │  │   RESOURCES   │  │    PROMPTS    │   │
│  │               │  │               │  │               │   │
│  │  Model calls  │  │  App attaches │  │  User selects │   │
│  │  when needed  │  │  to context   │  │  from menu    │   │
│  └───────────────┘  └───────────────┘  └───────────────┘   │
│                                                             │
│  Model-controlled  App-controlled   User-controlled        │
└─────────────────────────────────────────────────────────────┘

URI Schemes

Every resource in MCP is identified by a URI (Uniform Resource Identifier). The URI scheme tells clients what kind of resource it is:

Scheme Example Use Case
file:// file:///home/user/config.json Local files
http:// http://api.example.com/data Web resources
db:// db://mydb/users/123 Database records
custom:// slack://channel/general Custom integrations
URI vs URL

A URI is an identifier — it names a resource. A URL is a locator — it tells you how to access it. In MCP, we use URIs because the server handles the actual data retrieval; the client just needs to identify what it wants.

Resource Flow

Here's how resources work in practice:

diagram
Client                              Server
  │                                    │
  │─── resources/list ────────────────>│  "What resources do you have?"
  │<────────────────── list of URIs ───│
  │                                    │
  │─── resources/read ────────────────>│  "Give me file:///config.json"
  │    { uri: "file:///config.json" }  │
  │<────────────────── file contents ──│
  │                                    │

Example: Listing Resources

A client asks the server what resources are available:

json
// Request
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "resources/list",
    "params": {}
}

// Response
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "resources": [
            {
                "uri": "file:///project/config.json",
                "name": "config.json",
                "description": "Application configuration",
                "mimeType": "application/json"
            },
            {
                "uri": "file:///project/README.md",
                "name": "README.md",
                "description": "Project documentation",
                "mimeType": "text/markdown"
            }
        ]
    }
}

When to Use Resources

Resources are ideal when you want to:

  • Expose file contents to the AI (configuration, code, documentation)
  • Provide database records or API responses as context
  • Let the application control what data the AI sees
  • Share read-only data (resources are meant to be read, not modified)
Resources vs Tools

Use a resource when you want to provide data for context. Use a tool when you want the AI to be able to take an action or when it needs to decide dynamically what data to fetch.