Tutorials

Zelf een MCP-server maken: stap voor stap

Een eigen MCP-server bouwen klinkt als diepe techniek, maar het komt neer op één functie die je AI mag aanroepen. Dit is de complete route: van een tool definiëren tot registreren in Claude en veilig testen, in gewone taal en met geverifieerde code.

Dennis ClaassenDennis Claassen12 min lezen
Drie verlichte sokkels op een donker podium die tool, resource en prompt verbeelden, de drie bouwstenen van een zelfgebouwde MCP-server

AI-tools leren gebruiken?

In onze masterclass leer je ChatGPT, Claude en Gemini effectief inzetten voor je werk.

Dennis Claassen

Dennis Claassen

AI-trainer · 35+ teams getraind

Bekijk de Masterclass

Key Takeaways

  • Een MCP-server is gewoon een programma dat je AI drie soorten dingen kan aanbieden: tools (acties), resources (alleen-lezen data) en prompts (herbruikbare templates). Bron: modelcontextprotocol.io.
  • Je hebt geen zwaar framework nodig. In Python definieer je een tool met één decorator (@mcp.tool()); in TypeScript met server.registerTool(...). Bron: build-server docs.
  • Registreren in Claude Desktop is een paar regels JSON in claude_desktop_config.json, daarna herstarten. Bron: build-server docs.
  • Test eerst los met de MCP Inspector (npx @modelcontextprotocol/inspector ...) voordat je hem aan een AI hangt. Bron: inspector docs.
  • MCP is sinds eind 2025 een vendor-neutrale standaard: Anthropic doneerde het protocol op 9 december 2025 aan de Agentic AI Foundation onder de Linux Foundation. Bron: Anthropic.

Je vraagt Claude naar het weer van morgen. Hij verzint een antwoord, want hij heeft geen idee wat het echte weerbericht is. Frustrerend, want jij weet precies waar die data staat. Het gat tussen wat de AI kan en wat hij weet, is exact het gat dat een MCP-server dicht. Een klein programma dat jij schrijft, en dat de AI mag aanroepen. En je kunt er vandaag nog een bouwen.

MCP (Model Context Protocol) is de stekkerstandaard tussen AI-modellen en de buitenwereld. Een AI weet uit zichzelf niets van jouw agenda, jouw database of de live wisselkoers. Een MCP-server is het bruggetje dat die kennis en acties aanbiedt op een manier die elk MCP-compatibel AI-model begrijpt. Eén keer bouwen, overal bruikbaar.

En hier zit de winst: tot voor kort moest je voor elke AI-tool een eigen koppeling schrijven. MCP maakt daar één protocol van. Geïntroduceerd in november 2024 door Anthropic, en inmiddels overgenomen door zo ongeveer iedereen die ertoe doet (bron: Wikipedia). Meer daarover zo. Eerst de bouwstenen.

Wat is een MCP-server, en welk probleem lost MCP op?

Denk aan een MCP-server als een baliemedewerker tussen de AI en jouw systemen. De AI vraagt iets, de balie weet precies welke loketten er zijn, en geeft netjes antwoord. Die loketten zijn van drie soorten.

De drie bouwstenen: tools, resources en prompts

Een MCP-server biedt volgens de officiële documentatie drie soorten capabilities aan (bron: modelcontextprotocol.io):

  • Tools zijn acties. Functies die de AI met jouw toestemming mag aanroepen, zoals "stuur deze e-mail" of "haal de omzet van vorige maand op". Dit lijkt sterk op tool-use, alleen dan via een standaard die los staat van het model.
  • Resources zijn alleen-lezen data. Bestand-achtige context die de AI mag inzien, maar niet kan veranderen. Denk aan een documentje, een logbestand of een stukje configuratie.
  • Prompts zijn herbruikbare templates. Kant-en-klare instructies die een gebruiker kan oproepen.

Het verschil tussen een tool en een resource is het verschil tussen een knop en een prikbord. Een tool dóét iets. Een resource laat iets zien. Wil je dat de AI informatie ophaalt zonder iets aan te raken, dan is dat een resource. Mag hij iets uitvoeren, dan is dat een tool. Simpel als dat.

Voor de meeste eerste servers begin je met één tool. De rest komt vanzelf.

Waarom MCP nu een veilige keuze is

Een terechte vraag voordat je tijd investeert: bind ik me hiermee aan één leverancier? Het antwoord is nee, en dat werd recent extra hard gemaakt.

