fix: les
This commit is contained in:
404
Les15-MCP/Les15-Slide-Overzicht.md
Normal file
404
Les15-MCP/Les15-Slide-Overzicht.md
Normal file
@@ -0,0 +1,404 @@
|
||||
# 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=<jouw-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 <url>` 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 = <plak>
|
||||
- SUPABASE_SERVICE_ROLE_KEY = <plak>
|
||||
Daarna: deploy naar productie en geef me de URL terug.
|
||||
```
|
||||
|
||||
**Resultaat:** je krijgt een productie-URL terug — `polderfest-mcp-<scope>.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.
|
||||
Reference in New Issue
Block a user