CONCEPT · 30 minutes
Why the Model Context Protocol exists, what it standardizes, and the two building blocks — resources and tools — that every MCP server is made of.
When I built a support-automation system to triage incoming tickets using an AI model, I immediately hit a wiring problem. The AI needed three things to do its job: read from a knowledge-base of articles, pull recent ticket history, and hand off routing decisions to the ticketing backend. Each connection demanded its own custom schema. The KB used one query format; the ticket store used another; the routing action expected a completely different payload structure. I was building and maintaining three separate integration layers before the AI could do anything useful.
Think of it like having to solder a new connector every time you want to plug a new device into the wall. Each device works, but every connection is bespoke — no device can use another device's connector.
That pain scales badly. Every new capability means a new custom protocol. Every new AI application that wants to use my data sources needs to learn each protocol from scratch. What I actually needed was one standard interface that both the AI and my data sources could speak.
That is what MCP is: the Model Context Protocol. It provides a single, open standard that AI applications use to connect to data sources and action endpoints, so a host like Claude can talk to any MCP server without needing to know what is behind it.
Key insight: MCP does not replace your APIs or databases. It places a standard surface in front of them — the same surface, regardless of what sits behind it.
Before MCP, what would you have had to build to give an AI model access to your KB and ticket system? What does MCP replace in that picture?
Take a moment to think through this before reading on. You would have needed a custom function schema for the KB, a separate schema for the ticket store, and a third for the routing API — plus glue code to wire each one to the model. MCP replaces all of that per-integration work with a single server that speaks one protocol to any compatible host.
Think of MCP like a universal adapter for AI integrations. Before USB-C, every device had its own charging port — phones, tablets, and laptops all used different connectors. USB-C replaced all of that with one standard port. MCP does the same thing for AI tools: one protocol, any data source or action endpoint.
When an AI host connects to an MCP server, every conversation follows the same shape. The host asks what resources the server exposes; the server describes them with a standard schema. The host asks what tools are available; the server describes those too. The host then fetches a resource or calls a tool using the same protocol, regardless of what sits behind the server.
That standardization is what made it possible to extend the support-automation system later. Adding a new data source — an active-agent roster, an escalation history — meant writing one new resource definition on the existing server, not building a new integration from scratch.
What this unlocks: Because MCP is an open protocol, the same server works with Claude, with other MCP-compatible hosts, and with any future host that implements the specification. Build the integration once; any compatible host can use it.
Every MCP server is built from two primitives: resources and tools. Understanding the distinction between them is the most important concept in this path.
Resources are read-only. Think of a resource as a shelf in a library. The AI can walk up and pick up any book it wants — browse the titles, read the contents — but it cannot rearrange or write in them. Nothing on the shelf changes as a result of the read. In the support-automation system, the KB articles and the recent ticket history were both resources: the AI needed to read them to classify a ticket, but reading them had no side effects.
Tools trigger actions. Think of a tool as a power outlet. The moment you plug something in, current flows — something happens in the real world. Routing a ticket assigns it to a queue and notifies an agent. Escalating a ticket pages a human. Both operations change state, and that change is not reversed by anything else the AI might do. In the support-automation system, classify_ticket, route_ticket, and escalate_ticket were all tools because they changed real-world state.
The decision rule: If the operation returns data without changing anything, make it a resource. If it changes state in the real world, make it a tool. This boundary is what lets hosts and security audits know which operations are safe to retry and which ones commit changes.
Before moving on: in the support-automation example, why was ticket history exposed as a resource rather than a tool?
Take a moment to reason this through. The answer is in the definition: reading ticket history does not change the tickets. The AI can call that resource ten times in a row and the state of the system is identical each time. That predictability — no side effects — is exactly what makes it a resource.
The rest of this path builds one running example, a support-triage MCP server, one layer at a time. Module 02 scaffolds the server skeleton. Module 03 adds two resources: KB articles and ticket history. Module 04 adds three tools: classify_ticket, route_ticket, and escalate_ticket. Module 05 integrates everything into a complete, working server.
Before building any handlers, it helps to see the structure every MCP server starts from. This skeleton shows the imports, server instantiation, and transport wiring — no resource or tool handlers yet. Those come in the modules that follow.
Two things to notice in this skeleton. First, every handler uses typed schema objects — ListResourcesRequestSchema, CallToolRequestSchema — not string literals like 'resources/list'. The typed form is the correct API surface for the MCP SDK; any example using string-based registration is using a deprecated pattern. Second, the server does nothing until server.connect(transport) is called. The transport is the power cord that wires the server to the host — without it, the server cannot send or receive any messages.
Why stdio? StdioServerTransport is the standard transport for local MCP servers: the host spawns the server as a child process and communicates over stdin and stdout. Other transports (HTTP, SSE) exist for networked deployments, but stdio is the right starting point for a new server.
Application-level questions about MCP concepts and the resource/tool distinction.
1. In the support-automation example, why was ticket history exposed as a resource rather than a tool?
2. Which of the following should be exposed as a TOOL rather than a resource?
3. Which argument should be passed to `server.setRequestHandler()` when registering a handler for listing available MCP resources?
4. The "power outlet" analogy for tools highlights which property?
5. An order-tracking server needs to expose three capabilities: (1) look up an order by ID, (2) list recent orders for a customer, and (3) cancel an order. How should these be classified?
6. What role does `StdioServerTransport` play in an MCP server?
7. Before `await server.connect(transport)` is called, what is true of the MCP server?
Apply the resource/tool distinction to a new domain — no code required.
An e-commerce company is adding MCP support so an AI assistant can help customers track orders and support staff handle re-shipments and cancellations. The system supports five operations:
For each operation: classify it as a resource or a tool, give it a name following MCP conventions (URI-style for resources, e.g. orders://detail/{orderId}; snake_case verb for tools, e.g. cancel_order), and write one sentence justifying your choice.
Hint: Ask for each operation — does performing this change any stored data, or does it only read existing data without side effects? If the AI can call it repeatedly without consequence, it is a resource.
Worked Solution
<CodeExample title="Solution" language="text"> Resources (read-only, no side effects): - orders://detail/{orderId}: reading an order record does not modify it. - orders://recent/{customerId}: retrieving order history leaves it unchanged. - orders://shipping-status/{orderId}: fetching shipping status has no side effects.Tools (commit state changes):
The decision rule: anything the AI can call repeatedly without consequence is a resource. Anything that commits a change — even a soft one like updating a status field — is a tool.