Op 9 december 2025 doneerde Anthropic het Model Context Protocol aan de Agentic AI Foundation, een onderdeel van de Linux Foundation. Die foundation is mede-opgericht door Anthropic, Block en OpenAI, met steun van onder andere Google, Microsoft, AWS, Cloudflare en Bloomberg (bron: Anthropic). Vertaald: MCP is niet langer het speeltje van één bedrijf, maar een gedeelde standaard die de grootste namen samen dragen.

Dat zie je ook in de adoptie. OpenAI nam MCP over in maart 2025, Google DeepMind in april 2025 (bron: Wikipedia). Wat jij vandaag bouwt, blijft dus werken, ook als je later van AI-model wisselt.

Kies je SDK: Python of TypeScript

Je kunt een MCP-server in meerdere talen schrijven, maar voor de meeste mensen komt het neer op twee keuzes.

Kies Python als je snel een prototype wilt. De Python-SDK heeft FastMCP, waarmee een tool letterlijk één regel boven je functie is (bron: Python SDK). Ideaal als je vooral met data, scripts of bestaande Python-code werkt.

Kies TypeScript als je in het npm-ecosysteem zit, een webachtergrond hebt, of je server later wilt bundelen met een frontend. De TypeScript-SDK gebruikt Zod voor het beschrijven van invoer, wat je meteen typeveiligheid geeft (bron: TypeScript SDK).

Allebei werken even goed en spreken hetzelfde protocol. Twijfel je? Pak Python voor je eerste server. Je bent in tien minuten op gang.

De fout die mensen hier maken: de taal kiezen die het "serieust" aanvoelt in plaats van de taal die ze al kennen. Een MCP-server in een vreemde taal is een server die je nooit afmaakt. Pak wat je al spreekt; het protocol is identiek, dus je verliest niks.

Je omgeving opzetten

Voor de Python-route heb je Python 3.10 of nieuwer nodig en op dit moment de MCP Python SDK in versie 1.2.0 of hoger (bron: build-server docs). De officiële docs gebruiken uv als package-manager:

uv init weather
cd weather
uv add "mcp[cli]"

Voor de TypeScript-route heb je een recente Node.js-versie nodig plus twee pakketten:

npm install @modelcontextprotocol/sdk zod@3

Verder niets. Geen account, geen server in de cloud, geen abonnement. Een MCP-server draait gewoon lokaal op je eigen machine.

Eén ding dat veel mensen verrast: een te oude Python of Node draait wel, maar geeft pas bij het registreren cryptische fouten. Controleer de versie vooraf (python --version), dan voorkom je een halfuur zoeken naar een probleem dat geen probleem is.

Een tool definiëren (met codevoorbeeld)

Genoeg theorie. We bouwen een minimale server met één tool, en je ziet meteen hoe weinig code het kost. In Python ziet dat er zo uit:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather")

@mcp.tool()
async def get_forecast(city: str) -> str:
    """Haal het weerbericht op voor een stad."""
    # Hier roep je je eigen logica of een externe API aan
    return f"Het wordt morgen zonnig in {city}."

if __name__ == "__main__":
    mcp.run(transport="stdio")

Drie dingen doen het werk. De decorator @mcp.tool() zegt: dit is een tool die de AI mag aanroepen. De type hints (city: str) vertellen het model welke invoer verwacht wordt. En de docstring is geen bijzaak, dat is de beschrijving die de AI leest om te snappen wát de tool doet. Schrijf die dus als een nette uitleg, niet als een kreet.

In TypeScript is het idee identiek, alleen wat explicieter:

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: "weather", version: "1.0.0" });

server.registerTool(
  "get_forecast",
  {
    description: "Haal het weerbericht op voor een stad.",
    inputSchema: { city: z.string() },
  },
  async ({ city }) => ({
    content: [{ type: "text", text: `Het wordt morgen zonnig in ${city}.` }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);

Zie je de parallel? registerTool krijgt een naam, een beschrijving, een invoer-schema (via Zod, dat hier de rol van de Python type hints overneemt) en de functie zelf. De server praat via StdioServerTransport, oftewel standaard in- en uitvoer. Daar komen we zo nog op terug, want dat heeft een verraderlijke valkuil.

Beide voorbeelden zijn gebaseerd op de officiële build-server-tutorial (bron: modelcontextprotocol.io). Wil je een complete, werkende weather-server klonen in plaats van overtikken? Die staat in de officiële quickstart-repo.

Een resource toevoegen (alleen-lezen context)

Een tool is een actie. Wil je de AI iets láten lezen zonder dat hij iets uitvoert, dan voeg je een resource toe. In de Python-SDK gebruik je daarvoor een vergelijkbare decorator, en je kunt zelfs een placeholder in het pad zetten (bron: Python SDK):

@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    return f"Hallo, {name}!"

De {name} in greeting://{name} is een template. De AI kan dus greeting://Dennis opvragen en krijgt jouw begroeting terug. Handig voor dingen als config://settings of bestand://logboek waar je context aanbiedt zonder dat het model iets mag wijzigen.

Je server lokaal registreren in Claude

Je server werkt, maar Claude weet nog niet dat hij bestaat. Je vertelt dat via een configbestand.

Op macOS staat dat hier: ~/Library/Application Support/Claude/claude_desktop_config.json. Op Windows is het $env:AppData\Claude\claude_desktop_config.json (bron: build-server docs). Open dat bestand en zet je server onder de sleutel mcpServers.

Voor de Python-server:

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["--directory", "/absoluut/pad/naar/weather", "run", "weather.py"]
    }
  }
}

