Pranav Srivastava

10 lessons

0/10 done
Lesson 8 of 10·12 min·Intermediate

Resources and Prompt Templates

What you will learn
  • Understand what MCP resources are and when to use them instead of tools
  • Build resources with static and dynamic URI patterns
  • Define prompt templates that give Claude consistent, reusable starting points

Tools vs resources — when to use which

So far you have only built tools. MCP also has two other primitives: resources and prompts.

PrimitiveWhat it isWhen to use
ToolA callable functionAgent needs to take an action or fetch data on demand
ResourceA readable data endpoint with a URIStructured content the host app wants to display or provide
PromptA template for a taskReusable instruction patterns, slash-command style

Resources work like files on a server — they have URIs and MIME types, and a client can list and read them. A file server, a notes app, or a calendar app would expose its data as resources rather than (or in addition to) tools.

Prompts are predefined instruction templates that users can invoke. They let you encode your best prompts into the server itself, so they are always available consistently.

Exposing data as resources

import json
from pathlib import Path
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Notes App")

WORKSPACE = Path.home() / "ai-workspace" / "notes"
WORKSPACE.mkdir(parents=True, exist_ok=True)


@mcp.resource("notes://list")
def list_notes() -> str:
    """
    Resource: returns a JSON list of all note filenames.
    URI: notes://list
    """
    files = [f.name for f in WORKSPACE.glob("*.txt")]
    return json.dumps(sorted(files))


@mcp.resource("notes://{filename}")
def get_note(filename: str) -> str:
    """
    Resource: returns the content of a specific note.
    URI: notes://my-note.txt
    """
    path = WORKSPACE / filename
    if not path.exists():
        return f"Note not found: {filename}"
    return path.read_text(encoding="utf-8")

The {filename} in the URI pattern is a path parameter — FastMCP extracts it and passes it as a function argument.

Defining prompt templates

@mcp.prompt()
def summarize_note(filename: str) -> str:
    """
    Prompt template: summarize a note from the workspace.
    The user provides a filename and gets a task description back.
    """
    content = get_note(filename)
    return f"""Please summarize the following note in 3-5 bullet points.
Focus on the key ideas. Keep it concise.

Note content:
{content}"""


@mcp.prompt()
def compare_notes(filename_a: str, filename_b: str) -> str:
    """
    Prompt template: compare two notes and find key differences.
    """
    note_a = get_note(filename_a)
    note_b = get_note(filename_b)
    return f"""Compare these two notes and identify:
1. Key ideas they share
2. Where they differ
3. Which one you would prioritize acting on and why

Note A ({filename_a}):
{note_a}

Note B ({filename_b}):
{note_b}"""


if __name__ == "__main__":
    mcp.run()

How clients use resources and prompts

Resources and Prompts in the MCP flow
  MCP Client (Claude Desktop)
  |
  |-- resources/list     ->  server returns list of URIs
  |-- resources/read     ->  server returns content at URI
  |-- prompts/list       ->  server returns available prompt templates
  |-- prompts/get        ->  server returns rendered prompt for given args
  |
  Tools:   called by the AI when it decides to act
  Resources: called by the host app to display or provide context
  Prompts: invoked by the user (slash commands, menus, etc.)

When resources are better than tools

If you are building an app that shows content (a file browser, a notes list, a calendar view), expose that content as resources. The host application can display resources directly — they do not need to be requested by Claude, and they are not "actions." Use tools only for things that require computation or have side effects.

Chapter summary
  • Resources have URIs and MIME types — they are readable data endpoints, not actions
  • Dynamic URI patterns use {param} syntax — FastMCP extracts them as function args
  • Prompts encode reusable instruction templates directly in your server
  • Tools = actions; Resources = data; Prompts = instruction patterns
Check your understanding
  1. What is the main difference between a tool and a resource in MCP?
  2. How does FastMCP extract path parameters from a resource URI?
  3. How do users typically invoke prompt templates in Claude Desktop?

Finished this lesson?

Mark it done — your progress is saved automatically.