Pillar 4 · Knowledge · Intermediate

MCP Foundations: Tools, Resources, Prompts.

Model Context Protocol (MCP) is an open spec that lets any Claude client talk to any external system through a thin server, using three primitives: tools, resources, and prompts. You write a Python (or TypeScript) MCP server once, and every MCP-aware client (Claude Desktop, Claude Code, Cursor, your own harness) can use it without bespoke glue. This course builds a working server and client end-to-end so you understand the wire protocol, the inspector, and how the three primitives map to real agent behavior.

14 Skilljar lessons·~90 min on Skilljar·D2 + D3

Mirrors Anthropic's Introduction to Model Context Protocol course on Skilljar.

Original course14 lessons · ~90 min
Introduction to Model Context Protocol
Take it on Anthropic Skilljar ↗
MCP Foundations: Tools, Resources, Prompts, painterly hero showing the course's central concept with the Loop mascot as guide.
01 · What you'll learn

You'll walk away with

  1. What MCP is, why it exists, and how it differs from raw tool-calling on the Claude API
  2. The three MCP primitives (tools, resources, prompts) and which one to reach for in a given situation
  3. How to scaffold an MCP server in Python with the official SDK and verify it with the MCP Inspector
  4. How to implement an MCP client that handshakes, lists capabilities, and routes calls to the server
  5. How resources differ from tools (read-only data exposure vs callable actions) and why that distinction matters
  6. How prompts work as reusable, parameterized prompt templates the user explicitly invokes
02 · Prerequisites

Read these first

03 · The course mirror

Lesson outline

Every lesson from Introduction to Model Context Protocol with our one-line simplification. The Skilljar course is the source; we summarize.

#Skilljar lessonOur simplification
1Welcome to the courseCourse framing: build an MCP server and client from scratch in Python; tools, resources, prompts are the three primitives.
2Introducing MCPMCP is the USB-C of LLM integrations: one open protocol so any client speaks to any tool server without bespoke glue.
3MCP clientsClients (Claude Desktop, Claude Code, Cursor, custom harnesses) discover and call MCP servers over stdio or streamable-http.
4Project setupScaffold a Python project with uv, install the MCP SDK, and create the empty server entrypoint that the inspector can hit.
5Defining tools with MCPA tool is a callable function the model can decide to invoke; declare it with a name, description, and JSON-Schema input shape.
6The server inspectorMCP Inspector is the curl-equivalent for your server; use it to manually fire tools and verify the wire protocol before wiring a client.
7Course satisfaction surveyMid-course feedback checkpoint; no technical content.
8Implementing a clientBuild a minimal Python client that handshakes, calls list_tools, and routes Claude's tool-use blocks to the server.
9Defining resourcesA resource is read-only data exposed at a URI (file, DB row, log) that the client can fetch and inject as context.
10Accessing resourcesClients enumerate resources via list_resources and fetch bytes via read_resource; the user (not the model) usually picks which to attach.
11Defining promptsPrompts are server-defined, parameterized prompt templates a user explicitly invokes (e.g., a slash command in the client).
12Prompts in the clientWire the client to surface server prompts as user-selectable shortcuts; the user fills in arguments, the server returns a message list.
13Final assessment on MCPAssessment covering primitives, control flow, and which surface to use for which job.
14MCP reviewRecap: tools are model-controlled actions, resources are user-controlled data, prompts are user-invoked templates.
04 · Our simplification

The course in 7 paragraphs

MCP exists because every team that integrated Claude with their internal systems was solving the same plumbing problem: write a tool schema, write the dispatcher, write the auth, write it again next quarter when the API changes. Model Context Protocol standardizes that plumbing as an open spec so any MCP-aware client (Claude Desktop, Claude Code, Cursor, your own harness) can talk to any MCP server without bespoke wiring. Anthropic publishes the spec and reference SDKs in Python and TypeScript; the community publishes hundreds of servers for GitHub, Slack, Postgres, filesystems, browsers, and more.

