Model Context Protocol
- Explain the NรM integration problem and how a protocol reduces it to N+M
- Diagram MCP's participants โ host, client, server โ and what each owns
- Distinguish the three server primitives (tools, resources, prompts) and choose the right one for a capability
- Build and run a minimal Python MCP server and connect it to a host
| Spaced-rep: due cards + the five patterns from memory (D123) | 10 min |
| ELI5 + tech read; mcp-hosts visualizer | 20 min |
| Guided: wire protocol by hand + real SDK server | 42 min |
| Practice: primitive triage + trust review | 18 min |
| Project: docsqa_server.py | 22 min |
| Quiz + flashcards | 8 min |
Builds on: Day 111 โ Tool use & function calling ยท Day 120 โ Agents I โ the loop ยท Day 41 โ HTTP & APIs
Before USB, every gadget shipped its own plug, and every computer needed a matching port: N gadgets ร M computers = a drawer full of adapters and a lot of gadgets you simply couldn't connect. USB replaced the drawer with one agreement: any device that speaks the standard works with any computer that has the port. Device makers build ONE plug; computer makers build ONE port; NรM melted into N+M.
AI tools had the same drawer problem. Your Day 111 toolbelt was hand-wired to your app: your schemas, your dispatch code. Want those same tools in Claude Desktop? Rewire. In your IDE agent? Rewire again. Every tool provider was soldering custom plugs for every AI app. The Model Context Protocol is the USB moment: a tool provider wraps their capability in an MCP *server* (one plug), and any MCP *host* โ Claude Desktop, an IDE, your own agent โ can discover and use it through a standard handshake (one port). The host asks "what have you got?", the server answers with a machine-readable menu, and from then on the model can order off that menu. Build your filesystem tools once; every MCP-speaking app can use them forever.
MCP went from Anthropic announcement (late 2024) to industry standard with remarkable speed โ Claude, ChatGPT, VS Code, Cursor, and thousands of community servers speak it โ because NรM was everyone's cost center. For you it is doubly practical: as an AI engineer you will consume MCP servers (databases, ticketing, browsers) instead of hand-wiring integrations, and as an FDE the sentence "we can expose your internal systems to any AI application through one MCP server" is a deal-shaping capability. It is also fresh interview material: hosts vs clients vs servers, and why tools/resources/prompts are separate primitives, are exactly the questions that reveal whether someone has built with it or only read headlines.
The universal adapter โ NรM integrations become N+M
step 1 / 5The problem before MCP: every AI app that wants every tool writes a CUSTOM integration. 3 apps ร 4 tools = 12 bespoke connectors, each with its own bugs.
Guided practice
The wire protocol by hand โ discovery to invocation
20 min- Create
mcp_wire.pywith the starter code: a toy in-process "server" that dispatches the three JSON-RPC methods, and a "host" that walks the real message sequence โ list tools, then call one. No SDK, no processes: the point is to see that MCP is just structured messages, so nothing about it stays magic. - Run it. Read the
tools/listresponse: name, description, inputSchema โ recognize Day 111's tool schema, now standardized and *discoverable*. The host learned the menu at runtime; nothing was hard-coded. - Add a second tool to SERVER_TOOLS (e.g.
delete_note) and rerun WITHOUT touching the host code. The host picks it up from discovery โ that is the N+M economics in one edit. - Make the call fail: request a tool name that doesn't exist and see the JSON-RPC error object come back as data (not a crash) โ errors-as-observations again, one protocol layer down.
- Note what this toy omits (real framing, transports, capability negotiation, notifications) โ the SDK in exercise 2 handles all of it.
A real MCP server with the Python SDK
22 minThis exercise needs a local environment (pip install "mcp[cli]"); browser-only today means read every line, map it onto exercise 1, and run it tonight.
- Create
notes_server.pywith the starter code: the same notes capability, now as a real MCP server via FastMCP. Note how little is left: decorators register tools, type hints become the inputSchema, docstrings become the descriptions the model reads โ everything you hand-wrote in exercise 1, generated. - Test it with the MCP Inspector:
mcp dev notes_server.pyopens a browser UI where you can list and invoke your tools โ you are being the host, manually. - Connect it to a real host: add the printed config block to Claude Desktop's config file (or any MCP-speaking host), restart, and ask the assistant "what's in my oncall note?" Watch it discover and call YOUR server โ with the host's consent prompt in between (that approval UX is the security model working).
- Add a resource:
get_noteexposed atnotes://{title}โ data the HOST can load, distinct from tools the MODEL calls. Re-run the Inspector and find it under resources, not tools. Say out loud who decides for each primitive: model / application / user.
On your own
Primitive triage + the trust review
18 minPart 1 โ for each capability, pick tool, resource, or prompt, with one line of reasoning: (a) run a read-only SQL query the model composes; (b) the database's schema, so the model writes correct SQL; (c) a user-invoked "/weekly-report" template; (d) create a Jira ticket; (e) the contents of the currently open file in an editor; (f) redact PII from pasted text on demand.
Part 2 โ you are evaluating a community MCP server for your team ("connects to your CRM!"). Write the five-question security review you'd run before allowing it: think about what enters the model's context from the server, what credentials the server holds, and what its tools can do. Compare with: (1) what do its tool descriptions and results inject into context? (2) what scopes/credentials does it demand โ least privilege? (3) which tools are destructive and does the host gate them? (4) is the code auditable and the version pinnable? (5) where does data flow โ does ticket text leave your boundary?
Answers part 1: a tool; b resource; c prompt; d tool (destructive โ flag for approval); e resource; f tool (or prompt if user-invoked by convention).
An MCP server for the capstone corpus
Build docsqa_server.py: an MCP server exposing your capstone (Day 119) to any host. Tools: search_docs(query, k=3) calling your hybrid retriever and returning chunks with citations, and answer_question(question) returning your grounded answer() output (text, citations, refused). Resource: corpus://{doc_id} serving raw document text for host-side context. Write model-facing docstrings with the same care as Day 111 schemas โ they are the only manual the model gets. Verify with mcp dev (screenshot or transcript in the README), and add a security note: why answer_question is safe to auto-approve but a hypothetical reindex_corpus tool would need an approval gate. Commit to the capstone repo โ this is the capstone's second interface (CLI, now MCP; API comes Day 148).
Common mistakes & misconceptions
- Confusing the participants: the host is the app, the client is the per-server connection the host owns, the server exposes capabilities. One host, many clients, each pinned to one server.
- Exposing everything as tools. Data the application should load is a resource; user-invoked templates are prompts. The primitive encodes who decides โ model, app, or user.
- Writing lazy tool descriptions. Discovery means the model chooses tools by description alone; vague descriptions produce wrong tool choices at runtime, same as Day 111.
- Treating community servers as safe because the protocol is standard. The protocol standardizes the wire, not the trustworthiness โ server output is injected context; review, pin, least-privilege.
- Hard-coding against one server's tool list. The entire point is runtime discovery; enumerate tools/list at connect time and handle the menu changing.
- Building a bespoke REST API where an MCP server was the answer. If the consumer is an AI app โ yours or a customer's โ MCP gets you every host for free; that is the N+M argument in reverse.
Q1. MCP turns the integration problem from NรM into N+M becauseโฆ
Q2. A DB's schema should be exposed to the model as which primitive, and why?
Q3. Why is a malicious MCP server a prompt-injection vector?
Go deeper โ curated resources
- MCP server concepts โ tools/resources/prompts in depth โ โ The full primitive semantics, including annotations for destructive vs read-only tools โ the metadata Day 125's approval gates key off.
- Wire lab run; second tool discovered without host changes
- notes_server.py verified in Inspector (or fully traced if browser-only, run scheduled)
- All six primitive-triage calls correct; security review written
- docsqa_server.py committed to the capstone repo with README verification
- Quiz โฅ 2/3
โ Back: Day 111's tool schemas and descriptions are exactly what MCP standardizes and makes discoverable; Day 41's HTTP/JSON-RPC literacy is the transport layer; Day 120's loop is what lives inside every MCP host.
Forward โ: Day 125 builds the approval gates MCP's consent model expects around destructive tools. Day 132 weaponizes (then defends) the injection vector you named today, and Day 169 pitches MCP as the enterprise integration story.