Einen Model-Context-Protocol-(MCP-)Server in Delphi bauen

· Components

Was ist das Model Context Protocol?

Das Model Context Protocol (MCP) ist Anthropics offener Standard, um Tools, Daten und Prompt-Vorlagen für KI-Modelle bereitzustellen. Stell es dir als USB für KI vor: Jeder MCP-Server kann in jeden MCP-Client eingestöpselt werden (Claude Desktop, Cursor, Continue, deine eigene Delphi-App, OpenAIs Clients), und das Modell entdeckt sofort, welche Tools verfügbar sind und wie es sie aufruft.

Vor MCP bedeutete jede KI-Integration, Tool-Definitionen, JSON-Schemas und Call-Dispatcher in jede einzelne App zu verdrahten. MCP komprimiert das in ein einziges Protokoll: Server einmal schreiben, jedes Modell kann es nutzen. Für Delphi-Häuser, die bereits einen Stapel Business-APIs haben — ERP-Abfragen, CRM-Lookups, Datei-Generatoren, Abrechnungs-Funktionen — ist MCP der günstigste Weg, diese APIs KI-zugänglich zu machen.

Dieses Tutorial geht den Bau eines MCP-Servers in Delphi mit der Komponente TsgcAI_MCP_Server durch, gibt ein funktionierendes get_weather-Tool frei und verbindet es über stdio- und HTTP-Transports mit Claude Desktop.

Ein wenig Geschichte verortet MCP. Anthropic hat die Spezifikation Ende 2024 als Antwort auf die Inflation inkompatibler Tool-Call-Formate veröffentlicht — OpenAIs Function-Calling-JSON, Googles Gemini-Grounding-Tools, die Eigen­schemas jedes Herstellers. Wenn du das liest, ist MCP-Support in Claude Desktop, Cursor, Continue, Zed und den meisten modernen KI-IDEs ausgeliefert; OpenAI hat Anfang 2026 Kompatibilität angekündigt. Anders gesagt: Heute einen MCP-Server zu bauen ist eine einmalige Investition, die sich über jeden Client auszahlt, den deine Kunden nutzen könnten — heute und morgen.

MCP-Bausteine

Ein MCP-Server kann drei Arten von Fähigkeiten freigeben:

Tools

Aufrufbare Funktionen mit typisierten Eingaben. Das Modell entscheidet, wann es sie ruft. Beispiel: get_weather(city), create_invoice(customer, lines).
Resources

Nur-Lese-Daten, die das Modell holen kann. Jede Ressource hat eine URI. Beispiel: file:///docs/handbook.md, db://customers/12345.
Prompts

Wiederverwendbare Prompt-Vorlagen, die der Benutzer (nicht das Modell) auswählt. Beispiel: eine „Übersetze ins formelle Spanisch“- oder „Meeting-Notizen zusammenfassen“-Vorlage.

Das Protokoll nutzt JSON-RPC 2.0 über einen von zwei Transports: stdio (der Server ist ein Kindprozess; Nachrichten fließen über stdin/stdout) oder HTTP mit Server-Sent Events für den Server-zu-Client-Stream. Stdio ist der Standard für Desktop-Integrationen wie Claude Desktop; HTTP ist die richtige Wahl, wenn der Server auf einer anderen Maschine läuft oder mehrere Clients bedient.

Die Komponente versteckt beide Transports hinter einer einzigen API. Du schreibst deinen Tool-Handler einmal und wählst den Transport beim Start. Derselbe Code läuft als Claude-Desktop-Helfer, als netzwerkerreichbarer HTTP-Dienst oder als beides gleichzeitig in einem Prozess. Wir kennen Häuser, die 30+ MCP-Server auf einer einzigen Box betreiben — gemultiplext über verschiedene Ports und ein, zwei stdio-Binaries — und alle bedienen dieselbe Delphi-Codebasis.

Projekt-Setup

Füge sgcAI_MCP_Server in deine uses-Klausel ein, zieh ein TsgcAI_MCP_Server auf das Formular (oder erzeuge es in Code für eine Konsolen-App), verdrahte die Events und starte ihn. Die Komponente erledigt das JSON-RPC-Framing, das Message-Routing und das Fähigkeits-Advertisement für dich.

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;

Ein Tool implementieren: get_weather

Ein Tool braucht zwei Handler. OnListTools sagt dem Client, welche Tools existieren und welche Argumente sie akzeptieren. OnCallTool führt den Aufruf aus. Beide Handler sind normale Delphi-Events — keine manuelle JSON-Konstruktion.

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;

