The MCP Handbook

Chapter 5: Resources - The Memory of the Model

While Tools are meant for actions, Resources provide the LLM with knowledge or data. In the MCP specification (as of 2025-11-25), Resources are a central building block for securely integrating external data sources.

What is an MCP Resource?

A resource is comparable to a file or a database entry. Every resource is identified by a unique URI (e.g., file:///logs/today.txt).

Key features:

  • Identification: Via URIs (Uniform Resource Identifiers).
  • Content: Can be text (Text) or binary data (Blob).
  • Metadata: Contains name, description, and MIME type (MIMEType).
  • Icons (New in 2025-11): Every resource and every resource template can now carry icons for visual display in clients (SEP-973).

Implementation in Go

1. Static Resource

Here we use s.AddResource. The Go SDK (v1.4+) allows metadata icons to be attached via the interface.

s.AddResource(&mcp.Resource{
    Name:        "App Config",
    URI:         "file:///config.json",
    Description: "The current system configuration",
    MIMEType:    "application/json",
}, func(ctx context.Context, request *mcp.ReadResourceRequest) (*mcp.ReadResourceResult, error) {
    return &mcp.ReadResourceResult{
        Contents: []*mcp.ResourceContents{
            {
                URI:      "file:///config.json",
                MIMEType: "application/json",
                Text:     `{"env": "production", "debug": false}`,
            },
        },
    }, nil
})

2. Dynamic Resource Templates

Templates allow you to react to infinitely many resources without listing them all individually.

s.AddResourceTemplate(&mcp.ResourceTemplate{
    Name:        "User Profile",
    URITemplate: "users://{id}/profile",
    Description: "Access user profiles by ID",
}, func(ctx context.Context, request *mcp.ReadResourceRequest) (*mcp.ReadResourceResult, error) {
    // Read the concrete URI from the request
    uri := request.Params.URI
    return &mcp.ReadResourceResult{
        Contents: []*mcp.ResourceContents{
            {
                URI:  uri,
                Text: "These are the details for " + uri,
            },
        },
    }, nil
})

Real-Time Updates: Subscriptions

New in the current specification is the ability to subscribe to resources (resources/subscribe). If you set the capability Subscribe: true in ServerOptions, the server can notify the client about changes.

Workspace Roots (roots/list): Where is the Client Operating?

An MCP server rarely knows at startup which project directory the user is currently working on inside their editor or agent environment. Instead of hardcoding paths in local config files, MCP provides the Roots protocol:

The server queries the client actively for its current workspace boundaries (roots/list). The client responds with a list of root URIs:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "roots/list"
}

Client response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "roots": [
      {
        "uri": "file:///home/mlc/repositories/my-project",
        "name": "Frontend App"
      }
    ]
  }
}

When the user adds or removes a folder from their workspace in the client, the client broadcasts a notification:

{
  "jsonrpc": "2.0",
  "method": "notifications/roots/list_changed"
}

The server can then re-query roots/list and dynamically adjust its file watchers, indexers, or security boundaries. This ensures that filesystem, linter, and code-analysis tools operate strictly within the workspace boundaries explicitly authorized by the user.

Testing Resources with `mcp-tester`

With the mcp-tester you can check whether your server serves resources correctly:

# List resources (incl. pagination support with -C)
./bin/mcp-tester resources list --profile local

# List templates
./bin/mcp-tester resources templates --profile local

# Read a resource
./bin/mcp-tester resources read "file:///config.json" --profile local

In the next chapter we look at how Prompts let us orchestrate the interaction between human and machine to perfection.

← Chapter 4: Tools | Table of Contents | Next Chapter: Prompts →


Copyright Michael Lechner - 2026-03-09

Licence: CC BY-NC 4.0