# Les 15 — MCP (Model Context Protocol) ## Slide Overzicht (Klas A — 3 uur fysiek, demo + hands-on) **Lesvorm:** ±1 uur theorie + live demos (veel koppelen, weinig zelf coderen), daarna ±1,5 uur hands-on **Demo-MCPs:** GitHub MCP, Supabase MCP, Vercel MCP (bestaand) + Polderfest MCP (eigen) **Vervolg op:** Les 13 — Agents (Polderfest agent met 5 tools) **Aansluit op:** Les 16 — RAG + Embeddings --- ## Blok-structuur | Blok | Onderwerp | Slides | |------|-----------|--------| | 1 | Welkom + Vandaag | 1–2 | | 2 | Wat is MCP + ecosysteem | 3–6 | | 3 | Vier MCPs koppelen — live | 7–10 | | 4 | Polderfest MCP — eigen server | 11–13 | | 5 | LIVE — De drie chats workflow | 14–17 | | 6 | Lesopdracht + Extra + Vooruitblik | 18–20 | --- ## Slide 1: Title ### Les 15 — MCP **Visual:** - Background: CREAM - "Les 15" in BLUE - "Model Context Protocol" in BLACK - Subtitle: "Geef AI-clients superkrachten via standard-tools" - Iconen: GitHub + Supabase + Vercel + Polderfest --- ## Slide 2: Vandaag ### Drie blokken + climax **Wat we vandaag doen:** 1. **Theorie** — wat is MCP, waarom bestaat het (kort) 2. **Vier MCPs koppelen** — GitHub, Supabase, Vercel, Polderfest 3. **De drie chats workflow** — alles samen aan het werk **Climax (in drie chats):** - Chat 1: GitHub MCP maakt repo + voegt remote toe - Chat 2: Polderfest features bouwen via Cursor + Supabase MCP - Chat 3: Vercel MCP project + deploy Vandaag is dus meer koppelen en zien dan zelf coderen. --- ## Slide 3: Wat is MCP ### Eén standaard, vele clients **Model Context Protocol legt vast:** - Hoe AI-clients verbinding maken met tools en data - Hoe servers tools, resources en prompts beschrijven - Hoe data heen-en-weer stroomt over een transport **Open spec — geen vendor lock-in:** - Gestart door Anthropic (november 2024) - Cursor, Claude Desktop, OpenAI, Windsurf, Zed ondersteunen het **Analogie:** USB-C voor AI. Eén stekker, elke laptop. --- ## Slide 4: Het probleem ### Voor MCP | Voor MCP | Met MCP | |----------|---------| | Cursor: extension API | Eén MCP-server | | Claude Desktop: plugins | Cursor: werkt | | ChatGPT: GPTs/Actions | Claude Desktop: werkt | | Windsurf: eigen API | ChatGPT: werkt | | Zed: eigen API | Windsurf: werkt | | **= 5 integraties** | **= 1 integratie** | Dezelfde tool, één keer bouwen, overal beschikbaar. --- ## Slide 5: Architectuur + primitives ### MCP in één plaatje **Drie rollen:** | Rol | Voorbeeld | |-----|-----------| | **Host** | Cursor, Claude Desktop | | **Client** | MCP library (zit in host) | | **Server** | GitHub MCP, jouw Polderfest | **Drie primitives:** | Primitive | Wat | |-----------|-----| | **Tools** | functies (AI doet iets) | | **Resources** | read-only data | | **Prompts** | templates / persona's | Vandaag focus op tools. --- ## Slide 6: Het MCP-ecosysteem ### Honderden servers beschikbaar **Top servers:** | Server | Wat je krijgt | |--------|---------------| | GitHub | issues, PRs, repos, commits | | Supabase | DB queries, schema, migrations | | Vercel | projects aanmaken, deploys | | Filesystem | lees/schrijf in folders | | Slack / Linear / Jira | werk-tickets | | Brave Search / Notion / Postgres | enz. | Vandaag koppelen we **vier** in Cursor: GitHub, Supabase, Vercel — en onze eigen Polderfest. --- ## Slide 7: Vier MCPs vandaag ### Het overzicht | MCP | Type | Auth | |-----|------|------| | **GitHub** | HTTP (remote) | Bearer (PAT) | | **Supabase** | HTTP (remote) | Bearer (sbp_-token) | | **Vercel** | HTTP (remote) | OAuth (browser-flow) | | **Polderfest** | HTTP (lokaal) | geen (jouw eigen server) | **Alle vier in één `mcp.json`** — zelfde patroon, andere URLs. **Visual:** vier logo's met een pijl naar Cursor. --- ## Slide 8: De `mcp.json` config ### `~/.cursor/mcp.json` — globaal ```jsonc { "mcpServers": { "supabase": { "type": "http", "url": "https://mcp.supabase.com/mcp?project_ref=&read_only=true", "headers": { "Authorization": "Bearer sbp_..." } }, "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer ghp_..." } }, "vercel": { "type": "http", "url": "https://mcp.vercel.com" }, "polderfest": { "type": "http", "url": "http://localhost:3000/api/mcp" } } } ``` Eén patroon: `type: http` + `url` + optioneel `headers`. Vercel doet OAuth. --- ## Slide 9: Tokens regelen ### Drie tokens, één OAuth **GitHub PAT (fine-grained):** - github.com → Settings → Developer settings → Personal access tokens → Fine-grained - Repo-permissies: Contents + Issues + Pull requests (read+write) - Token begint met `ghp_...` **Supabase Personal Access Token:** - supabase.com → Account → Access Tokens → Generate - ⚠️ Account-level — NIET project anon key / service role - Token begint met `sbp_...` - `project_ref` haal je uit Supabase project URL **Vercel:** geen token vooraf. Bij eerste gebruik in Cursor → OAuth-prompt → toestaan. --- ## Slide 10: Live koppelen + check ### Vier stappen **1.** `mkdir -p ~/.cursor && nano ~/.cursor/mcp.json` **2.** Plak de JSON van slide 8 + vul je tokens in **3.** **Volledig herstart Cursor** (`Cmd+Q`, opnieuw openen) **4.** Open een chat — onderaan MCP-indicator → moet **4 servers groen** tonen **Voor Vercel:** klik op "Needs login" → OAuth-flow → autoriseer **Visual:** screenshot van 4 groene indicators. --- ## Slide 11: Polderfest MCP ### Onze eigen server `polderfest-mcp-finished.zip` bevat een complete Next.js-app: ``` polderfest-mcp/ ├── app/ │ ├── api/mcp/route.ts ← MCP server zelf │ ├── lib/supabase.ts ← Supabase client │ ├── page.tsx ← landingspagina │ └── layout.tsx ├── package.json ← mcp-handler + sdk + zod ├── .env.example └── README.md ``` **Vier tools:** `searchBands` · `getStageSchedule` · `festivalStats` · `getWeather` --- ## Slide 12: Code-tour ### Eén tool — anatomie ```typescript server.tool( "searchBands", "Zoek bands op query, genre, of dag.", { query: z.string().optional(), genre: z.string().optional(), day: z.enum(["vrijdag","zaterdag","zondag"]).optional(), }, async ({ query, genre, day }) => { let q = supabase.from("bands").select("*").limit(50); if (query) q = q.ilike("name", `%${query}%`); if (day) q = q.eq("day", capitalizeDay(day)); const { data } = await q; return { content: [{ type: "text", text: JSON.stringify(data) }] }; }, ); ``` **Bekend:** Zod (uit Les 12/13). **Nieuw:** `server.tool()` + content-array. --- ## Slide 13: Lokaal draaien ### Drie commando's ```bash unzip polderfest-mcp-finished.zip cd polderfest-mcp-finished npm install cp .env.example .env.local # vul SUPABASE_URL + SERVICE_ROLE_KEY (uit Les 11/12) npm run dev ``` - Landingspagina: `localhost:3000` - MCP endpoint: `localhost:3000/api/mcp` - Polderfest entry zit al in `mcp.json` — herstart Cursor → 4 servers groen --- ## Slide 14: De drie chats workflow ### Demo overview — alles samen **Drie aparte Cursor-chats. Elke chat = één doel:** | Chat | MCP | Doel | |------|-----|------| | **Chat 1** | GitHub MCP | Maak GitHub repo + voeg toe als remote | | **Chat 2** | Polderfest + Supabase MCP | Bouw een nieuwe feature in onze MCP-server | | **Chat 3** | Vercel MCP | Maak Vercel project + deploy + env vars | **Resultaat:** complete deploy van een nieuwe feature, vanaf je editor, zonder browser of CLI-commando's. **Visual:** flow-diagram drie chats → één live productie-URL. --- ## Slide 15: Chat 1 — GitHub MCP ### Repo aanmaken + remote toevoegen **Cursor chat 1 — prompt:** ``` Maak een nieuwe public GitHub repo "polderfest-mcp" aan via GitHub MCP. Voeg toe als remote `origin` aan deze folder. Push de main branch. ``` **Wat er gebeurt:** - GitHub MCP roept `create_repository` aan → krijgt URL terug - Cursor draait `git remote add origin ` in terminal - Cursor draait `git push -u origin main` - Open github.com → repo staat er met onze code **Geen browser. Geen `gh repo create` zelf typen.** --- ## Slide 16: Chat 2 — Polderfest features ### Bouw via Cursor + Supabase MCP **Cursor chat 2 — prompt (nieuwe chat!):** ``` Ik wil een review-systeem voor de Polderfest MCP. Stap 1: vraag Supabase MCP om een tabel `band_reviews` te maken (id, band_id FK naar bands, score 1-10, comment, created_at) Stap 2: voeg twee tools toe aan @file:app/api/mcp/route.ts: - addReview(bandName, score, comment) - getReviews(bandName) Gebruik dezelfde patroon als bestaande tools. ``` **Test live in dezelfde chat:** - *"Geef Maud and The Cathedrals een review: 9, episch."* - *"Toon alle reviews voor Maud and The Cathedrals."* → Polderfest MCP voert addReview en getReviews uit. --- ## Slide 17: Chat 3 — Vercel MCP ### Project + deploy + env vars **Cursor chat 3 — prompt (nieuwe chat!):** ``` Maak via Vercel MCP een nieuw Vercel-project voor mijn GitHub repo `polderfest-mcp`. Voeg toe als env vars (production): - SUPABASE_URL = - SUPABASE_SERVICE_ROLE_KEY = Daarna: deploy naar productie en geef me de URL terug. ``` **Resultaat:** je krijgt een productie-URL terug — `polderfest-mcp-.vercel.app/api/mcp`. **Tot slot:** vervang in `mcp.json` de polderfest-URL `localhost:3000` door de productie-URL. Herstart Cursor → werkt nu **zonder** dat npm run dev draait. --- ## Slide 18: Nu jullie — Lesopdracht ### Doorloop de hele flow zelf **Stappen (basis, ±1 uur):** 1. Pak `polderfest-mcp-finished.zip` uit + `npm install` + env vars 2. `npm run dev` — test lokaal 3. Voeg vier MCPs toe aan `~/.cursor/mcp.json` (template in lesbestanden) 4. Herstart Cursor — check 4 indicators groen 5. **Chat 1:** GitHub MCP → repo aanmaken + remote 6. **Chat 2:** Test Polderfest MCP met een paar vragen 7. **Chat 3:** Vercel MCP → project + deploy 8. Update mcp.json met productie-URL → herstart Cursor → werkt zonder localhost **Geen deliverables.** Gewoon doen tot het werkt. --- ## Slide 19: Extra werk ### Voeg een eigen feature toe **Voor wie sneller is.** Doe wat Tim in Chat 2 deed — voor je eigen idee. **Patroon:** 1. Supabase MCP → tabel + seed-data via Cursor 2. Cursor → genereer nieuwe tool(s) in `route.ts` 3. Push → Vercel deploy't automatisch (omdat het project gekoppeld is) 4. Test in Cursor chat **Ideeën:** - `addReview` + `getReviews` (zoals de demo) - `addToWishlist` + `getMyWishlist` - `rateStage` + `getStageRatings` - `addNote` + `getNotes` **Geen deliverables.** --- ## Slide 20: Volgende les ### Les 16 — RAG + Embeddings **Wat we gaan bouwen:** - PDF Q&A-app from scratch - Embeddings + vector search (pgvector) - AI antwoorden op basis van eigen documenten **Voorbereiding:** - Polderfest MCP staat live op Vercel - Vier MCPs gekoppeld in Cursor — github, supabase, vercel, polderfest - Supabase project blijft draaien — we breiden uit met pgvector **Visual:** document → vector → AI.