Resources & Prompts 📚🔍🤖
Discover how to harness the power of resources and prompts to supercharge your AI agent's abilities. Learn how to effectively utilize these tools to enhance your agent's performance and capabilities.
Day 3 — MCP Resources & Prompts
MCP & AI Agents — Agent Bootcamp Part 2 — RohithBuilds
So far your server only has tools — functions the AI actively calls when it decides it needs to. Today you'll meet MCP's other two building blocks: resources (read-only data an AI can look at) and prompts (reusable message templates). By the end of today, your notes won't just be something the AI can fetch on request — they'll be something it can browse, and you'll have ready-made prompts that turn your data into useful AI conversations instantly.
Step 1 — Tools vs Resources vs Prompts
These three MCP building blocks solve different problems:
- Tools (Day 1–2) — actions. The AI decides "I need to do something" and calls a function, like
add_noteorexam_countdown. - Resources (today) — data. Read-only information an AI client can browse or attach as context, identified by a URI like
notes://all. No "calling" or reasoning required — it's just there to be read. - Prompts (today) — templates. Pre-written, sometimes parameterized, message templates that turn a request like "summarize my notes" into a fully-formed prompt, every time, the same way.
A simple way to remember it: tools are verbs, resources are nouns, and prompts are sentences your server hands to the AI.
Step 2 — Expose Your Notes as a Resource
Open server.py. Add this above if __name__ == "__main__":, anywhere after your list_notes_logic function:
@mcp.resource("notes://all")
def notes_resource() -> str:
"""All of the student's saved notes, as a readable resource."""
return list_notes_logic()
The "notes://all" string is a URI — a unique address for this resource, the same idea as a URL. Any MCP client can now "open" notes://all the way a browser opens a web page, without calling it like a function.
Step 3 — Build a Resource Template for a Single Note
Resources can also be templated — part of the URI becomes a parameter. Add this:
def get_note_by_id(note_id: str) -> str:
try:
nid = int(note_id)
except ValueError:
return f"'{note_id}' is not a valid note ID."
conn = sqlite3.connect(DB_FILE)
row = conn.execute(
"SELECT id, text, created_at FROM notes WHERE id = ?", (nid,)
).fetchone()
conn.close()
if row is None:
return f"No note found with ID #{note_id}."
return f"#{row[0]} [{row[2]}]: {row[1]}"
@mcp.resource("notes://{note_id}")
def note_by_id_resource(note_id: str) -> str:
"""A single note, looked up by its ID."""
return get_note_by_id(note_id)
Notice the {note_id} in the URI — MCP matches that against the function parameter, the same way Flask matches <filename> in a route. notes://1, notes://2, and so on all become valid resource addresses automatically.
Step 4 — Restart Inspector & Explore Resources
Restart Inspector to pick up the changes:
mcp dev server.py
Open the Inspector link and click the Resources tab. You should see notes://all listed, plus notes://{note_id} shown as a template.
Expected Output
Click notes://all to read it — you should see every note you've saved so far.
Expected Output
Now click on the notes://{note_id} template, enter 1 for note_id, and read it.
Expected Output
Step 5 — Build a Prompt: Summarize My Notes
Prompts work like resources and tools — a plain function plus a thin @mcp.prompt() wrapper. Add this:
def build_summary_prompt() -> str:
notes = list_notes_logic()
return (
f"Here are my notes:\n\n{notes}\n\n"
"Summarize these into a short to-do list, grouped by topic if possible."
)
@mcp.prompt()
def summarize_notes() -> str:
"""Ask the AI to summarize all saved notes into a short to-do list."""
return build_summary_prompt()
This prompt pulls your live notes into the template every time it's used — it's never out of date.
Step 6 — Build a Prompt: Exam Prep Plan
Let's tie today back to Day 1's exam_countdown tool. Add this:
def build_exam_prep_prompt(exam_name: str, exam_date: str) -> str:
countdown = get_exam_countdown(exam_name, exam_date)
return (
f"{countdown}\n\n"
f"Based on this, create a realistic day-by-day study plan for {exam_name}. "
"Keep it practical for a student with 2-3 hours of free time per day."
)
@mcp.prompt()
def exam_prep_plan(exam_name: str, exam_date: str) -> str:
"""Ask the AI to build a day-by-day study plan for an exam."""
return build_exam_prep_prompt(exam_name, exam_date)
This prompt takes parameters — Inspector will show input fields for exam_name and exam_date, just like it does for tools.
Step 7 — Test Your Prompts in Inspector
Restart Inspector again, then click the Prompts tab. You should see summarize_notes and exam_prep_plan listed.
Expected Output
Click summarize_notes and run it. You should see the full generated prompt, with your actual notes embedded inside it.
Expected Output
Now click exam_prep_plan, enter exam_name: GATE 2027 and exam_date: 2027-02-08, and run it.
Expected Output
This is the output an AI client would actually receive and respond to. Tomorrow, you'll build a client that does exactly that — automatically.
Step 8 — Fallback Test Without Inspector
Create test_local.py (or extend yesterday's):
from server import get_note_by_id, build_summary_prompt, build_exam_prep_prompt
print("=== Note #1 ===")
print(get_note_by_id("1"))
print("\n=== Summarize Notes Prompt ===")
print(build_summary_prompt())
print("\n=== Exam Prep Plan Prompt ===")
print(build_exam_prep_prompt("GATE 2027", "2027-02-08"))
Run it:
python test_local.py
Expected Output
✅ Day 3 Complete
Here is what you accomplished today:
Key Takeaways
- Understood the difference between tools, resources, and prompts ✅
- Exposed your notes as a readable resource (notes://all) ✅
- Built a parameterized resource template (notes://{note_id}) ✅
- Built a prompt that summarizes live notes data ✅
- Built a parameterized prompt for exam study plans ✅
- Tested resources and prompts in MCP Inspector ✅
What Is Coming Tomorrow
On Day 4 you will:
- Build your first MCP client in Python
- Connect that client to the server you've been building all week
- List your server's tools programmatically — no Inspector needed
- Bridge those tools to Groq, so an AI model can choose and call them on its own
This is the day everything clicks together. See you there! 🚀
Continue Learning with Rohi
You've used your 3 free Rohi questions. Create a free account to continue learning.