# Les 16 — MCP (Model Context Protocol) ## Slide Overzicht (Klas A — 3 uur fysiek, demo-driven) **Lesvorm:** Tim demonstreert klassikaal. Studenten kijken. Zelf bouwen = huiswerk. **Demo-app:** Eigen MCP server voor Polderfest-data (Node/TypeScript) **Vervolg op:** Les 15 — Cursor + Vercel deploy **Aansluit op:** Les 17 — Externe APIs in diepte --- ## Slide 1: Title ### Les 16 — MCP **Visual:** "Les 16" BLUE, "Model Context Protocol" BLACK, subtitle "Eén protocol, alle AI-clients, jouw tools beschikbaar" --- ## Slide 2: Terugblik ### Waar staan we? **Lessen 11-15:** - AI SDK, Tool Calling, Agents, RAG, Cursor+Vercel deploy **Het probleem dat we nu oplossen:** - Tools die je bouwt zitten VAST aan jouw app - Wil je dezelfde tools in Cursor? Claude Desktop? Een script? Drie keer schrijven - MCP = standaard die alle AI-clients begrijpen **Visual:** 3 AI-clients (Cursor, Claude Desktop, ChatGPT) → 1 MCP-server → jouw data --- ## Slide 3: Planning ### Vandaag — 180 minuten | Onderwerp | Duur | |-----------|------| | Terugblik + waarom MCP? | 15 min | | Theorie: MCP architectuur | 20 min | | Theorie: bestaande servers + eco | 15 min | | **Live Demo 1** — MCP SDK + eerste server | 25 min | | **Live Demo 2** — Server laden in Cursor/Claude | 20 min | | **Pauze** | 15 min | | **Live Demo 3** — Eigen Polderfest MCP server | 30 min | | **Live Demo 4** — Resources + prompts toevoegen | 20 min | | MCP vs Tool Calling | 10 min | | Lesopdracht + Huiswerk | 10 min | --- ## Slide 4: Wat is MCP? ### Een open protocol voor AI ↔ tools **Definitie:** > Model Context Protocol (MCP) is an open standard for connecting AI assistants to data sources and tools — created by Anthropic in november 2024. **Het idee:** - AI-clients (Claude Desktop, Cursor, custom apps) zijn **MCP clients** - Tools/data-bronnen zijn **MCP servers** - Eén protocol voor de communicatie tussen beide **Wat krijg je:** - Bouw je tool ÉÉN keer, gebruik 'm in elke MCP-client - Het Anthropic-ecosysteem heeft al 100+ MCP servers (filesystem, github, slack, postgres, ...) - Voor productie-apps: complete decoupling tussen AI-frontend en jouw backend **Visual:** USB-C analogie — één standaard connector voor verschillende apparaten --- ## Slide 5: MCP architectuur ### Client / Server / Transport ``` ┌──────────────┐ JSON-RPC ┌──────────────┐ │ MCP Client │ ◄────────────────────► │ MCP Server │ │ (Cursor, │ stdio / HTTP/SSE │ (jouw code) │ │ Claude │ │ │ │ Desktop) │ │ exposes: │ └──────────────┘ │ - tools │ │ - resources │ │ - prompts │ └──────────────┘ ``` **Drie primitieven die een server kan exposeren:** - **Tools** — uitvoerbare functies (zoals Les 12 tool calling) - **Resources** — data die de AI mag lezen (files, DB rows) - **Prompts** — herbruikbare prompt-templates **Twee transports:** - **stdio** — server runt als lokaal proces, communicatie via stdin/stdout (default) - **HTTP/SSE** — remote server, voor cloud-deploys --- ## Slide 6: Bestaande MCP servers ### Het ecosysteem **Officiële Anthropic servers (npm @modelcontextprotocol/server-*):** - `filesystem` — lees/schrijf files - `github` — repos, issues, PRs - `slack` — channels, messages - `postgres` — query database - `puppeteer` — browser automation - `memory` — persistent geheugen tussen sessies **Community servers:** - `linear`, `notion`, `asana`, `figma`, `stripe`, `youtube`, ... **Hoe gebruik je ze:** - In Cursor: `~/.cursor/mcp.json` config - In Claude Desktop: Settings → Developer → MCP config - Beide laden de server bij startup, server wordt vanzelf beschikbaar **Visual:** Lijst van populaire MCP-servers met logo's --- ## Slide 7: Eigen MCP server bouwen ### TypeScript SDK basics **Package:** ```bash pnpm add @modelcontextprotocol/sdk ``` **Skeleton:** ```typescript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; const server = new McpServer({ name: "polderfest-server", version: "1.0.0", }); server.tool( "searchBands", "Zoek bands op dag, stage of genre", { day: z.string().optional(), stage: z.string().optional() }, async ({ day, stage }) => { const bands = await queryDb(day, stage); return { content: [{ type: "text", text: JSON.stringify(bands) }] }; } ); const transport = new StdioServerTransport(); await server.connect(transport); ``` **Drie regels:** maak server, registreer tool, connect transport. Klaar. --- ## Slide 8: Wat we vandaag bouwen ### Polderfest MCP server **Doel:** MCP server die Polderfest-data exposeert. Werkt in Cursor, Claude Desktop, en elk ander MCP-client. **Wat zit erin:** | Type | Naam | Wat | |------|------|-----| | Tool | `searchBands` | Filter op dag/stage/genre | | Tool | `getBandStats` | Aggregate counts | | Tool | `addFavorite` | Write — voeg toe aan favorites | | Resource | `bands://list` | Volledige bandenlijst (read-only) | | Prompt | `dailyRecap` | "Geef recap van dag X" template | **Demo:** - Eerst werkend in dev (stdio) - Daarna geladen in Cursor → Cursor kan zelfstandig vragen beantwoorden over Polderfest - Idem in Claude Desktop --- ## Slide 9: LIVE DEMO 1 — MCP SDK + eerste server ### ~25 min **Wat ik laat zien:** 1. `pnpm create-typescript-app mcp-polderfest` + `pnpm add @modelcontextprotocol/sdk zod` 2. `src/index.ts` — minimal server skeleton (15 regels) 3. Eerste tool: `searchBands` met hardcoded data (mock) 4. `pnpm build` → `dist/index.js` 5. Test met MCP Inspector: `npx @modelcontextprotocol/inspector dist/index.js` 6. Inspector UI in browser → zien dat tool beschikbaar is → tool aanroepen → resultaat **MCP Inspector is jouw vriend** — debug-tool zonder Claude/Cursor nodig --- ## Slide 10: LIVE DEMO 2 — Laden in Cursor + Claude Desktop ### ~20 min **Cursor (`~/.cursor/mcp.json`):** ```json { "mcpServers": { "polderfest": { "command": "node", "args": ["/full/path/to/mcp-polderfest/dist/index.js"] } } } ``` **Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):** Idem — zelfde JSON structuur. **Demo:** 1. Edit config, restart Cursor 2. Cursor → settings → MCP — server zichtbaar + groen vinkje 3. In chat: "Zoek bands op zaterdag voor mij" — Cursor roept onze tool aan 4. Idem in Claude Desktop chat 5. Eén server, twee clients, geen extra werk --- ## Slide 11: Pauze ### 15 min --- ## Slide 12: LIVE DEMO 3 — Echte Polderfest server ### ~30 min **Wat ik laat zien:** 1. Server koppelen aan Supabase (env vars via dotenv) 2. `searchBands` echt naar database 3. `getBandStats` toevoegen 4. `addFavorite` (write-tool) toevoegen — let op user-intent 5. Errors netjes afhandelen (return `isError: true`) 6. Live testen in Cursor — vraag stellen, écht data uit database komt terug 7. Trick: ook nuttig in Claude Desktop voor research-werkflow **Belangrijk:** MCP server is gewoon een node-proces. Logging via `console.error` (stdout is gereserveerd voor protocol). --- ## Slide 13: LIVE DEMO 4 — Resources + Prompts ### ~20 min **Resources** zijn read-only data die AI mag inladen: ```typescript server.resource( "bands-list", "bands://list", async () => ({ contents: [{ uri: "bands://list", mimeType: "text/plain", text: bandList.map(b => b.name).join("\n"), }], }) ); ``` In Cursor: `@polderfest:bands-list` — bands-data direct beschikbaar voor AI **Prompts** zijn herbruikbare templates: ```typescript server.prompt( "daily-recap", "Geef een samenvatting van een festivaldag", { day: z.string() }, ({ day }) => ({ messages: [{ role: "user", content: { type: "text", text: `Geef recap van ${day} ...` } }] }) ); ``` In Cursor command palette: snel die prompt invoegen. --- ## Slide 14: MCP vs Tool Calling ### Wanneer welk? | | Tool Calling (Les 12) | MCP (Les 16) | |---|----------------------|--------------| | Waar leeft de tool | In jouw Next.js app | Aparte server, los proces | | Wie kan 'm gebruiken | Alleen jouw chat | Alle MCP-clients | | Setup-complexiteit | Laag | Iets hoger | | Distributie | Niet — alleen in jouw app | npm publish, anderen installen | | Voor productie-app | Default | Voor herbruikbaarheid / multi-client | **Mentale model:** - **Tool calling** = "function in mijn app" - **MCP server** = "library die elke AI-client kan gebruiken" Veel productie-teams gebruiken beide: tool calling in hun product, MCP voor interne dev-tools. --- ## Slide 15: Lesopdracht + Huiswerk ### Bouw je eigen MCP server **Lesopdracht (30 min):** - MCP server skeleton opzetten - 1 tool met mock-data - MCP Inspector test - Laden in Cursor of Claude Desktop **Huiswerk (~2 uur, voor Les 17):** - A: 3 tools (read) + 1 write-tool naar Supabase - B: 1 resource toevoegen - C: Laden in Cursor — werkt + screenshot in MCP.md - D: `MCP.md` met tool-lijst + 3 voorbeeld-prompts + reflectie **Bonus:** publish naar npm, OR maak een HTTP-transport variant voor remote loading --- ## Slide 16: Volgende les + Afsluiting ### Vragen? **Vandaag gezien:** - MCP = open protocol voor AI ↔ tools/data - Drie primitieven: tools, resources, prompts - Twee transports: stdio + HTTP/SSE - Eigen server in <50 regels code - Werkt in Cursor + Claude Desktop + custom clients **Volgende les (Les 17): Externe APIs in diepte** - OAuth flows (Google, GitHub login) - Webhooks ontvangen + verifiëren - Paid APIs (Stripe, Resend) - Rate-limiting + retry patterns **Daarna:** Les 18 — Supabase Auth + RLS multi-user (de laatste!) **Vragen?** --- ## Slide Summary | # | Title | Type | |---|-------|------| | 1 | Title | Opening | | 2 | Terugblik | Recap | | 3 | Planning | 180-min | | 4 | Wat is MCP | Theorie | | 5 | MCP architectuur | Theorie | | 6 | Bestaande servers | Theorie | | 7 | Eigen server bouwen | Theorie | | 8 | Wat we bouwen | Intro | | 9 | **DEMO 1** — SDK setup | Demo | | 10 | **DEMO 2** — Laden Cursor/Claude | Demo | | 11 | Pauze | Break | | 12 | **DEMO 3** — Polderfest server | Demo | | 13 | **DEMO 4** — Resources + Prompts | Demo | | 14 | MCP vs Tool Calling | Reflectie | | 15 | Lesopdracht + Huiswerk | Praktijk | | 16 | Afsluiting | Closing | --- ## Bronnen - **MCP officiële site:** https://modelcontextprotocol.io/ - **MCP SDK (TS):** https://github.com/modelcontextprotocol/typescript-sdk - **MCP Inspector:** `npx @modelcontextprotocol/inspector` - **Anthropic announcement:** https://www.anthropic.com/news/model-context-protocol - **Cursor MCP docs:** https://docs.cursor.com/context/model-context-protocol - **Claude Desktop MCP:** https://docs.anthropic.com/en/docs/build-with-claude/mcp - **Awesome MCP servers:** https://github.com/punkpeye/awesome-mcp-servers