Voor de TypeScript-server:

{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["/absoluut/pad/naar/weather/build/index.js"]
    }
  }
}

Let op dat ene woord: absoluut. Een relatief pad werkt hier niet, want Claude weet niet vanuit welke map jij denkt. Geef het volledige pad. Daarna Claude Desktop helemaal afsluiten en opnieuw openen, anders pikt hij de wijziging niet op.

Klein voorbehoud: Claude for Desktop is op dit moment niet beschikbaar op Linux. Werk je op Linux, gebruik dan de Inspector hieronder, of koppel je server aan een andere MCP-client die wél op jouw systeem draait.

AI Training

Wil je AI leren inzetten?

In onze praktische trainingen leer je hoe je ChatGPT, Claude en andere AI-tools effectief inzet voor jouw werk.

Testen met de MCP Inspector

Voordat je je server aan een AI hangt, wil je weten of hij überhaupt doet wat hij moet doen. Daar is de MCP Inspector voor. Een los testgereedschap dat je server start en je in een interface laat zien welke tools, resources en prompts er zijn.

Het mooie: je hoeft niks te installeren, het draait via npx. Voor een TypeScript-server (bron: inspector docs):

npx @modelcontextprotocol/inspector node path/to/server/index.js

Voor een Python-server:

npx @modelcontextprotocol/inspector uv --directory path/to/server run package-name

De Inspector opent een interface in je browser met aparte tabs voor Tools, Resources en Prompts, en een paneel om de verbinding (het transport) te kiezen. Klik je tool aan, vul een waarde in, en kijk of het antwoord klopt. Werkt het hier, dan werkt het straks ook in Claude. Werkt het hier niet, dan heb je net een hoop frustratie in de AI-client voorkomen.

En dan die valkuil die ik eerder noemde. Bij stdio-servers mag je nooit naar stdout schrijven. In Python betekent dat: geen kale print(...), maar print(..., file=sys.stderr) of een logger. In TypeScript: console.error() in plaats van console.log() (bron: build-server docs). De reden is technisch maar belangrijk: stdout is het kanaal waarover de protocol-berichten lopen. Eén losse print verstoort dat verkeer en je server breekt zonder duidelijke foutmelding. Dit is verreweg de meestgemaakte "het werkt niet"-fout. Onthoud hem.

Veilig bouwen: het least-privilege-principe

Een MCP-server is krachtig, en daar hoort verantwoordelijkheid bij. Een lokale server draait met dezelfde rechten als jij. Geeft je server toegang tot je bestanden, dan heeft de AI die ook. Daarom een paar regels die de officiële docs voorschrijven (bron: security best practices).

Begin met de kleinst mogelijke rechten en breid pas uit als het nodig is. De docs noemen dit een "progressive, least-privilege scope model": start met alleen lezen en laag-risico acties, en verhoog stap voor stap. Vermijd alles-of-niets-scopes zoals *, all of full-access. Een tool die alleen het weer ophaalt, hoeft niet bij je bestanden te kunnen.

Twee dingen nog. Een MCP-server mag geen tokens accepteren die niet expliciet aan hém zijn uitgegeven, anders wordt hij een doorgeefluik voor andermans toegang. En zet nooit geheimen in je logs of in stdout. Draai bovendien alleen code die je vertrouwt, net zoals je geen willekeurig script van internet als beheerder zou starten.

Niets hiervan is ingewikkeld. Het is dezelfde voorzichtigheid die je bij elke andere software hanteert. Maar omdat een AI je tools autonoom kan aanroepen, telt elke onnodige rechten-bevoegdheid dubbel.

Werkt je server ook buiten Claude?

Ja. Dat is precies het punt van een standaard. Een MCP-server die je voor Claude bouwt, werkt net zo goed met andere MCP-clients. OpenAI ondersteunt MCP (onder andere in de ChatGPT-desktopapp), Google adopteerde het, en ook coding-platforms zoals Replit en code-intelligence-tools zoals Sourcegraph hebben MCP overgenomen (bron: Wikipedia).

