# Les 16 — Lesopdracht ## Eerste MCP server bouwen + laden in Cursor **Vak:** AI-Assisted Development **Duur:** 30 min in-class --- ## Doel Werkende MCP server met 1 tool, geladen in Cursor of Claude Desktop, en getest met een echte chat-vraag. --- ## Stap 1 — Setup ```bash mkdir mcp-demo && cd mcp-demo pnpm init pnpm add @modelcontextprotocol/sdk zod pnpm add -D typescript @types/node tsx ``` `tsconfig.json`: ```json { "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./dist", "strict": true, "esModuleInterop": true }, "include": ["src/**/*"] } ``` `package.json` — voeg `"type": "module"` toe. --- ## Stap 2 — Minimal server `src/index.ts`: ```typescript #!/usr/bin/env node 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: "demo-server", version: "1.0.0", }); // Mock data const BANDS = [ { name: "Lost Tigers", day: "Vrijdag", stage: "Main Stage", genre: "rock" }, { name: "Polderfunk", day: "Zaterdag", stage: "Main Stage", genre: "funk" }, { name: "Jazz Collective", day: "Zaterdag", stage: "Tent", genre: "jazz" }, { name: "Echo Bay", day: "Zondag", stage: "Beach Stage", genre: "indie" }, // ... voeg er een paar toe ]; server.tool( "searchBands", "Zoek bands op dag, stage of genre", { day: z.enum(["Vrijdag", "Zaterdag", "Zondag"]).optional(), stage: z.string().optional(), genre: z.string().optional(), }, async ({ day, stage, genre }) => { const results = BANDS.filter(b => (!day || b.day === day) && (!stage || b.stage === stage) && (!genre || b.genre === genre) ); return { content: [{ type: "text", text: JSON.stringify(results, null, 2), }], }; } ); const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP server started"); ``` --- ## Stap 3 — Build ```bash pnpm tsc # resultaat: dist/index.js ``` --- ## Stap 4 — Test met Inspector ```bash npx @modelcontextprotocol/inspector node dist/index.js ``` Browser opent automatisch op `http://localhost:5173`: 1. Klik "Tools" tab 2. Zie `searchBands` in de lijst 3. Klik "Call Tool" 4. Vul `day: Zaterdag` in 5. Verwacht: JSON met 2 bands Werkt? Door naar Cursor. --- ## Stap 5 — Laden in Cursor Open `~/.cursor/mcp.json` (maak aan als 'ie nog niet bestaat): ```json { "mcpServers": { "demo": { "command": "node", "args": ["/FULL/PATH/TO/mcp-demo/dist/index.js"] } } } ``` **Belangrijk:** - Vervang `/FULL/PATH/TO/` met je echte absolute path (`pwd` in terminal) - Geen `~`, geen relative paths Restart Cursor (Cmd+Q + opnieuw openen). Check: Cursor Settings → MCP → server "demo" zichtbaar met groen vinkje. --- ## Stap 6 — Test in Cursor chat In Cursor chat (Cmd+L of Cmd+I): > "Welke bands spelen op zaterdag?" Cursor roept `searchBands` aan en toont resultaat. Werkt? Klaar. --- ## Alternatief — Claude Desktop Als Cursor niet wil: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS): ```json { "mcpServers": { "demo": { "command": "node", "args": ["/FULL/PATH/TO/mcp-demo/dist/index.js"] } } } ``` Restart Claude Desktop. Chat input toont MCP-icon. Vraag stellen werkt identiek. --- ## Eisen - [ ] Project opgezet (package.json, tsconfig, ts source) - [ ] Build succesvol (`dist/index.js` bestaat) - [ ] MCP Inspector toont tool + tool werkt - [ ] Geladen in Cursor of Claude Desktop - [ ] Chat-vraag werkt — AI roept tool aan, geeft antwoord --- ## Veelvoorkomende problemen | Symptoom | Oplossing | |----------|-----------| | `cannot find module` | Check `"type": "module"` in package.json + `.js` extensies in imports | | Cursor toont server niet | Restart Cursor volledig (Cmd+Q). Check absolute path. Check JSON valid. | | Tool niet aanroepbaar | Check tool name + parameters in Inspector eerst | | Stdout pollution | `console.log` → `console.error` (stdout = protocol) | | `tsc` errors | Check tsconfig en moduleResolution | --- ## Klaar? Verder met huiswerk (`Les16-Huiswerk.md`): - 3 tools + 1 write-tool naar Supabase - 1 resource toevoegen - `MCP.md` met tool-lijst + voorbeeldprompts --- ## Tijdsindeling (30 min) | Stap | Tijd | |------|------| | 1-3 — Setup + minimal + build | 10 min | | 4 — Inspector test | 5 min | | 5 — Cursor config | 5 min | | 6 — Chat test | 5 min | | Buffer | 5 min |