The protocol exposes three primitives, and the exam loves to test which one fits which job. Tools are functions the *model* decides to call (write to a database, run a query, send a Slack message). Resources are read-only data the *user or client* decides to attach (a file's contents, a row from a table, a log snippet). Prompts are parameterized prompt templates the *user* explicitly invokes, often as slash commands. The control point is the load-bearing distinction: model-controlled tools, user-controlled resources, user-invoked prompts.

Mechanically, an MCP server is a process that speaks JSON-RPC over either stdio (local subprocess; default) or streamable-http (remote, multiplexed). The client launches or connects to the server, performs a capability handshake, then calls list_tools, list_resources, and list_prompts to discover what the server offers. Discovery is dynamic: the server can publish or revoke capabilities at runtime, and the client surfaces them to the user or the model accordingly. The Python SDK wraps this so you write decorators (@mcp.tool(), @mcp.resource(), @mcp.prompt()) and the SDK handles the wire format.

Tools are where most beginners over-reach. The temptation is to ship a single do_anything tool with a free-form query string. Don't. The exam, and reality, both reward narrow tools with strict JSON-Schema inputs, like create_issue(title, body, labels[]) rather than github(query). The description field is what the model reads to decide whether to call the tool, so write it like a function docstring aimed at a teammate, not a marketing blurb. Tool errors should return structured failure (isError: true plus a message) rather than raising; the model can then recover.

Resources are the primitive that's easiest to misunderstand. A resource has a URI, a MIME type, and a read_resource handler that returns bytes. Think of them as files that live behind the server. The user (or the client UI) picks which ones to attach to the conversation, the server reads them on demand, and Claude treats the contents as plain context. Resources should never have side effects; if you find yourself wanting one to do work, you wanted a tool. The MCP Inspector lets you enumerate resources and fetch them by URI without writing any client code, which is invaluable while developing.

Prompts round out the trio: they are server-side prompt templates with named arguments, surfaced to the user as shortcuts (Claude Desktop renders them as slash commands; Claude Code surfaces them in its prompt chooser). When the user invokes one, the server returns a list of messages, ready to send. Prompts are a UX primitive, not a model primitive. The model never decides to invoke a prompt; the user does. Treat them as the right home for canonical workflows your team runs over and over: /standup, /review-pr, /draft-incident-postmortem. Each one becomes shareable, version-controlled, and discoverable across every MCP-aware client.

When you've finished the course you should be able to: scaffold a server with the official Python SDK, expose a tool with strict JSON-Schema inputs, expose a resource at a stable URI, define a prompt template with named arguments, verify each surface via the MCP Inspector, and wire a thin Python client that proxies Claude's tool-use blocks to the server. That's the whole loop. The exam is built around recognizing this loop in different shapes. A question that says "Claude should be able to read a project file but not modify it" is testing resources vs tools. A question about a slash command in Claude Desktop is testing prompts. A question about why tool descriptions matter is testing the model-controlled discovery flow. From there, advanced MCP topics (sampling, notifications, roots, transport choice) are the natural next layer, covered in mcp-advanced, and they are where production deployments actually live.

05 · Listicle pattern

The 3 MCP primitives and who controls each

The single most-tested MCP concept is which primitive fits which job. Memorize the control point.

  1. Tools: model-controlled actions

    The model decides whether and when to call a tool. Use for side-effectful actions: writes, sends, mutations. Declare with a name, description, and JSON-Schema input. Return structured success or isError: true for failures.

    Concept: tool-calling
  2. Resources: user-controlled data

    The user (or client UI) decides which resources to attach to the conversation. Use for read-only context: file contents, DB rows, logs. Each resource has a URI and MIME type; the server reads bytes on demand. Never side-effectful.

    Concept: mcp
  3. Prompts: user-invoked templates

    The user explicitly invokes a prompt (often as a slash command). The server returns a list of messages with arguments interpolated. Treat as a UX shortcut for canonical team workflows. The model never picks prompts.

    Concept: prompt-engineering-techniques
06 · Listicle pattern

5 anti-patterns when designing MCP tools

Each of these will be a question on the exam in disguise. Watch for the failure mode behind each.

  1. The kitchen-sink tool

    A single do_thing(query: string) that branches internally on the query. The model can't tell when to call it; descriptions become marketing. Split into narrow tools with typed inputs.

    Concept: tool-calling
  2. Free-text inputs instead of JSON-Schema

    Letting Claude pass args: string and parsing inside the tool. The schema is your validation contract; without it the model hallucinates shapes. Always type every input.

    Concept: structured-outputs
  3. Raising exceptions instead of structured errors

    An unhandled exception kills the tool call without giving the model anything to recover from. Return isError: true with a message so the loop can adapt.

    Concept: agentic-loops
  4. Side-effects in resources

    Treating resources as triggerable actions. Resources are read-only; the moment one mutates state, you wanted a tool. Mixing them up makes audit and gating impossible.

    Concept: mcp
  5. No description, or a marketing description

    The description is what the model reads to decide whether to call the tool. Write it like a function docstring, not a tagline. State what it does, when to use it, and what it returns.

    Concept: tool-calling
07 · Key takeaways

6 takeaways with cross-pillar bridges

MCP standardizes the LLM-to-system integration plumbing so any MCP-aware client speaks to any MCP server without bespoke glue.

The three primitives split by control point: tools are model-controlled, resources are user-controlled, prompts are user-invoked.

Tools should be narrow with strict JSON-Schema inputs; the description field is what the model reads to decide whether to call them.

Resources are read-only data attached at user discretion; if you want side effects, you wanted a tool, not a resource.

Use the MCP Inspector to verify your server end-to-end before wiring a client; it is the curl-equivalent for the protocol.

Prompts are server-side templates the user invokes (often as slash commands); they are a UX primitive, not a model primitive.

08 · Exam mapping

How this maps to the CCA-F exam

Domains
D2 Tool Design + Integration · D3 Agent Operations
Blueprint
18% (D2) + 20% (D3)
What it advances
Direct prep for D2 task statements on extending Claude with external tools and D3 questions on integration patterns. MCP shows up across claude-code-in-action, the agentic-tool-design scenario, and any item that asks how Claude reaches systems outside its context.
09 · Curated supplementary sources

3 hand-picked extras

These amplify the Skilljar course beyond what the course itself covers. Each was picked for a specific reason.

10 · Concepts wired

Concepts in this course

11 · Scenarios in play

Where you'll see this in production

12 · Sibling Knowledge

Other course mirrors you may want next

13 · AEO FAQ

8 questions answered

Phrased as the way real students search. Tagged by intent so you can scan to what you actually need.

DefinitionWhat is Model Context Protocol and why do I need it?
MCP is an open spec that standardizes how an LLM client (Claude Desktop, Claude Code, Cursor) talks to external systems. You write a thin MCP server for your system once, and every MCP-aware client can use it without bespoke integration code. The alternative is rebuilding tool wiring for every client surface, which is exactly what MCP was designed to eliminate.
ComparisonWhat are the three MCP primitives and when do I use each one?
Tools are model-controlled actions (the model decides when to call them; use for writes and side effects). Resources are user-controlled read-only data (the user attaches a file or DB row as context). Prompts are user-invoked templates (the user runs them as slash commands). The control point is the discriminator: model, user-attached, user-invoked.
How-toHow do I create my first MCP server in Python?
Install the official SDK with uv add mcp, create a server.py that instantiates FastMCP, and decorate functions with @mcp.tool(), @mcp.resource(), or @mcp.prompt(). Run it with uv run server.py and verify with mcp dev server.py to launch the MCP Inspector. The Inspector lets you fire tools and read resources without writing a client.
ComparisonWhat is the difference between an MCP tool and an MCP resource?
Tools are callable actions the model invokes (often with side effects); resources are read-only data the user attaches. The control point is the load-bearing distinction. If your function mutates state or sends a message, it is a tool. If it returns bytes for context with no side effects, it is a resource. Mixing them breaks audit and confuses the model.
TroubleshootWhy isn't my MCP server showing up in Claude Desktop?
First check claude_desktop_config.json in the right OS-specific path (~/Library/Application Support/Claude/ on macOS) and confirm the JSON is valid. Then restart Claude Desktop; the config is read at startup, not live-reloaded. Run the same command from the config block in a terminal to confirm the server actually starts. Use the MCP Inspector to bypass Claude Desktop entirely and isolate whether the bug is in the server or the wiring.
ComparisonAre MCP tools the same as Claude API tool use?
They translate to the same thing on the wire to Claude (a tool_use block), but the discovery and dispatch layer is different. With raw Claude API tool use, your code declares the tools inline and dispatches the call. With MCP, the client discovers tools dynamically from a server, and the server handles dispatch. MCP shines when many clients need to share the same tool surface.
ComparisonHow does MCP differ from agent skills in Claude Code?
MCP provides external tools and integrations through a separate server process. Agent skills are local markdown files Claude Code loads on demand to add task-specific knowledge to the conversation. They are complementary: MCP gives Claude new capabilities; skills teach Claude how to use them. The Skilljar agent-skills-intro course goes deeper on the latter.
How-toWhat is the MCP Inspector and how do I use it?
The Inspector is a local web UI that connects to any MCP server and lets you manually call tools, fetch resources, and invoke prompts. Launch it with mcp dev <server-file>. Treat it as curl for MCP: use it to verify the protocol surface before wiring a real client, and to reproduce bugs without involving Claude.
Last reviewed: 2026-05-06·Refresh cadence: 90 days; or whenever Skilljar updates the Introduction to MCP course or the MCP spec ships a breaking version·View on Skilljar ↗
K · Intermediate · D2 · Tool Design + Integration

MCP Foundations: Tools, Resources, Prompts, complete.

You've covered the full ten-section breakdown for this primitive, definition, mechanics, code, false positives, comparison, decision tree, exam patterns, and FAQ. One technical primitive down on the path to CCA-F.

Share your win →