Learn MCP - Resources & Prompts
Episode 5 of 23

Learn MCP - Resources & Prompts

Diving into MCP's two passive primitives: Resources as context data providers via resources/list and resources/read with resource URIs and templates, and Prompts as reusable templates via prompts/list and prompts/get with argument binding.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 4 we dissected Tools — the primitives that "act". Now it's the turn of two more passive but equally important primitives: Resources and Prompts. If tools are the server's hands, then resources are the library and prompts are the ready-made recipes.

This episode covers how resources are registered and read via resources/list and resources/read, what resource URIs and resource templates are, and how prompt templates are registered via prompts/list and retrieved via prompts/get with argument binding. Understand these two primitives, and your MCP knowledge is three quarters of the way there.

Resources: Context Data Providers

Resources are formatted data the model can read as context. Some real examples:

  • File contents — for example README.md or a server configuration.
  • Database query results shaped as documents.
  • API documentation, internal policies, or knowledge bases.
  • Content pulled from external systems by the server.

The distinguishing property of resources: passive. Reading a resource doesn't change any state — the model reads, the server sends data, done. Because of this nature, resources are a great fit for the RAG (retrieval-augmented generation) pattern we'll cover in episode 20.

Resource URIs: Every Resource's Address

Every resource has a unique address in the form of a URI. MCP uses standard URIs (file://, https://, or custom schemes) with a scheme followed by a host and path. Examples: file:///home/user/config.json, weather://jakarta/current, or git://repo/main/README.md. The client uses this URI to request a specific resource — whether that resource is a physical file, a database entry, or server-generated data.

Discovering Resources: resources/list

The resources/list method returns the list of available resources:

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

The server responds with a resource list containing uri and name. Just like tools, this list supports pagination via nextCursor when it's large.

Reading Resources: resources/read

To fetch the contents of a resource, the client calls resources/read with the URI:

Request resources/read
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "resources/read",
  "params": {
    "uri": "file:///home/user/config.json"
  }
}

The server replies with formatted content (text or blob):

Response resources/read
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "contents": [
      {
        "uri": "file:///home/user/config.json",
        "mimeType": "application/json",
        "text": "{ \"port\": 8080 }"
      }
    ]
  }
}

mimeType tells the host the content type, while text (or blob for binary) holds the data. This is where the model gets its context to answer questions.

Resource Templates: Dynamic Resources

Sometimes resources can't be registered one by one — for example, "any file inside a directory". That's where resource templates come in. A template is a URI pattern with placeholder parameters:

Resource template dalam resources/list
{
  "resourceTemplates": [
    {
      "uriTemplate": "file://{path}",
      "name": "File di workspace"
    }
  ]
}

A URI pattern with a path placeholder matches any URI like file:///home/user/app.py. When a client wants to read file:///home/user/app.py, the server simply matches the URI against the template and serves the request. This makes resources effectively infinite in number — from a single pattern.

Prompts: Reusable Templates

If tools and resources provide content, prompts provide structure. A prompt is a reusable message template designed to complete a specific task — for example "summarize meeting", "generate commit message", or "review pull request".

An important difference from tools: a prompt doesn't "do" anything. It prepares messages that will later be sent to the model. The model is the one that acts — but the direction of the task has already been designed by the server.

Listing Prompts: prompts/list

The prompts/list method returns the list of available prompts:

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

Each prompt is defined by name, description, and a list of arguments the user can fill in.

Fetching Prompts: prompts/get

When a user selects a prompt, the host calls prompts/get with the prompt name and arguments:

Request prompts/get
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "prompts/get",
  "params": {
    "name": "summarize-meeting",
    "arguments": {
      "meetingId": "2026-08-03"
    }
  }
}

The server replies with a sequence of messages ready to send to the model. Note the argument binding part: the server inserts the meetingId value into the template, producing a message specific to that meeting.

Response prompts/get
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "description": "Ringkas catatan rapat",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Ringkas catatan rapat dengan ID 2026-08-03 menjadi tiga poin."
        }
      }
    ]
  }
}

Info

Resources and prompts are both passive primitives, but their roles differ: resources provide data for the model to read, while prompts provide instructions sent to the model. Tools that perform actions can use either as inputs or outputs.

When to Use Resources vs Prompts

To keep them straight, here's a quick guide:

NeedChoose
The model needs data/facts (file contents, query results)Resources
The model needs task structure (summarize, review, generate)Prompts
The model must perform an action (send email, write file)Tools

The simple rule: data is read via resources, work is structured via prompts, and actions are executed via tools. All three complement each other within a single server. To see the full list of resources and prompts on your server interactively, run npx @modelcontextprotocol/inspector and open the corresponding tab.

Conclusion

In this episode 5 you've understood Resources as context data providers (with resource URIs and resource templates), and Prompts as reusable templates (with argument binding). You also know when to use each primitive.

Key takeaways:

  • Resources are read via resources/read using resource URIs.
  • Resource templates enable unlimited dynamic resources from a single URI pattern.
  • Prompts are prepared via prompts/get and produce messages ready to send to the model.
  • Argument binding fills user arguments into the prompt template.
  • The practical rule: data -> resources, structure -> prompts, actions -> tools.

In the next episode 6 we start getting hands-on: building an MCP server with the SDK — TypeScript using McpServer and FastMCP, and Python using FastMCP, up to a working simple tool server ready to test. See you in episode 6!

Learn MCP - Resources & Prompts | Learning MCP