Wat is het Model Context Protocol?
Het Model Context Protocol (MCP) is Anthropic’s open standaard voor het blootstellen van tools, data en prompt-templates aan AI-modellen. Zie het als USB voor AI: elke MCP-server kan worden ingeplugd in elke MCP-client (Claude Desktop, Cursor, Continue, je eigen Delphi-app, OpenAI’s clients), en het model ontdekt direct welke tools beschikbaar zijn en hoe ze aan te roepen.
Voor MCP betekende elke AI-integratie het bedraden van tool-definities, JSON-schema’s en call-dispatchers in elke individuele app. MCP brengt dat samen in een enkel protocol: schrijf de server een keer, elk model kan hem gebruiken. Voor Delphi-shops die al een stapel business-API’s hebben — ERP-queries, CRM-lookups, file-generatoren, billing-functies — is MCP de goedkoopste route om die API’s AI-toegankelijk te maken.
Deze tutorial doorloopt het bouwen van een MCP-server in Delphi met de TsgcAI_MCP_Server-component, het blootstellen van een werkende get_weather-tool, en het verbinden met Claude Desktop via zowel stdio- als HTTP-transporten.
Een stukje geschiedenis plaatst MCP in context. Anthropic publiceerde de spec eind 2024 als antwoord op de wildgroei van incompatibele tool-calling-formaten — OpenAI’s function-calling JSON, Google’s Gemini grounding tools, elke leveranciers eigen schema. Tegen de tijd dat je dit leest, wordt MCP-ondersteuning geleverd in Claude Desktop, Cursor, Continue, Zed en de meeste moderne AI-IDE’s; OpenAI kondigde compatibiliteit aan begin 2026. Met andere woorden: een MCP-server bouwen vandaag is een eenmalige investering die uitbetaalt over elke client die je klanten kunnen gebruiken, vandaag en morgen.
MCP-bouwstenen
Een MCP-server kan drie soorten capabilities blootstellen:
| Tools Aanroepbare functies met typed inputs. Het model beslist wanneer ze in te roepen. Voorbeeld: get_weather(city), create_invoice(customer, lines). |
Resources Read-only data die het model kan ophalen. Elke resource heeft een URI. Voorbeeld: file:///docs/handbook.md, db://customers/12345. |
Prompts Herbruikbare prompt-templates die de gebruiker (niet het model) selecteert. Voorbeeld: een “Vertaal naar formeel Spaans”- of “Vat vergadernotities samen”-template. |
Het protocol gebruikt JSON-RPC 2.0 over een van twee transporten: stdio (de server is een childproces; berichten lopen via stdin/stdout) of HTTP met Server-Sent Events voor de server-naar-client-stream. Stdio is de standaard voor desktop-integraties zoals Claude Desktop; HTTP is de juiste keuze wanneer de server op een andere machine draait of meerdere clients bedient.
De component verbergt beide transporten achter een enkele API. Je schrijft je tool-handler een keer, dan kies je het transport bij opstart. Dezelfde code draait als Claude Desktop-helper, een netwerk-bereikbare HTTP-service, of beide tegelijkertijd binnen een proces. We hebben shops die 30+ MCP-servers op een box draaien, gemultiplexed over verschillende poorten en een of twee stdio-binaries, allemaal dezelfde Delphi-codebase serverend.
Project-setup
Voeg sgcAI_MCP_Server toe aan je uses-clausule, plaats een TsgcAI_MCP_Server op het formulier (of maak hem in code voor een console-app), hang de events aan en start hem. De component doet de JSON-RPC-framing, message-routing en capability-advertisement voor je.
uses sgcAI_MCP_Server, sgcAI_MCP_Classes; procedure TForm1.FormCreate(Sender: TObject); begin oMCP := TsgcAI_MCP_Server.Create(Self); oMCP.ServerInfo.Name := 'weather-mcp'; oMCP.ServerInfo.Version := '1.0.0'; // Wire handlers oMCP.OnListTools := DoListTools; oMCP.OnCallTool := DoCallTool; // Stdio transport for Claude Desktop integration oMCP.Transport := mtStdio; oMCP.Active := True; end;
Een tool implementeren: get_weather
Een tool heeft twee handlers nodig. OnListTools vertelt de client welke tools bestaan en welke argumenten ze accepteren. OnCallTool voert de aanroep daadwerkelijk uit. Beide handlers zijn gewone Delphi-events — geen handmatige JSON-constructie.
procedure TForm1.DoListTools(Sender: TObject;
const aTools: TsgcAI_MCP_Tools);
var
oTool: TsgcAI_MCP_Tool;
begin
oTool := aTools.Add;
oTool.Name := 'get_weather';
oTool.Description := 'Return the current weather for a city.';
oTool.InputSchema :=
'{"type":"object",' +
'"properties":{' +
'"city":{"type":"string","description":"City name, e.g. Madrid"},' +
'"units":{"type":"string","enum":["metric","imperial"],"default":"metric"}' +
'},' +
'"required":["city"]}';
end;
procedure TForm1.DoCallTool(Sender: TObject;
const aRequest : TsgcAI_MCP_ToolCall;
const aResult : TsgcAI_MCP_ToolResult);
var
vCity, vUnits, vReport: string;
begin
if aRequest.Name = 'get_weather' then
begin
vCity := aRequest.Arguments.S['city'];
vUnits := aRequest.Arguments.S['units'];
if vUnits = '' then vUnits := 'metric';
// Call your own weather backend
vReport := MyWeatherService.Fetch(vCity, vUnits);
aResult.AddText(vReport);
end
else
aResult.Error('Unknown tool: ' + aRequest.Name);
end;
Dat is de volledige implementatie. De component zorgt voor input-validatie tegen het schema, error-formattering en de onderliggende JSON-RPC-envelop. Jij richt je op de businesslogica.
Enkele principes voor het ontwerpen van goede tools, de harde weg geleerd:
- Een werkwoord per tool. “get_weather” is beter dan “weather_operations” met een sub-action-parameter. Het model kiest de juiste tool sneller wanneer elke naam exact een uitkomst beschrijft.
- Wees meedogenloos met beschrijvingen. De schema-beschrijving is je enige kans om het model te leren wat de tool wel en niet doet. Spel edge cases, eenheden, formats en voorwaarden uit.
- Default alles wat je kunt. Optionele parameters met zinnige defaults laten het model je tool succesvol aanroepen, ook wanneer hij maar de helft van de context kent.
- Geef kleine, gerichte payloads terug. Een 50-regel-tekstantwoord is prima; een 5.000-regel-dump blaast het context-venster en de factuur op. Vat samen aan de server-kant.
- Faal expliciet. Geef een gestructureerd foutbericht terug (“Stad niet herkend. Bedoelde je Madrid of Madras?”) in plaats van stilzwijgend lege resultaten.
Resources blootstellen
Tools zijn voor acties; resources zijn voor data die het model kan lezen. Een resource-handler geeft de content terug voor een gegeven URI. Een documentatieserver zou elk Markdown-bestand onder docs/ als resource kunnen blootstellen.
oMCP.OnListResources := DoListResources;
oMCP.OnReadResource := DoReadResource;
procedure TForm1.DoListResources(Sender: TObject;
const aResources: TsgcAI_MCP_Resources);
var
vFiles: TStringDynArray;
i : Integer;
oRes : TsgcAI_MCP_Resource;
begin
vFiles := TDirectory.GetFiles('C:\docs', '*.md');
for i := 0 to High(vFiles) do
begin
oRes := aResources.Add;
oRes.URI := 'file:///' + StringReplace(vFiles[i], '\', '/', [rfReplaceAll]);
oRes.Name := ExtractFileName(vFiles[i]);
oRes.MimeType := 'text/markdown';
oRes.Description := 'Documentation page';
end;
end;
procedure TForm1.DoReadResource(Sender: TObject;
const aURI: string; const aResult: TsgcAI_MCP_ResourceResult);
var
vPath: string;
begin
vPath := StringReplace(Copy(aURI, 9, MaxInt), '/', '\', [rfReplaceAll]);
if FileExists(vPath) then
aResult.AddText(TFile.ReadAllText(vPath))
else
aResult.Error('Resource not found');
end;
Stdio vs HTTP-transport
Kies het transport op basis van waar de server draait en wie hem gebruikt.
| Transport | Gebruik | Voordelen | Nadelen |
| Stdio | Lokale desktop-tools (Claude Desktop, Cursor) | Geen configuratie, geen poorten, OS regelt proces-lifecycle | Een client per proces, geen externe toegang |
| HTTP / SSE | Gedeelde bedrijfsservers, webclients, multi-tenant | Veel clients, netwerk-bereikbaar, TLS, auth | Vereist hosting, poortbeheer, auth-ontwerp |
Transport wisselen is een regel:
// Stdio (default for desktop) oMCP.Transport := mtStdio; // HTTP listener on port 8080 oMCP.Transport := mtHTTP; oMCP.HTTPOptions.Host := '0.0.0.0'; oMCP.HTTPOptions.Port := 8080; oMCP.HTTPOptions.TLS.Enabled := True; oMCP.HTTPOptions.TLS.CertFile := 'cert.pem'; oMCP.HTTPOptions.TLS.KeyFile := 'key.pem'; oMCP.Active := True;
Verbinden vanuit Claude Desktop
Voor stdio bewerk je claude_desktop_config.json en voeg je een entry toe die naar je gecompileerde .exe wijst. Claude Desktop spawnt het proces op afroep.
{
"mcpServers": {
"weather": {
"command": "C:\\Tools\\weather-mcp.exe",
"args": []
}
}
}
Herstart Claude Desktop en je ziet een klein tools-icoon in het prompt-gebied. Vraag “Wat is het weer in Tokio?” en Claude zal je Delphi-tool aanroepen.
Voor HTTP wijs je elke MCP-capable client naar https://your-host:8080/mcp. Dezelfde Delphi-server bedient probleemloos een Claude Desktop-instance, een Cursor-sessie en een custom Delphi MCP-client tegelijkertijd.
Prompts: de onderbenutte derde capability
Tools en resources krijgen alle aandacht; prompts zijn het stille werkpaard. Een MCP-prompt is een herbruikbaar template — “vat deze vergadering samen”, “extraheer actiepunten”, “vertaal naar formeel Spaans” — dat de gebruiker vanuit een UI-menu in zijn MCP-client invoegt. Het model voert die prompt vervolgens uit tegen de context die de gebruiker levert.
Voor interne tooling is dit goud. Je supportteam krijgt een gecureerde lijst bedrijfsgezegende prompts binnen Claude Desktop. Je salesteam krijgt een “stel een follow-up e-mail op”-prompt die je tone of voice al kent. Geen van hen hoeft prompt engineering te leren — ze kiezen gewoon het template.
oMCP.OnListPrompts := DoListPrompts;
oMCP.OnGetPrompt := DoGetPrompt;
procedure TForm1.DoListPrompts(Sender: TObject;
const aPrompts: TsgcAI_MCP_Prompts);
var
oPrompt: TsgcAI_MCP_Prompt;
begin
oPrompt := aPrompts.Add;
oPrompt.Name := 'summarise_meeting';
oPrompt.Description := 'Turn a meeting transcript into bullet decisions and actions.';
oPrompt.AddArgument('transcript', 'Plain-text transcript', True);
end;
procedure TForm1.DoGetPrompt(Sender: TObject;
const aRequest: TsgcAI_MCP_PromptRequest;
const aResult : TsgcAI_MCP_PromptResult);
begin
if aRequest.Name = 'summarise_meeting' then
aResult.AddMessage('user',
'You are a meeting note taker. Read the transcript and produce: ' +
'(1) a 3-sentence summary, (2) decisions taken, (3) action items ' +
'with owners and due dates.' + sLineBreak + sLineBreak +
aRequest.Arguments.S['transcript']);
end;
Productie-overwegingen
Een paar dingen om voor te budgetteren voordat je een MCP-server in productie brengt:
- Authenticatie: stdio erft OS-niveau-vertrouwen, maar HTTP heeft bearer-tokens of mTLS nodig. Gebruik
OnHTTPAuthenticateom te valideren. - Rate limiting: een spraakzaam model kan tool-aanroepen in tight loops afvuren. Combineer de MCP-server met
TsgcWebSocketHTTPServer_RateLimiterof je eigen quota-logica. - Logging: verbind
OnLogom elke tool-call vast te leggen. Dit heb je nodig wanneer een gebruiker meldt “Claude deed iets raars”. - Schema-discipline: hoe accurater je JSON-schema’s (beschrijvingen, enums, voorbeelden), hoe beter het model de juiste tool met de juiste argumenten kiest.
- Idempotentie: tools kunnen tweemaal worden aangeroepen als het model retried. Markeer schrijf-operaties idempotent of voeg een transaction-id-parameter toe.
Debug-tips
MCP draait onzichtbaar binnen de AI-client, wat debuggen lastig maakt de eerste keer dat er iets misgaat. Drie gewoonten besparen je uren:
- Stderr is je console. In stdio-modus hoort stdout bij JSON-RPC. Alles wat je daar naartoe schrijft, breekt het protocol. Log naar stderr (dat Claude Desktop opvangt in zijn logbestanden) of naar een side-logbestand met een process-id-suffix.
- Gebruik de MCP Inspector. Anthropic levert een gratis tool (
npx @modelcontextprotocol/inspector) waarmee je een UI op je server kunt richten, elke tool kunt klikken, de ruwe request/response kunt zien, en schema’s kunt valideren zonder enige AI-client te betrekken. - Voeg een “diagnostic”-tool toe. Een eenvoudige
server_info-tool die de builddatum, host en versie teruggeeft, maakt het triviaal om in de AI-client te bevestigen dat je met de juiste server praat. We voegen dit toe aan elke productie-MCP-server.
Afronding
MCP verandert een interne Delphi-API in iets dat elke moderne AI-client kan gebruiken, zonder per-client-bedrading. De TsgcAI_MCP_Server-component handelt de JSON-RPC-framing, transport en capability-advertisement af, en laat jou de daadwerkelijke tool-body schrijven. Begin met een read-only tool, kijk hoe het model hem gebruikt, breid dan uit naar writes, resources en prompts.
Onze grootste les uit het intern uitrollen van MCP: de waarde is niet “Claude kan nu onze API’s gebruiken”. De waarde is “iedereen in het bedrijf kan onze API’s gebruiken via natuurlijke taal, zonder de API te leren”. Dat verandert wie wat kan doen, en daar komt de werkelijke productiviteitswinst vandaan.
Wil je de bijbehorende client? Zie TsgcAI_MCP_Client voor het bouwen van Delphi-apps die elke MCP-server consumeren. En als de AI-componenten nieuw voor je zijn, loopt de Aan de slag-hub je in vijf minuten door de installatie.