Zelf een MCP server bouwen: complete gids (2026)
Een MCP server is een programma dat via het Model Context Protocol tools, data en prompts aanbiedt aan AI-assistenten zoals Claude. Zelf bouwen kost in 2026 nog maar circa tien regels Python dankzij de officiële SDK's. Deze gids doorloopt SDK-keuze, een minimaal voorbeeld, koppelen aan Claude, testen met de MCP Inspector en publiceren in de officiële registry.
Wanneer bouw je zelf en wanneer pak je een bestaande server?
Zelf bouwen is zelden de eerste stap. Voor gangbare systemen — GitHub, Jira, boekhoudpakketten, CRM's — bestaan al kant-en-klare MCP servers; ons overzicht van MCP servers per sector is dan het startpunt. Zelf bouwen loont in drie situaties: je wilt een intern systeem ontsluiten waarvoor geen server bestaat (een legacy-API, een eigen database), je wilt een workflow op maat die bestaande servers niet bieden, of je wilt als leverancier je product beschikbaar maken voor AI-clients. Twijfel je over de afweging, bedenk dan dat een eigen server ook onderhoud betekent: het protocol evolueert (er komt eind juli 2026 een breaking spec-release aan, zie verderop) en je bent zelf verantwoordelijk voor beveiliging — lees daarvoor ook onze pagina over MCP-veiligheid. Hoe het protocol zelf in elkaar zit, staat op hoe werkt MCP.
Welke SDK kies je?
Sinds 23 februari 2026 hanteert het MCP-project een officieel SDK-tiersysteem met geautomatiseerde conformance-tests, zo blijkt uit de officiële MCP-documentatie op modelcontextprotocol.io. Tier 1-SDK's halen een 100% score op de conformance-tests, krijgen nieuwe protocolfeatures vóór een nieuwe spec-release en garanderen issue-triage binnen twee werkdagen en P0-bugfixes binnen zeven dagen. Er is ook degradatie: een Tier 1-SDK die vier weken lang een conformance-test laat falen, zakt naar Tier 2. Voor zakelijke bouwers is het advies simpel: kies een Tier 1-taal, tenzij je een zwaarwegende reden hebt.
| Taal | Tier | Opmerking |
|---|---|---|
| TypeScript | Tier 1 | De-facto standaard voor npm-servers |
| Python | Tier 1 | Package mcp op PyPI, met ingebouwde FastMCP-API |
| C# | Tier 1 | Onderhouden met Microsoft, integreert met ASP.NET Core |
| Go | Tier 1 | Onderhouden met Google |
| Java, Rust | Tier 2 | ≥80% conformance, nieuwe features binnen 6 maanden |
| Swift, Ruby, PHP, Kotlin | Tier 3 | Experimenteel, geen garanties |
Voor Python bestaan overigens twee smaken FastMCP, een bekende bron van verwarring. De officiële Python SDK bevat de in 2024 gemergde FastMCP 1.0-API (from mcp.server.fastmcp import FastMCP). Daarnaast bestaat het zelfstandige FastMCP-project (package fastmcp), dat volgens de eigen documentatie op gofastmcp.com is doorontwikkeld met auth-providers, OpenAPI-generatie en deployment-tooling. Voor je eerste server volstaat de ingebouwde variant uit de officiële SDK — die gebruiken we hieronder.
Hoe bouw je een minimale MCP server in Python?
Het onderstaande stappenplan volgt de officiële quickstart van modelcontextprotocol.io: een weerserver met twee tools. Vereisten: Python 3.10 of hoger en de MCP SDK vanaf 1.2.0. Het kernidee: je schrijft een gewone Python-functie met type hints en een docstring, en de SDK genereert daaruit automatisch het JSON Schema dat de AI-client nodig heeft.
- Project opzetten met uv.
curl -LsSf https://astral.sh/uv/install.sh | sh # install uv uv init weather && cd weather uv venv && source .venv/bin/activate uv add "mcp[cli]" httpx touch weather.py - Tools definiëren in
weather.py.from typing import Any import httpx from mcp.server.fastmcp import FastMCP mcp = FastMCP("weather") NWS_API_BASE = "https://api.weather.gov" @mcp.tool() async def get_alerts(state: str) -> str: """Get weather alerts for a US state. Args: state: Two-letter US state code (e.g. CA, NY) """ ... @mcp.tool() async def get_forecast(latitude: float, longitude: float) -> str: """Get weather forecast for a location. ...""" ... def main(): mcp.run(transport="stdio") if __name__ == "__main__": main() - Draaien:
uv run weather.py. De server wacht nu op een client via stdio.
Naast tools kent MCP nog twee primitieven: resources (read-only data, vergelijkbaar met bestanden) en prompts (herbruikbare prompt-templates). Tools zijn functies die het model — met goedkeuring van de gebruiker — kan aanroepen, en vormen voor vrijwel elke server het startpunt. Zie de begrippenlijst voor alle termen.
Hoe koppel je de server aan Claude Desktop en Claude Code?
Voor Claude Desktop bewerk je claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %AppData%\Claude\):
{
"mcpServers": {
"weather": {
"command": "uv",
"args": ["--directory", "/ABSOLUTE/PATH/TO/weather", "run", "weather.py"]
}
}
}
Absolute paden, altijd
De officiële docs zijn er expliciet over: gebruik het absolute pad naar je project, en zo nodig ook naar de uv-executable zelf (which uv). Op Windows: dubbele backslashes. En herstart Claude Desktop na elke configwijziging — anders verschijnt de server niet. Claude Desktop is niet beschikbaar op Linux.
In Claude Code (CLI) gaat het via claude mcp add:
# lokale stdio-server
claude mcp add --transport stdio --env AIRTABLE_API_KEY=KEY airtable -- npx -y airtable-mcp-server
# remote HTTP-server
claude mcp add --transport http secure-api https://api.example.com/mcp --header "Authorization: Bearer token"
Met --scope project komt de configuratie in een gedeelde .mcp.json in je repository, zodat het hele team dezelfde servers gebruikt via version control. De opties staan vóór de servernaam; -- scheidt Claude-flags van het servercommando. Status controleren doe je in Claude Code met /mcp.
Hoe test en debug je een MCP server?
Test nooit rechtstreeks via Claude Desktop — elke wijziging vergt daar een herstart, en dat maakt debuggen tergend traag. De standaard eerste stap is de officiële MCP Inspector: npx @modelcontextprotocol/inspector uv run weather.py start je server als childprocess en opent een web-UI op localhost:6274. Daarin kun je tools aanroepen met willekeurige argumenten, resources en prompts bekijken, en de ruwe JSON-RPC-berichten live volgen. Werkt het in de Inspector, koppel dan pas aan een echte client. Komt je server in Claude Desktop toch niet op, kijk dan in de logs onder ~/Library/Logs/Claude/mcp*.log (macOS); in Claude Code helpt claude --debug.
Beginnersfout #1: loggen naar stdout
Bij een stdio-server vervoert stdout de JSON-RPC-stream. Eén verdwaalde print() of console.log() corrumpeert die stream en de server breekt geruisloos — volgens de officiële MCP-docs dé nummer één oorzaak van "mijn server start niet". Log naar stderr (print(..., file=sys.stderr), console.error()) of naar een bestand. Alleen bij HTTP-servers is stdout-logging onschuldig.
Kies je stdio of Streamable HTTP?
De vuistregel: stdio voor lokaal en persoonlijk gebruik, Streamable HTTP zodra iets remote, gedeeld of gehost moet zijn. Bij stdio start de client je server als childprocess en loopt JSON-RPC over stdin/stdout — geen netwerk-overhead, maar single-client. Streamable HTTP werkt via één HTTP-endpoint (meestal /mcp) waar de client JSON-RPC naartoe POST en de server antwoorden kan streamen; dit is dé transport voor cloud- en multi-clientservers in 2026. Het oudere HTTP+SSE-model met twee endpoints is al sinds spec 2025-03-26 deprecated — bouw er niets nieuws op. Ter illustratie: Atlassian houdt zijn oude /v1/sse-endpoint slechts tot 30 juni 2026 in de lucht, meldt het Atlassian-communityforum.
Wat moet je weten over OAuth 2.1 voor remote servers?
Zodra je server remote draait, schrijft de MCP-specificatie OAuth 2.1 voor, met de MCP server als resource server. Verplicht: de Authorization Code-flow met PKCE, Protected Resource Metadata (RFC 9728) zodat clients ontdekken welke authorization servers je vertrouwt, en Resource Indicators (RFC 8707) die tokens aan jouw specifieke server binden. Dynamic Client Registration is sinds spec 2025-11-25 deprecated ten gunste van Client ID Metadata Documents. Het goede nieuws: frameworks en gateways nemen dit steeds vaker uit handen — het standalone FastMCP 3 heeft ingebouwde auth-providers en hosted gateways handelen OAuth-terminatie af. Voor de bredere beveiligingscontext, inclusief prompt injection en toegangsbeheer, zie onze veiligheidspagina en MCP en wetgeving.
Hoe publiceer je in de officiële MCP-registry?
De officiële MCP Registry (registry.modelcontextprotocol.io, sinds september 2025 in preview) is het canonieke publicatiekanaal. Belangrijk om te begrijpen: de registry host metadata, niet je code. Je publiceert een server.json die verwijst naar je package op npm, PyPI of Docker Hub (of naar een remote server-URL). Namespaces werken via reverse-DNS gekoppeld aan geverifieerde identiteit: io.github.gebruikersnaam/server via GitHub-OAuth, of com.jouwbedrijf/server via een DNS- of HTTP-challenge op je eigen domein. Alleen de geverifieerde eigenaar kan onder die namespace publiceren.
- Package je server: npm (draaibaar via
npx), PyPI (viauvx) of Docker-image. - Maak een
server.jsonmet naam, beschrijving, repository en packages. - Verifieer je namespace:
mcp-publisher login githubof een DNS TXT-/HTTP-challenge voor je eigen domein. - Publiceer met
mcp-publisher publish. - Aggregators en marketplaces pikken je server automatisch op via de REST API van de registry.
Let op: de registry is nog "preview" (breaking changes en data-resets zijn mogelijk), ondersteunt geen private servers en delegeert security-scanning aan npm/PyPI/Docker Hub en aan aggregators.
Hoe ontwerp je goede tools?
Anthropic's engineeringpost "Writing effective tools for agents" bevat de belangrijkste ontwerplessen. Ten eerste: een paar goede tools verslaan veel dunne wrappers — spiegel je REST-API niet één-op-één, maar consolideer workflows (één schedule_event-tool in plaats van list_users + list_events + create_event). Ten tweede: schrijf tool-descriptions "zoals je een nieuwe collega zou inwerken" — het model kiest tools op basis van de beschrijving, niet de code; een vage beschrijving betekent een tool die nooit wordt gebruikt. Verder: ondubbelzinnige parameternamen (user_id, niet user), namespacing per dienst (jira_search), paginering en truncatie met verstandige defaults zodat je het contextvenster niet opblaast, en foutmeldingen die de agent vertellen wat er te repareren valt in plaats van kale foutcodes. En: evalueer met realistische taken en lees agent-transcripten terug om ruwe randen te vinden. Meer praktijkadvies staat bij onze tips en tricks.
Let op: spec 2026-07-28 en SDK v2-beta's
Op 28 juli 2026 verschijnt een breaking spec-release die het protocol stateless maakt (geen initialize-handshake en Mcp-Session-Id meer) en Roots, Sampling en Logging deprecatet met een venster van twaalf maanden, aldus de officiële MCP-blog. De v2-beta's zijn al uit: Python mcp[cli]==2.0.0b1 (waarin FastMCP hernoemd wordt naar MCPServer), TypeScript @modelcontextprotocol/server@beta, Go v1.7.0-pre.1 en C# 2.0.0-preview.1. Advies: bouw vandaag op de stabiele v1-SDK's, maar ontwerp geen tools die leunen op protocol-sessies of de te deprecaten features.
Verder lezen
MCP servers per sector
Eerst kijken of er al een kant-en-klare server bestaat voor jouw use-case.
MCP-veiligheid
Prompt injection, toegangsbeheer en wat je moet regelen vóór productie.
Betrouwbare bronnen
De officiële documentatie, registry en specs op een rij.
Veelgestelde vragen
Welke programmeertaal is het beste voor een MCP server?
Hoeveel code kost een minimale MCP server?
@mcp.tool() boven en start met mcp.run(). De SDK genereert het JSON Schema automatisch.Hoe koppel ik mijn MCP server aan Claude Desktop?
claude_desktop_config.json onder mcpServers, met een absoluut pad naar je project. Herstart daarna Claude Desktop. In Claude Code gebruik je claude mcp add op de command line.Waarom start mijn MCP server niet in Claude Desktop?
print() corrumpeert de stream. Log naar stderr of een bestand. Controleer daarnaast of je absolute paden gebruikt in de config.Wat is het verschil tussen stdio en Streamable HTTP?
Hoe test ik een MCP server zonder Claude?
npx @modelcontextprotocol/inspector uv run server.py opent een web-UI op localhost:6274 waarin je tools aanroept met eigen argumenten en de ruwe JSON-RPC-berichten meekijkt. Test altijd eerst hier, daarna pas in Claude.Hoe publiceer ik mijn MCP server in de officiële registry?
server.json, verifieer je namespace (GitHub-login of DNS-challenge voor reverse-DNS-namen zoals com.example/server) en publiceer met de mcp-publisher CLI. De registry host metadata, niet je code.Moet ik nu al bouwen op de nieuwe MCP-spec van juli 2026?
Laatst bijgewerkt: