fix: les
This commit is contained in:
147
Les15-MCP/Les15-Huiswerk.md
Normal file
147
Les15-MCP/Les15-Huiswerk.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Les 15 — Huiswerk
|
||||
## Voeg een eigen tool toe aan je Polderfest MCP server
|
||||
|
||||
**Vak:** AI-Assisted Development
|
||||
**Opleiding:** NOVI Hogeschool Utrecht
|
||||
**Werkvorm:** take-home (±1–2 uur)
|
||||
**Deadline:** vóór Les 16
|
||||
|
||||
---
|
||||
|
||||
## Doel
|
||||
|
||||
Je breidt je Polderfest MCP server uit met minimaal één eigen tool. Daarmee laat je zien dat je het patroon van `server.tool()` zelf kunt toepassen — en je geeft Cursor een nieuwe mogelijkheid die er niet eerder was.
|
||||
|
||||
---
|
||||
|
||||
## Wat je gaat doen
|
||||
|
||||
### Stap 1 — Bedenk een tool
|
||||
|
||||
Kies één van de voorbeelden hieronder, of bedenk er zelf één.
|
||||
|
||||
#### Voorbeeld A — `findBandsByVibe`
|
||||
|
||||
Input: een vibe-omschrijving (string, bv. "donker en stoer" of "vrolijk zonnig").
|
||||
Output: 5 bands die bij die vibe passen.
|
||||
|
||||
Implementatie-hint: gebruik `searchBands` onderliggend met een keyword-mapping, of vraag de AI om de vibe te interpreteren als genre.
|
||||
|
||||
#### Voorbeeld B — `comparePerformances`
|
||||
|
||||
Input: twee dagen (`day1`, `day2`).
|
||||
Output: vergelijking — hoeveel bands per stage, populairste genres, schema-conflicten.
|
||||
|
||||
#### Voorbeeld C — `recommendForGenres`
|
||||
|
||||
Input: een lijst favoriete genres (string array).
|
||||
Output: aanbevolen bands die in die genres vallen, gegroepeerd per dag.
|
||||
|
||||
#### Voorbeeld D — `getBandDetails`
|
||||
|
||||
Input: bandnaam (string).
|
||||
Output: alle info over die band — stage, dag, tijd, genre, eventueel duurtijd-berekening.
|
||||
|
||||
#### Voorbeeld E — `searchByTimeSlot`
|
||||
|
||||
Input: dag + tijdsblok (`day`, `from`, `to`).
|
||||
Output: welke bands spelen er in dat blok.
|
||||
|
||||
### Stap 2 — Implementeer
|
||||
|
||||
Open `app/api/mcp/route.ts` in je Polderfest MCP folder. Voeg je tool toe onder de bestaande tools.
|
||||
|
||||
**Template:**
|
||||
|
||||
```typescript
|
||||
server.tool(
|
||||
"naamVanTool",
|
||||
"Korte beschrijving — wat doet hij. Goede beschrijvingen helpen de AI te beslissen wanneer hij de tool aanroept.",
|
||||
{
|
||||
// Zod input-schema
|
||||
arg1: z.string(),
|
||||
arg2: z.enum(["optie1", "optie2"]).optional(),
|
||||
},
|
||||
async ({ arg1, arg2 }) => {
|
||||
// Jouw logica — meestal een Supabase-query
|
||||
const { data } = await supabase.from("bands")./* ... */;
|
||||
return {
|
||||
content: [
|
||||
{ type: "text", text: JSON.stringify(data, null, 2) },
|
||||
],
|
||||
};
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### Stap 3 — Lokaal testen
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
In Cursor: stel een vraag die je nieuwe tool zou moeten aanroepen. Check dat:
|
||||
- De MCP-indicator je tool laat zien
|
||||
- Cursor de tool aanroept (zie tool-call output in chat)
|
||||
- De output zinvol is
|
||||
|
||||
### Stap 4 — Pushen + deployen
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: <jouw tool-naam>"
|
||||
git push
|
||||
```
|
||||
|
||||
**Vercel deploy't automatisch** zodra je naar `main` pusht. Wacht ±45 seconden.
|
||||
|
||||
### Stap 5 — Test op productie
|
||||
|
||||
In Cursor (mcp.json wijst al naar productie-URL), stel dezelfde vraag. Check dat het ook live werkt.
|
||||
|
||||
---
|
||||
|
||||
## Op te leveren (via Teams)
|
||||
|
||||
1. **GitHub repo URL** met je nieuwe tool
|
||||
2. **Korte beschrijving** (3–5 zinnen):
|
||||
- Welke tool heb je gebouwd?
|
||||
- Welke probleem lost hij op?
|
||||
- Met welke prompt heb je hem in Cursor getest?
|
||||
3. **Twee screenshots:**
|
||||
- Cursor chat waar je tool aangeroepen wordt (zichtbaar in tool-call output)
|
||||
- De output die Cursor met je tool gaf
|
||||
|
||||
**Deadline:** vóór Les 16 (volgende week).
|
||||
|
||||
---
|
||||
|
||||
## Beoordeling
|
||||
|
||||
| Criterium | Punten |
|
||||
|-----------|--------|
|
||||
| Tool is gedefinieerd met juiste `server.tool()` signature | 25% |
|
||||
| Input-schema gebruikt Zod correct (geen `any`) | 15% |
|
||||
| Tool returnt valide MCP-output (`{ content: [...] }`) | 15% |
|
||||
| Tool werkt lokaal én op productie | 25% |
|
||||
| Beschrijving + screenshots compleet | 20% |
|
||||
|
||||
---
|
||||
|
||||
## Tips
|
||||
|
||||
- **Hou de tool focused.** Eén ding goed doen is beter dan vijf dingen half.
|
||||
- **Schrijf een goede description.** De AI leest die om te beslissen wanneer hij hem aanroept. Zwakke beschrijving = tool wordt niet gebruikt.
|
||||
- **Test met meerdere prompts.** Sommige tools worden alleen aangeroepen bij heel specifieke woorden — probeer variaties.
|
||||
- **Gebruik Cursor om Cursor te bouwen.** Vraag in een aparte Cursor chat: *"Schrijf een MCP tool voor X gebaseerd op de patronen in @file:app/api/mcp/route.ts"*. Meta!
|
||||
|
||||
---
|
||||
|
||||
## Vooruitblik
|
||||
|
||||
In Les 16 (RAG + Embeddings) ga je verder met je Supabase project, dus zorg dat:
|
||||
- Je MCP server live blijft staan
|
||||
- Je huiswerk-tool werkt (we komen erop terug)
|
||||
- Je `.cursor/mcp.json` correct wijst naar productie
|
||||
|
||||
Veel succes!
|
||||
Reference in New Issue
Block a user