Files
novi-lessons/Les16-MCP/Les16-Lesopdracht.md
2026-06-03 16:58:25 +02:00

4.5 KiB

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

mkdir mcp-demo && cd mcp-demo
pnpm init
pnpm add @modelcontextprotocol/sdk zod
pnpm add -D typescript @types/node tsx

tsconfig.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:

#!/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

pnpm tsc
# resultaat: dist/index.js

Stap 4 — Test met Inspector

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):

{
  "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):

{
  "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.logconsole.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