
Je kunt een MCP-server bouwen die Claude daadwerkelijk aanroept in ongeveer 15 minuten. We hebben het geklokt op Node 20 en Python 3.11: een werkende add-tool, draaiend over stdio en opgepikt door Claude Desktop, kostte de eerste keer 14 minuten en onder de 5 zodra je de structuur kent. Deze handleiding bouwt dezelfde server twee keer, één keer in Python met FastMCP 2.x, één keer in TypeScript met @modelcontextprotocol/sdk 1.x, zodat je je stack kunt kiezen en echte code kunt kopiëren. Wil je eerst de architectuur en protocoltheorie, dan staat die in onze gids over het Model Context Protocol; hier bouwen we gewoon.
MCP-server snelstart: wat je bouwt
Een MCP-server is een klein programma dat tools, data en prompt-sjablonen beschikbaar stelt aan AI-clients zoals Claude, Cursor of VS Code via het Model Context Protocol. Je schrijft de server één keer, en elke MCP-compatibele client kan hem aanroepen. In deze handleiding bouw je een server met twee tools (een add-rekenmachine en een fetch_url-helper), draai je hem lokaal over stdio, test je hem en verbind je hem met een echte client.
Hier is alles wat je nodig hebt voordat je begint.
| Vereiste | Python-route | TypeScript-route |
|---|---|---|
| Runtime | Python 3.10+ (3.11 aanbevolen) | Node.js 20 LTS+ |
| Pakketbeheerder | uv (aanbevolen) of pip | npm, pnpm of bun |
| SDK | mcp 1.x / FastMCP 2.x | @modelcontextprotocol/sdk 1.x |
| Client om te testen | Claude Desktop, Claude Code of Cursor | hetzelfde |
| Testtool | npx @modelcontextprotocol/inspector | hetzelfde |
Beide routes leveren een server met identiek gedrag. Kies de taal waarin je team toch al werkt. Heb je geen voorkeur, begin dan met Python, want FastMCP maakt de eerste server korter.
Wat stelt een MCP-server eigenlijk beschikbaar?
Voordat je code schrijft, helpt het te weten welke drie dingen een server kan aanbieden. Een MCP-server stelt tools beschikbaar (functies die het model kan aanroepen, zoals "doorzoek de database"), resources (alleen-lezen data die het model kan laden, zoals een bestand of record) en prompts (herbruikbare prompt-sjablonen). De meeste servers die je bouwt zijn tool-zwaar; resources en prompts zijn optioneel.
MCP-server, gedefinieerd: een proces dat het Model Context Protocol spreekt en een lijst van tools, resources en prompts aankondigt die een AI-client tijdens runtime kan ontdekken en aanroepen.
De client (Claude Desktop, bijvoorbeeld) fungeert als host. Hij start je server of verbindt ermee, vraagt "welke tools heb je?", en roept ze dan aan wanneer het model besluit dat een tool nuttig is. Je roept het model nooit vanuit de server aan. De stroom loopt de andere kant op.

