Model Context Protocol (MCP) from scratch | Connecting your AI Agents with external server and tools
Het Model Context Protocol (MCP) is een open-source standaard die de communicatie formaliseert tussen AI-modellen (zoals LLM-gebaseerde agents) en externe systemen, gegevensbronnen of rekenkundige tools. In plaats van voor elk afzonderlijk subsysteem maatwerkkoppelingen te schrijven, definieert MCP een universeel client-serverprotocol waarmee AI-applicaties dynamisch context kunnen inwinnen en gecontroleerd acties kunnen uitvoeren. Dit hoofdstuk behandelt de theoretische fundamenten, de drielaagse architectuur en een complete end-to-end implementatie in Python met LangChain.
1. Waarom hebben we het Model Context Protocol nodig?
Grote taalmodellen (LLM's) opereren fundamenteel in een geïsoleerde runtime-omgeving. Hun kennis is begrensd door de trainings-cutoff en ze hebben uit zichzelf geen directe toegang tot real-time data, interne bedrijfssystemen of uitvoerbare code.
Vóór de introductie van MCP moesten ontwikkelaars voor elk extern systeem—zoals databases, cloud-opslagdiensten, agendabeheer of rekenmodules—aangepaste integratielagen en API-wrappers bouwen:
- Gefragmenteerde gereedschapsdefinities: Elk framework (LangChain, LlamaIndex, AutoGen) hanteerde eigen specificaties voor gereedschappen (tool calling).
- N-tot-M koppelingsprobleem: Wanneer AI-applicaties moeten communiceren met externe diensten, vereist dit unieke integraties.
- Beveiligings- en onderhoudsrisico's: Rechtstreekse verbindingen tussen LLM-hosts en databases bemoeilijken centrale toegangscontrole en auditing.
MCP lost dit op door een abstractielaag te introduceren. Vergelijkbaar met hoe het Language Server Protocol (LSP) de interactie tussen code-editors en programmeertalen standaardiseerde, standaardiseert MCP de manier waarop AI-applicaties context en gereedschappen uitwisselen met externe services.
2. Wat is het Model Context Protocol (MCP)?
Het Model Context Protocol is een open architectuurstandaard die vastlegt hoe een AI-systeem gegevens en functies van de buitenwereld ontdekt, opvraagt en uitvoert.
Definitie:
Het Model Context Protocol (MCP) is een gestandaardiseerd communicatieprotocol dat de uitwisseling van contextuele gegevens (bronnen), acties (tools) en prompts structureert tussen een AI-host en externe servers via gedefinieerde transportkanalen.
Door MCP te implementeren, kunnen geavanceerde AI-systemen (waaronder Claude, ChatGPT-gebaseerde agents en lokale modellen):
- Context consumeren: Bestanden lezen, databases doorzoeken en actuele statusinformatie opvragen.
- Tools aanroepen: Rekenbewerkingen delegeren, externe API's triggeren of workflows in gang zetten.
- Prompts synchroniseren: Gestandaardiseerde instructiesets en sjablonen inladen vanuit externe domeinen.
3. Praktijkvoorbeelden en Mentale Modellen
Om de noodzaak van een uniforme protocollaag te begrijpen, kunnen we kijken naar alledaagse scenario's waarin AI-agents handelen als persoonlijke assistenten of gespecialiseerde engineers:
Real-Life Analogie: De Persoonlijke Directieassistent (Google Calendar)
Stel dat een AI-agent fungeert als directieassistent. Een gebruiker vraagt: "Ben ik morgenmiddag tussen 14:00 en 15:00 uur beschikbaar voor een afspraak?"
- Zonder MCP: De agent moet expliciet worden geconfigureerd met specifieke Google Calendar REST API-aanroepen, OAuth-tokens en aangepaste foutafhandeling binnen de hostcode.
- Met MCP: De Google Calendar service draait als een MCP-server. De agent vraagt via het protocol het dagschema op, analyseert de teruggemelde tijdvakken en stelt vast of het tijdstip vrij is. Is het bezet, dan stelt de agent autonoom een alternatief beschikbaar tijdstip voor.
Ontwerp-naar-Code Automatisering (Figma)
Een agent wordt verbonden met een Figma MCP-server. De agent inspecteert via gestandaardiseerde protocol-calls de componenthiërarchie en visuele attributen van een vectorontwerp. Vervolgens genereert het AI-systeem direct de bijbehorende React- of Tailwind CSS-code, zonder dat de host-applicatie specifieke kennis hoeft te hebben van de interne Figma REST API's.
Veilige Database-Introspectie
Een agent die via MCP gekoppeld is aan een enterprise database-server kan schema's inspecteren, queries uitvoeren en resultaten aggregeren. De authenticatie en het bereik van de queries worden op het niveau van de MCP-server afgedwongen, waardoor de kern van de AI-toepassing ontkoppeld blijft van de databaseconfiguratie.
4. De Drielaagse MCP-Architectuur
De interactie binnen MCP rust op drie strikt gescheiden lagen:
- MCP-Host (Applicatielaag):
Het bovenliggende AI-systeem (bijvoorbeeld een LangChain-agent, LangGraph-toepassing of Claude Desktop). De host orchestreert het redeneerproces van het model, beslist wanneer een tool nodig is en formuleert het definitieve antwoord aan de eindgebruiker. - MCP-Client (Middlewarelaag):
Een connector die door de host wordt geïnstantieerd. De client beheert de netwerk- of procesverbinding met de server, verzamelt de beschikbare tools en context, en vertaalt deze naar formaten die de host direct kan consumeren. - MCP-Server (Servicelaag):
Een autonoom programma dat specifieke capaciteiten beschikbaar stelt via het protocol. De server definieert gereedschappen, valideert inputparameters, voert de achterliggende bedrijfslogica uit en retourneert het gestructureerde resultaat.
5. De 1-op-1 Verbindingsregel en Multi-Server Orchestratie
Een fundamenteel ontwerpprincipe binnen MCP is de strikte één-op-één relatie tussen een MCP-client en een MCP-server.
- Een MCP-host praat nooit direct met een MCP-server.
- Een individuele MCP-client onderhoudt een exclusieve sessie met exact één MCP-server.
- Indien een AI-applicatie gelijktijdig gebruik wil maken van meerdere domeinen (bijvoorbeeld een rekenservice, een weerdienst en een database), start de host voor elke server een afzonderlijke client-instantie op.
In modulaire softwareontwerpen (zoals demonstraties binnen LangChain) wordt deze orchestratie vaak samengebracht in een containerklasse, zoals de MultiServerMCPClient. Deze abstraheert de onderliggende verzameling van individuele 1:1-verbindingen, zodat de agent eenvoudig over alle geïntegreerde tools kan beschikken.
6. Transportmechanismen: Stdio vs. HTTP / SSE
De communicatie tussen een MCP-client en MCP-server vindt plaats over een transportkanaal. Het protocol specificeert standaard twee methoden:
In lokale ontwikkelscenario's geniet stdio de voorkeur wegens het minimale configuratiebeslag: de host start de Python-servers aan als deelprocessen en wisselt JSON-RPC-berichten uit via standaard streams.
7. Implementatie van MCP-Servers in Python
Hieronder implementeren we twee autonome MCP-servers met behulp van de officiële MCP-bibliotheek: een wiskundige rekenmodule (maths_server.py) en een locatiespecifieke weerservice (weather_server.py).
Server 1: De Rekenmodule (maths_server.py)
Deze server exposeert twee functies (add en multiply) via de @mcp.tool() decorator:
# maths_server.py
from mcp.server.fastmcp import FastMCP
# Initialiseer de FastMCP serverinstantie met een unieke naam
mcp = FastMCP("Math Server")
@mcp.tool()
def add(a: float, b: float) -> float:
"""Tel twee getallen bij elkaar op."""
return a + b
@mcp.tool()
def multiply(a: float, b: float) -> float:
"""Vermenigvuldig twee getallen met elkaar."""
return a * b
if __name__ == "__main__":
# Start de server over het standaard input/output transportkanaal
mcp.run(transport="stdio")
Server 2: De Weerservice (weather_server.py)
Deze server levert real-time contextuele informatie over weersomstandigheden:
# weather_server.py
from mcp.server.fastmcp import FastMCP
# Initialiseer de Weer MCP-server
mcp = FastMCP("Weather Server")
@mcp.tool()
def get_weather_status(location: str) -> str:
"""Haal de huidige weersgesteldheid op voor een specifieke locatie."""
# Gesimuleerde implementatie; in productie zou hier een live API worden aangeroepen
return f"Het regent momenteel in {location}."
if __name__ == "__main__":
# Start over stdio voor lokale integratie
mcp.run(transport="stdio")
8. Implementatie van de MCP-Host met LangChain
De hostlaag configureert de clientverbindingen, laadt de tools in, bindt deze aan een taalmodel (zoals OpenAI's GPT-4) en handelt de redeneercyclus af.
# agent_host.py
import asyncio
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
load_dotenv()
async def main():
# 1. Definieer de configuratie voor de MCP-servers
# MultiServerMCPClient beheert intern de afzonderlijke 1:1 clientverbindingen
server_config = {
"math": {
"command": "python",
"args": ["maths_server.py"],
"transport": "stdio",
},
"weather": {
"command": "python",
"args": ["weather_server.py"],
"transport": "stdio",
}
}
# 2. Initialiseer de MultiServer-client
async with MultiServerMCPClient(server_config) as client:
# Haal alle gereedschappen op van alle aangesloten servers
tools = client.get_tools()
# 3. Initialiseer het taalmodel
model = ChatOpenAI(model="gpt-4o", temperature=0)
# 4. Bouw de ReAct-agent met behulp van LangGraph prebuilt
agent = create_react_agent(model, tools)
# Scenario A: Rekenbewerking over meerdere stappen
query_math = "Wat is 3 + 5 keer 12?"
response_math = await agent.ainvoke({"messages": [("user", query_math)]})
print("=== Wiskunde Query Uitvoer ===")
print(response_math["messages"][-1].content)
# Scenario B: Context ophalen uit externe service
query_weather = "Hoe is het weer in San Francisco?"
response_weather = await agent.ainvoke({"messages": [("user", query_weather)]})
print("\n=== Weer Query Uitvoer ===")
print(response_weather["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(main())
9. End-to-End Workflow: Van Gebruikersinvoer tot Uitvoering
Wanneer de agent de wiskundige query "Wat is 3 + 5 keer 12?" ontvangt, voert het systeem een samengestelde tool-executielus uit:
De agent begrijpt de volgorde van bewerkingen (eerst de optelling van , vervolgens de vermenigvuldiging met ) en koppelt de output van de eerste MCP-aanroep als input aan de tweede aanroep.
10. Dynamische Serverinteractie en Runtime Wijzigingen
Een belangrijk architectonisch voordeel van MCP is de ontkoppeling tussen de model-inferentie en de server-logica. Wijzigingen aan de serverzijde vereisen geen herstart of code-aanpassing van de agent.
Stel dat we in weather_server.py de hardgecodeerde toestand aanpassen van neerslag naar zonneschijn:
# Gewijzigde tool binnen weather_server.py
@mcp.tool()
def get_weather_status(location: str) -> str:
"""Haal de huidige weersgesteldheid op voor een specifieke locatie."""
return f"Het is momenteel erg zonnig in {location}."
Wanneer de agent nu exact dezelfde vraag stelt ("Hoe is het weer in San Francisco?"), verandert het gedrag direct:
Vraag: "Hoe is het weer in San Francisco?"
Tool Call: get_weather_status(location="San Francisco")
Server Response: "Het is momenteel erg zonnig in San Francisco."
Agent Output: "Het is momenteel erg zonnig in San Francisco. Zorg dat je geniet van de zon of laat het weten als je een uitgebreide voorspelling wilt!"
De agent past zijn redenering en adviezen (van paraplu naar zonnebescherming) naadloos aan op basis van de gewijzigde context die via de MCP-client binnenkomt.
11. Valkuilen, Foutafhandeling en Productie-Aandachtspunten
Bij het uitrollen van MCP-systemen in productie moeten engineers rekening houden met specifieke storingsfactoren:
- Zombiekinderprocessen bij
stdio: Wanneer de host abrupt crasht, kunnen lokale Python MCP-processen op de achtergrond blijven draaien. Zorg voor degelijk procesbeheer en signaalafhandeling (SIGTERM/SIGINT). - Schema-inconsistenties: De LLM verwacht strikte JSON-schema's voor tool-aanroepen. Als typen (zoals
floatvs.int) verkeerd worden geretourneerd of verwerkt, kan de agent vastlopen in foutlussen. Pydantic-validatie op serverniveau is essentieel. - Latentie bij ketenaanroepen: Samengestelde berekeningen vereisen meerdere roundtrips tussen host, client en server. Voor interactieve applicaties kan dit leiden tot een merkbare vertraging.
- Beveiligingsgrenzen: Geef MCP-servers via
stdioalleen toegang tot de minimaal noodzakelijke systeembronnen (principe van minimale bevoegdheden). Externe HTTP/SSE-servers moeten altijd worden beveiligd met encryptie en authenticatietokens.
12. Samenvatting van de Architectuurcomponenten
Summary and Key Takeaways
- Gestandaardiseerde Integratie: Het Model Context Protocol (MCP) fungeert als een universele open standaard waarmee AI-agents kunnen communiceren met externe databronnen, rekenmodules en API's, waardoor point-to-point maatwerkintegraties overbodig worden.
- Drielaags Model: De MCP-architectuur bestaat uit de Host (de overkoepelende AI-applicatie), de Client (de verbindende middleware) en de Server (de aanbieder van context en gereedschappen).
- Strikte 1-op-1 Relatie: Een MCP-client onderhoudt altijd een exclusieve verbinding met precies één MCP-server. Multi-server functionaliteit wordt gerealiseerd door meerdere clients tegelijk te orchestreren binnen de host.
- Geen Directe Koppeling: De MCP-host communiceert nooit direct met servers; alle data-uitwisseling verloopt gecontroleerd via de tussenliggende clientlaag.
- Flexibele Transportlagen: Lokale integraties maken hoofdzakelijk gebruik van snelle
stdiointer-proceskanalen, terwijl gedistribueerde systemen leunen op HTTP in combinatie met Server-Sent Events (SSE). - Dynamische Contextupgrades: Wijzigingen in de data of bedrijfslogica van een MCP-server worden direct weerspiegeld in het redeneerproces van het model, zonder dat de host-applicatie opnieuw hoeft te worden getraind of gehercompileerd.
- Sequentiële Tool-Executie: Complexe vraagstukken kunnen door de agent worden opgesplitst in meerdere afhankelijke MCP-tool-aanroepen, waarbij tussenresultaten van de ene call als parameters dienen voor de volgende call.