Je schrijft dus één keer en koppelt overal: dezelfde server bedient Claude, ChatGPT en je editor zonder dat je iets verandert.

Eén eerlijke kanttekening uit de community. Een veelgehoorde klacht is dat MCP-servers veel tools tegelijk in het contextvenster laden, waardoor de AI het overzicht verliest. Volgens MCP-mede-bedenker David Soria Parra is dat geen probleem van het protocol zelf, maar van hoe sommige clients het implementeren, en het wordt al opgelost via "progressive discovery": tools pas laden wanneer ze nodig zijn (bron: Obot AI). Goed om te weten, geen reden om te wachten.

Van eerste server naar echte koppeling

Je hebt nu het hele plaatje: wat een MCP-server is, hoe je een tool en een resource definieert, hoe je hem registreert in Claude, hoe je hem veilig test, en waarom hij overal werkt. De volgende stap is bewust kiezen wat je wilt ontsluiten. Begin klein. Eén tool die één echt probleem oplost, is meer waard dan tien half-werkende.

Wil je inspiratie of de volgende stap? De officiële servers-repo staat vol referentievoorbeelden (filesystem, git) waar je de bouwpatronen van bestaande AI-agents van afkijkt, en hoe je een server inzet binnen een echte werkflow lees je in Claude Code gebruiken.

Wil je dit niet alleen lezen maar onder begeleiding bouwen, met je eigen use case en je eigen systemen? Daar is onze MCP-protocol training voor gemaakt. Je gaat naar huis met een werkende server die op jouw werk aansluit, niet met een weerbericht-voorbeeld.

Bronnen

Veelgestelde vragen

Wat is een MCP-server in gewone taal?

Een MCP-server is een klein programma dat als bruggetje werkt tussen een AI-model en jouw systemen. Het biedt drie soorten dingen aan: tools (acties die de AI mag uitvoeren), resources (alleen-lezen data die de AI mag inzien) en prompts (herbruikbare templates). Omdat het Model Context Protocol een open standaard is, werkt één zelfgebouwde server met elke MCP-compatibele AI, van Claude tot ChatGPT.

Heb je Python of TypeScript nodig voor een MCP-server?

Allebei kan, en ze spreken hetzelfde protocol. Kies Python als je snel een prototype wilt: met de FastMCP-SDK is een tool één decorator boven je functie. Kies TypeScript als je in het npm-ecosysteem zit of je server later met een frontend wilt bundelen; daar gebruik je Zod om de invoer te beschrijven. Voor je eerste server is Python meestal het snelst op gang.

Hoe registreer ik mijn MCP-server in Claude Desktop?

Open het configbestand claude_desktop_config.json (op macOS in ~/Library/Application Support/Claude/, op Windows in $env:AppData\Claude\) en zet je server onder de sleutel mcpServers. Gebruik altijd een absoluut pad naar je serverbestand, geen relatief pad. Sluit daarna Claude Desktop volledig af en open het opnieuw, anders wordt de wijziging niet opgepikt. Let op: Claude for Desktop is op dit moment niet op Linux beschikbaar.

Hoe test ik of mijn MCP-server werkt?

Gebruik de MCP Inspector, een los testgereedschap dat zonder installatie via npx draait. Voor TypeScript: npx @modelcontextprotocol/inspector node path/to/server/index.js. Voor Python: npx @modelcontextprotocol/inspector uv --directory path/to/server run package-name. De Inspector toont aparte tabs voor Tools, Resources en Prompts zodat je elke functie los kunt aanroepen voordat je hem aan een AI koppelt.

Wat is het verschil tussen een tool en een resource in MCP?

Een tool is een actie: een functie die de AI met jouw toestemming mag uitvoeren, zoals een e-mail sturen of data ophalen. Een resource is alleen-lezen: bestand-achtige context die de AI mag inzien maar niet kan veranderen, zoals een document of een logbestand. Kort gezegd: een tool dóét iets, een resource laat iets zien. Daarnaast bestaan er prompts, dat zijn herbruikbare instructie-templates.

Tags
mcpmcp-servermodel-context-protocolclaudedeveloper-toolsai-agents
Dennis Claassen
Geschreven door

Dennis Claassen

Founder & AI Trainer

Dennis is de oprichter van Project Impact en traint Nederlandse bedrijven in het effectief gebruiken van AI. Met jarenlange ervaring in tech en onderwijs helpt hij teams om AI praktisch toe te passen.

AI leren toepassen in je bedrijf?

Ontdek onze praktische AI trainingen voor teams.