378 lines
11 KiB
Markdown
378 lines
11 KiB
Markdown
# 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 — RAG + Embeddings
|
|
**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
|