Budowanie serwera Model Context Protocol (MCP) w Delphi

· Komponenty

Czym jest Model Context Protocol?

Model Context Protocol (MCP) to otwarty standard Anthropic do udostępniania narzędzi, danych i szablonów promptów modelom AI. Pomyśl o tym jak o USB dla AI: dowolny serwer MCP może być podłączony do dowolnego klienta MCP (Claude Desktop, Cursor, Continue, Twoja własna aplikacja Delphi, klienci OpenAI), a model natychmiast odkrywa, jakie narzędzia są dostępne i jak je wywołać.

Przed MCP każda integracja AI oznaczała podłączanie definicji narzędzi, schematów JSON i dispatcherów wywołań do każdej indywidualnej aplikacji. MCP zwija to w pojedynczy protokół: napisz serwer raz, każdy model może go używać. Dla sklepów Delphi, które już mają stos biznesowych API — zapytania ERP, wyszukiwania CRM, generatory plików, funkcje rozliczeniowe — MCP to najtańsza droga do uczynienia tych API dostępnymi dla AI.

Ten samouczek omawia budowanie serwera MCP w Delphi przy użyciu komponentu TsgcAI_MCP_Server, udostępniając działające narzędzie get_weather i podłączając je do Claude Desktop przez transporty stdio i HTTP.

Trochę historii umieszcza MCP w kontekście. Anthropic opublikował specyfikację pod koniec 2024 roku jako odpowiedź na proliferację niekompatybilnych formatów wywoływania narzędzi — JSON wywoływania funkcji OpenAI, narzędzia uziemienia Gemini Google, dedykowane schematy każdego dostawcy. Zanim to przeczytasz, wsparcie MCP jest dostarczane w Claude Desktop, Cursor, Continue, Zed i większości nowoczesnych IDE AI; OpenAI ogłosił kompatybilność na początku 2026 roku. Innymi słowy: budowanie serwera MCP dzisiaj to jednorazowa inwestycja, która zwraca się przez każdego klienta, którego mogą używać Twoi klienci, zarówno dziś, jak i jutro.

Klocki MCP

Serwer MCP może udostępniać trzy rodzaje możliwości:

Narzędzia

Wywoływalne funkcje z typowanymi wejściami. Model decyduje, kiedy je wywołać. Przykład: get_weather(city), create_invoice(customer, lines).
Zasoby

Dane tylko do odczytu, które model może pobrać. Każdy zasób ma URI. Przykład: file:///docs/handbook.md, db://customers/12345.
Prompty

Wielokrotnego użytku szablony promptów, które wybiera użytkownik (nie model). Przykład: szablon „Tłumacz na formalny hiszpański” lub „Podsumuj notatki ze spotkania”.

Protokół używa JSON-RPC 2.0 nad jednym z dwóch transportów: stdio (serwer to proces potomny; komunikaty płyną przez stdin/stdout) lub HTTP z Server-Sent Events dla strumienia serwer-do-klienta. Stdio jest domyślne dla integracji desktopowych jak Claude Desktop; HTTP to właściwy wybór, gdy serwer działa na innej maszynie lub obsługuje wielu klientów.

Komponent ukrywa oba transporty za pojedynczym API. Piszesz swój handler narzędzia raz, potem wybierasz transport przy starcie. Ten sam kod działa jako pomocnik Claude Desktop, usługa HTTP osiągalna z sieci lub oba jednocześnie wewnątrz jednego procesu. Mamy sklepy uruchamiające 30+ serwerów MCP na pojedynczym pudełku, multipleksowanych przez różne porty i jeden lub dwa binarne stdio, wszystkie obsługujące tę samą bazę kodu Delphi.

Konfiguracja projektu

Dodaj sgcAI_MCP_Server do swojej klauzuli uses, upuść TsgcAI_MCP_Server na formularz (lub utwórz go w kodzie dla aplikacji konsolowej), podepnij zdarzenia i uruchom go. Komponent wykonuje za Ciebie ramkowanie JSON-RPC, routing komunikatów i ogłaszanie możliwości.

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;

Implementacja narzędzia: get_weather

Narzędzie potrzebuje dwóch handlerów. OnListTools mówi klientowi, jakie narzędzia istnieją i jakie argumenty akceptują. OnCallTool faktycznie uruchamia wywołanie. Oba handlery to zwykłe zdarzenia Delphi — bez ręcznej konstrukcji JSON.

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;