Das ist die vollständige Implementierung. Die Komponente kümmert sich um die Eingabevalidierung gegen das Schema, die Fehler-Formatierung und den zugrunde liegenden JSON-RPC-Umschlag. Du konzentrierst dich auf die Geschäftslogik.

Ein paar Prinzipien für gute Tool-Designs, hart erarbeitet:

Ressourcen freigeben

Tools sind für Aktionen; Ressourcen sind für Daten, die das Modell lesen kann. Ein Resource-Handler liefert den Inhalt für eine gegebene URI. Ein Doku-Server könnte jede Markdown-Datei unter docs/ als Ressource freigeben.

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

Wähle den Transport danach, wo der Server läuft und wer ihn nutzt.

Transport Anwendungsfall Vorteile Nachteile
Stdio Lokale Desktop-Tools (Claude Desktop, Cursor) Null Konfiguration, keine Ports, OS regelt den Prozess-Lebenszyklus Ein Client pro Prozess, kein Remote-Zugriff
HTTP / SSE Gemeinsam genutzte Unternehmens-Server, Web-Clients, Multi-Tenant Viele Clients, netzwerkerreichbar, TLS, Auth Benötigt Hosting, Port-Management, Auth-Design

Den Transport zu wechseln ist ein Einzeiler:

// 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;

Verbindung aus Claude Desktop

Für stdio editiere claude_desktop_config.json und ergänze einen Eintrag, der auf deine kompilierte .exe zeigt. Claude Desktop startet den Prozess bei Bedarf.

{
  "mcpServers": {
    "weather": {
      "command": "C:\\Tools\\weather-mcp.exe",
      "args": []
    }
  }
}

Starte Claude Desktop neu, und du siehst ein kleines Tools-Icon im Prompt-Bereich. Frage „What is the weather in Tokyo?“ und Claude ruft dein Delphi-Tool auf.

Für HTTP zeigst du jeden MCP-fähigen Client auf https://your-host:8080/mcp. Derselbe Delphi-Server bedient parallel eine Claude-Desktop-Instanz, eine Cursor-Session und einen eigenen Delphi-MCP-Client.

Prompts: die unterschätzte dritte Fähigkeit

Tools und Ressourcen bekommen die ganze Aufmerksamkeit; Prompts sind der stille Arbeiter. Ein MCP-Prompt ist eine wiederverwendbare Vorlage — „Fasse dieses Meeting zusammen“, „Extrahiere die To-dos“, „Übersetze ins formelle Spanisch“ — die der Benutzer aus einem UI-Menü seines MCP-Clients aufruft. Das Modell führt diesen Prompt dann gegen den vom Benutzer gelieferten Kontext aus.

Für internes Tooling ist das Gold wert. Dein Support-Team bekommt eine kuratierte Liste firmen-gesegneter Prompts direkt in Claude Desktop. Dein Vertriebsteam bekommt einen „Folge-E-Mail entwerfen“-Prompt, der eure Tonalität schon kennt. Niemand muss Prompt-Engineering lernen — einfach die Vorlage wählen.

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;

Produktions-Überlegungen

Ein paar Dinge, die du einplanen solltest, bevor du einen MCP-Server in Produktion bringst:

Debugging-Tipps

MCP läuft unsichtbar im KI-Client — das macht das Debugging beim ersten Problem knifflig. Drei Gewohnheiten ersparen dir Stunden:

Abschluss

MCP verwandelt eine interne Delphi-API in etwas, das jeder moderne KI-Client nutzen kann — ohne pro Client zu verdrahten. Die Komponente TsgcAI_MCP_Server handhabt das JSON-RPC-Framing, den Transport und das Fähigkeits-Advertisement, sodass du nur den eigentlichen Tool-Body schreibst. Starte mit einem Nur-Lese-Tool, schau, wie das Modell es nutzt, und erweitere dann um Schreiben, Ressourcen und Prompts.

Unser wichtigster Take-away aus dem internen MCP-Rollout: Der Wert ist nicht „Claude kann jetzt unsere APIs nutzen“. Der Wert ist „jeder im Unternehmen kann unsere APIs über natürliche Sprache nutzen, ohne die API zu lernen“. Das verändert, wer was tun kann — und genau dort entsteht der eigentliche Produktivitätsgewinn.

Willst du den passenden Client? Siehe TsgcAI_MCP_Client für den Bau von Delphi-Apps, die beliebige MCP-Server konsumieren. Und wenn du neu bei den KI-Komponenten bist, führt dich der Getting-Started-Hub in fünf Minuten durch die Installation.