Die richting doet ertoe. Je server is een passieve leverancier. Hij wacht tot de client verbinding maakt, beantwoordt de ontdekkingsaanvraag en voert de aangeroepen tool uit. Houd dit mentale model vast en de rest van deze handleiding wordt vanzelf duidelijk.
Hoe bouw je een MCP-server in Python (stap voor stap)
Python is de snelste route naar een draaiende server, omdat FastMCP de protocol-bedrading afhandelt en gewone functies met een decorator in tools verandert. Alles hieronder gebruikt de officiële Python-SDK. Hier zijn de vier stappen.
Stap 1: project opzetten. Gebruik uv, inmiddels de standaard voor MCP-Python-projecten:
uv init mcp-demo
cd mcp-demo
uv add "mcp[cli]"Geef je de voorkeur aan pip: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]".
Stap 2: server schrijven. Maak server.py:
from mcp.server.fastmcp import FastMCP
import httpx
# Name shows up in the client's tool list
mcp = FastMCP("demo-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers and return the sum."""
return a + b
@mcp.tool()
async def fetch_url(url: str) -> str:
"""Fetch a URL and return the first 2000 characters of the body."""
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.get(url)
return resp.text[:2000]
if __name__ == "__main__":
mcp.run() # defaults to stdio transportTwee dingen om op te merken. De docstring wordt de toolbeschrijving die het model leest, dus schrijf hem als een instructie. En de type-hints (a: int) worden automatisch het invoerschema, zodat FastMCP het JSON-schema voor je genereert.
Stap 3: uitvoeren. mcp.run() start de server over stdio, het transport dat clients lokaal starten. Je voert dit tijdens de ontwikkeling niet direct uit; de client start het. Voor een snelle test gebruik je de dev-runner:
uv run mcp dev server.pyStap 4: schone output teruggeven. Een valkuil die nu al de moeite waard is om te noemen: geef een string of een getypeerde waarde terug, geen geneste dict in de hoop dat het rendert. We komen hier in het productiegedeelte op terug, maar kort gezegd kunnen dubbelzinnige retourtypes in sommige clients stilletjes worden afgekapt.
Dit is een complete Python-MCP-server. Twee tools, echte netwerkoproepen, automatisch schema. Vervolgens hetzelfde in TypeScript.
Hoe bouw je een MCP-server in TypeScript (stap voor stap)
De TypeScript-route gebruikt de officiële TypeScript-SDK direct en zod voor invoervalidatie. Het is iets uitgebreider dan FastMCP, maar de types zijn uitstekend en het deployt netjes naar Node-hosts.
Stap 1: project opzetten.
mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsxStap 2: server schrijven. Maak server.ts:
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" });
server.tool(
"add",
"Add two numbers and return the sum.",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}),
);
server.tool(
"fetch_url",
"Fetch a URL and return the first 2000 characters.",
{ url: z.string().url() },
async ({ url }) => {
const resp = await fetch(url);
const body = await resp.text();
return { content: [{ type: "text", text: body.slice(0, 2000) }] };
},
);
const transport = new StdioServerTransport();
await server.connect(transport);Stap 3: uitvoeren. Tijdens de ontwikkeling: npx tsx server.ts. Voor productie compileer je met tsc en draai je de gebouwde .js met Node. Let op de retourvorm: elke tool geeft { content: [{ type: "text", text: ... }] } terug. Die expliciete content-array is het TypeScript-equivalent van de "geef een schone string terug"-regel uit Python. De SDK wil getypeerde content-blokken, geen rauwe objecten.
Stap 4: invoer valideren met zod. Het schema z.string().url() weigert ongeldige invoer voordat je handler draait, precies wat je wilt wanneer een model de argumenten genereert.
Dezelfde twee tools, hetzelfde gedrag, idiomatisch TypeScript. Laten we nu beslissen hoe clients je server moeten bereiken.
stdio vs Streamable HTTP: welk transport kies je?
MCP-servers communiceren via een van twee transporten. stdio draait de server als lokaal subproces dat de client start en waarmee hij communiceert via standaard in-/uitvoer. Streamable HTTP draait de server als netwerkdienst waarmee clients via HTTP verbinden. Kies op basis van waar de server moet draaien.
| stdio | Streamable HTTP | |
|---|---|---|
| Waar het draait | Lokaal, gestart door de client | Op afstand of lokaal, als webdienst |
| Beste voor | Persoonlijke tools, dev, één machine | Gedeelde servers, teams, SaaS, cloud |
| Auth | Erft de machine van de gebruiker | Vereist OAuth 2.1 / token-auth |
| Opzetkosten | Laagst (gewoon een commando) | Vereist hosting + endpoint |
| Onze gemeten overhead | ~8-12 ms per oproep (lokaal) | ~40-70 ms per oproep (netwerkgebonden) |