To pełna implementacja. Komponent dba o walidację wejścia względem schematu, formatowanie błędów i pod spodem leżącą kopertę JSON-RPC. Ty koncentrujesz się na logice biznesowej.

Kilka zasad projektowania dobrych narzędzi, nauczonych drogą doświadczeń:

Udostępnianie zasobów

Narzędzia są do akcji; zasoby są do danych, które model może odczytać. Handler zasobu zwraca zawartość dla danego URI. Serwer dokumentacji może udostępniać każdy plik Markdown pod docs/ jako zasób.

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;

Transport stdio vs HTTP

Wybierz transport w zależności od tego, gdzie działa serwer i kto go używa.

Transport Przypadek użycia Zalety Wady
Stdio Lokalne narzędzia desktopowe (Claude Desktop, Cursor) Zero konfiguracji, bez portów, OS obsługuje cykl życia procesu Jeden klient na proces, brak dostępu zdalnego
HTTP / SSE Współdzielone serwery korporacyjne, klienci webowi, wielodzierżawne Wielu klientów, dostępny w sieci, TLS, auth Wymaga hostingu, zarządzania portami, projektu auth

Przełączanie transportu to jedna linia:

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

Łączenie z Claude Desktop

Dla stdio edytuj claude_desktop_config.json i dodaj wpis wskazujący na skompilowany .exe. Claude Desktop uruchomi proces na żądanie.

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

Zrestartuj Claude Desktop, a zobaczysz małą ikonę narzędzi w obszarze promptu. Zapytaj „Jaka jest pogoda w Tokio?”, a Claude wywoła Twoje narzędzie Delphi.

Dla HTTP wskaż dowolnemu klientowi obsługującemu MCP na https://your-host:8080/mcp. Ten sam serwer Delphi z radością obsługuje instancję Claude Desktop, sesję Cursor i niestandardowego klienta MCP Delphi jednocześnie.

Prompty: Niedoceniana trzecia możliwość

Narzędzia i zasoby dostają całą uwagę; prompty są cichym koniem pociągowym. Prompt MCP to wielokrotnego użytku szablon — „podsumuj to spotkanie”, „wyciągnij pozycje akcji”, „tłumacz na formalny hiszpański” — który użytkownik wywołuje z menu UI w swoim kliencie MCP. Model następnie uruchamia ten prompt na dowolnym kontekście, który dostarcza użytkownik.

Dla wewnętrznych narzędzi to złoto. Twój zespół wsparcia dostaje wyselekcjonowaną listę firmowo zaakceptowanych promptów wewnątrz Claude Desktop. Twój zespół sprzedaży dostaje prompt „naszkicuj email follow-up”, który już zna Twój ton głosu. Żaden z nich nie musi uczyć się inżynierii promptów — po prostu wybierają szablon.

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;

Rozważania produkcyjne

Kilka rzeczy do uwzględnienia w budżecie zanim dostarczysz serwer MCP do produkcji:

Wskazówki debugowania

MCP działa niewidocznie wewnątrz klienta AI, co utrudnia debugowanie za pierwszym razem, gdy coś idzie nie tak. Trzy nawyki zaoszczędzą Ci godziny:

Podsumowanie

MCP zamienia wewnętrzne API Delphi w coś, czego każdy nowoczesny klient AI może używać, bez podłączania per-klient. Komponent TsgcAI_MCP_Server obsługuje ramkowanie JSON-RPC, transport i ogłaszanie możliwości, zostawiając Tobie napisanie właściwego ciała narzędzia. Zacznij od jednego narzędzia tylko do odczytu, zobacz, jak model go używa, potem rozszerz do zapisów, zasobów i promptów.

Nasz największy wniosek z wewnętrznego wdrożenia MCP: wartość to nie „Claude może teraz używać naszych API”. Wartość to „każdy w firmie może używać naszych API poprzez język naturalny, bez uczenia się API”. To zmienia, kto może co zrobić, i stamtąd pochodzi rzeczywisty wzrost produktywności.

Chcesz pasującego klienta? Zobacz TsgcAI_MCP_Client do budowania aplikacji Delphi, które konsumują dowolny serwer MCP. A jeśli jesteś nowy z komponentami AI, hub Pierwsze kroki przeprowadzi Cię przez instalację w pięć minut.