De vuistregel: bouw en test op stdio, schakel pas over naar Streamable HTTP wanneer meer dan één persoon of machine de server nodig heeft. De meeste servers hoeven stdio nooit te verlaten. De bovenstaande aanroepen mcp.run() en StdioServerTransport() zijn al stdio, dus je bent klaar voor ontwikkeling.
Hoe test je je MCP-server met de Inspector
Voordat je je server in Claude inbouwt, test je hem geïsoleerd met de MCP Inspector. Het is een browser-UI die met je server verbindt, zijn tools opsomt en je ze handmatig laat aanroepen. Draai hem tegen je server:
# Python
npx @modelcontextprotocol/inspector uv run server.py
# TypeScript
npx @modelcontextprotocol/inspector npx tsx server.tsDe Inspector opent een lokale pagina waar je je tools add en fetch_url ziet, een testoproep afvuurt en het ruwe antwoord leest. Dit is de beste gewoonte voor MCP-ontwikkeling. Als het schema van een tool misvormd is of een retourwaarde fout, zie je het hier in seconden in plaats van te staren naar een stille fout in Claude. We vingen zo een verkeerd invoerschema dat ons anders een volledige debug-ronde door de client had gekost. Test elke keer eerst in de Inspector.
Hoe verbind je je MCP-server met Claude Desktop, Claude Code en Cursor
Zodra de Inspector tevreden is, richt je een echte client op je server. Elke client leest een configuratiebestand dat hem vertelt hoe je server over stdio te starten.
Claude Desktop. Bewerk claude_desktop_config.json (op macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"demo-server": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/mcp-demo", "run", "server.py"]
}
}
}Herstart Claude Desktop en je tools verschijnen onder het connectors-icoon.
Claude Code. Voeg de server toe met één commando vanuit je project: claude mcp add demo-server -- uv run server.py. Claude Code bewaart hem in je projectconfig en laadt hem bij het starten. Gebruik je ook hooks om Claude Code te scripten, dan past onze gids over Claude Code-hooks goed bij eigen MCP-tools.
Cursor. Voeg hetzelfde mcpServers-blok toe aan .cursor/mcp.json in de projectroot. De vorm komt overeen met die van Claude Desktop. Voor een echt voorbeeld van een MCP-server die in Claude Code draait, zie hoe we Higgsfield in Claude Code hebben aangesloten.
Gebruik absolute paden in elke config. Relatieve paden zijn de meest voorkomende reden dat een server niet start.
Een MCP-server naar productie deployen (auth en hosting)
Wanneer je server gedeeld moet worden, verplaats hem van stdio naar Streamable HTTP en voeg drie dingen toe: authenticatie, foutafhandeling en een host.
- Authenticatie. Externe MCP-servers moeten OAuth 2.1 gebruiken volgens de MCP-autorisatiespecificatie. Voor interne tools is een bearer-tokencontrole op het HTTP-endpoint het pragmatische minimum. Lever nooit een publieke, niet-geauthenticeerde toolserver uit, want een tool die SQL uitvoert of interne API's raakt is een actief aanvalsoppervlak.
- Foutafhandeling. Omsluit toolbodies met try/except (of try/catch) en geef een getypeerd foutbericht terug in plaats van te throwen. Het model verwerkt "de query is mislukt, hier is waarom" veel beter dan een verbroken verbinding.
- Hosting. Elk platform dat een langlevend Node- of Python-proces draait werkt: een kleine VPS, Fly.io, Railway of een container op je eigen infrastructuur. Houd het proces warm, want koude starts voegen latentie toe aan de eerste tooloproep.
- Concurrency en kosten. Als je tools stroomafwaarts een LLM of betaalde API aanroepen, zet er dan een gateway voor. Ons overzicht van LLM-gatewaytools behandelt rate-limiting en fallback, en context-engineeringtools helpen tooloutput uit het contextvenster van het model te houden.
Voor Python verander je de run-aanroep naar mcp.run(transport="streamable-http"); voor TypeScript verwissel je StdioServerTransport voor de StreamableHTTPServerTransport van de SDK. De tooldefinities veranderen helemaal niet. Dat is het hele punt van de transport-abstractie.
Wat we leerden bij het uitleveren van MCP-servers in productie
We hebben bij Techsy MCP-servers gebouwd voor intern gebruik, en sommige lessen komen pas naar voren wanneer er echt verkeer op komt. Hier is wat we maten en waar we werden gebeten.
De eerste server die we uitleverden was een alleen-lezen Postgres-querytool, gebouwd met FastMCP 2.x op de Python-mcp-SDK 1.x, later herschreven in @modelcontextprotocol/sdk 1.x ter vergelijking. Op een stack uit 2026 (Node 20, Python 3.11) voegden lokale stdio-tooloproepen ongeveer 8 tot 12 ms transport-overhead per oproep toe. Toen we diezelfde server naar Streamable HTTP op een VPS verplaatsten, steeg de kost per oproep naar 40 tot 70 ms, vrijwel volledig netwerk-roundtrip in plaats van protocolkost. De FastMCP-koudestart was ongeveer 300 ms voor het proces, daarom houden we het productieproces warm.
De valkuil die ons ongeveer twee uur kostte: een tool die een rauwe Python-dict teruggaf renderde prima in de Inspector maar kwam afgekapt terug in Claude Desktop. De retourwaarde inpakken als een getypeerde tekststring loste het meteen op. Daarom geeft deze handleiding overal strings en content-tekstblokken terug in plaats van geneste objecten. De andere gewoonte die zich meteen uitbetaalde was elke server door npx @modelcontextprotocol/inspector halen voordat je een clientconfig aanraakt, wat een misvormd invoerschema in de TypeScript-herschrijving aan het licht bracht dat anders stil in Cursor zou zijn mislukt.
| Wat we gebruikten | Versie |
|---|---|
Python-mcp-SDK | 1.x |
| FastMCP | 2.x |
@modelcontextprotocol/sdk (TS) | 1.x |
| Node.js | 20 LTS |
| Inspector | @modelcontextprotocol/inspector (nieuwste) |
Kies je welke tools je überhaupt in servers bouwt, dan is onze lijst van de beste MCP-servers in 2026 een goede ideeënbank.
Hoe Techsy MCP-ontwikkeling aanpakt
Bij Techsy bouwen we MCP-servers als onderdeel van de AI-agentsystemen die we voor klanten uitleveren, door agents via een getypeerde toollaag te verbinden met interne databases, CRM's en API's. Onze aanpak is om smal te beginnen (één goed geteste tool over stdio), het te valideren in de Inspector en het pas te promoveren tot een geauthenticeerde HTTP-dienst wanneer meer dan één agent het nodig heeft. We combineren eigen servers met de Claude Agent SDK wanneer de agentlogica complex wordt.
Dit is de eerlijke versie: de meeste teams overbouwen hun eerste server. Je hebt zelden HTTP, OAuth en een dozijn tools op dag één nodig. Wil je een tweede paar ogen op een MCP-integratie, vraag dan een gratis consult aan en we vertellen je of het een één-tool-stdio-klus is of iets dat echt infrastructuur nodig heeft.
Veelgestelde vragen
Moet ik mijn MCP-server in Python of TypeScript bouwen?
Gebruik de taal waarin je team toch al werkt. Python met FastMCP is de kortste route naar een eerste werkende server, want een decorator verandert een functie in een tool. TypeScript met de officiële SDK is iets uitgebreider maar geeft je uitstekende types en deployt netjes naar Node-hosts. Beide leveren servers die zich voor de client identiek gedragen.
Heb ik een framework als FastMCP nodig om een MCP-server te bouwen?
Nee, maar het helpt. FastMCP zit in de officiële Python-mcp-SDK en verwijdert het meeste protocol-boilerplate. Je kunt de lagere Server-API gebruiken voor fijnmazige controle, maar voor bijna elke server is FastMCP (Python) of McpServer (TypeScript) de juiste tool en veel minder code.
Hoe debug ik een MCP-server die niet werkt?
Haal hem eerst door de MCP Inspector: npx @modelcontextprotocol/inspector gevolgd door je run-commando. De Inspector somt je tools op en laat je ze direct aanroepen, zodat je kunt bevestigen dat de server werkt voordat je de client de schuld geeft. Is de Inspector in orde maar de client niet, controleer dan of je config absolute paden gebruikt en je de client hebt herstart.
Is FastMCP een officieel onderdeel van MCP?
Ja. FastMCP wordt meegeleverd met de officiële Model Context Protocol Python-SDK als hoogniveau-serverinterface. De @mcp.tool()-decorator die je gebruikt is de aanbevolen manier om Python-servers te bouwen, geen externe add-on.
Wat is het verschil tussen een lokale en een externe MCP-server?
Een lokale server draait op je machine over stdio, gestart door de client als subproces, ideaal voor persoonlijke tools en ontwikkeling. Een externe server draait als webdienst over Streamable HTTP en is bereikbaar voor meerdere clients, wat OAuth 2.1-authenticatie vereist. Bouw eerst lokaal, ga pas extern wanneer je deelt.
In welke talen kan ik een MCP-server bouwen?
Het Model Context Protocol heeft officiële SDK's voor Python, TypeScript, Java, Kotlin en C#, met community-SDK's in andere talen. Omdat MCP een wire-protocol is, kan elke taal die JSON-RPC over stdio of HTTP kan lezen en schrijven een server implementeren, maar de officiële SDK's besparen je dat werk.
Werkt een MCP-server met ChatGPT en Gemini, of alleen Claude?
MCP is een open standaard die in het hele agentische AI-ecosysteem wordt overgenomen, waaronder ChatGPT, Gemini, Cursor en VS Code Copilot. Eén server die je bouwt werkt met elke compatibele client. Je schrijft geen aparte integratie per model, wat het hele punt van het protocol is.
Hoe lang duurt het om een werkende MCP-server te bouwen?
Een eerste server met één of twee tools over stdio kost ongeveer 15 minuten zodra je runtime is geïnstalleerd. We maten 14 minuten voor een nieuwkomer op Node 20 en onder de 5 minuten voor een herhaalde bouw. Authenticatie, HTTP-transport en productie-hosting kosten echte tijd, niet de server zelf.
Over de auteur
Mert Batur is medeoprichter van Techsy.io, waar het team AI-agents, automatiseringssystemen en voice/SDR-pipelines voor B2B-klanten uitlevert. Hij schrijft over de LLM-toolingstack die het Techsy-team daadwerkelijk in productie gebruikt. Maak verbinding op LinkedIn.
Mert Batur, medeoprichter, Techsy.io