Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Реализация MCP-сервера на Delphi: советы и быстрый старт.

Delphi , Синтаксис , API реализация

 

Введение в Model Context Protocol (MCP)

Model Context Protocol (MCP) — это новый протокол, разработанный для унификации взаимодействия между клиентскими приложениями и различными моделями искусственного интеллекта (ИИ), такими как LLM (Large Language Models). MCP предоставляет стандартизированный способ обнаружения и доступа к инструментам и контенту через JSON RPC 2.0 API.

Как отмечают участники форума, MCP пока что кажется ориентированным в первую очередь на Claude от Anthropic, но другие системы, такие как Cursor, уже начали адаптировать этот протокол, что может свидетельствовать о его становлении в качестве отраслевого стандарта.

Зачем реализовывать MCP-сервер на Delphi?

Основные причины для реализации MCP-сервера на Delphi:

  1. Интеграция Delphi-приложений с современными ИИ-системами
  2. Предоставление доступа к данным и функциональности вашего приложения через стандартизированный интерфейс
  3. Участие в экосистеме инструментов, поддерживающих MCP

Как отметил пользователь omnibrain: "Я хочу реализовать несколько вещей: a) способ для любого агента взаимодействовать с (аспектами) моего программного обеспечения; b) MCP-сервер для используемой нами СУБД, чтобы я мог использовать (мета)информацию во время разработки с помощью агентов или Cursor."

Быстрый старт: пример реализации MCP-сервера на Delphi

Рассмотрим пример реализации простого MCP-сервера для получения погодных данных, основанный на коде Geoffrey Smith с GitHub.

1. Базовый каркас MCP-сервера

unit MCPServerCore;

interface

uses
  System.Classes, System.SysUtils, System.JSON, System.NetEncoding;

type
  TMCPServer = class
  private
    FOnRequest: TFunc<string, string>;
  public
    constructor Create;
    function ProcessRequest(const ARequest: string): string;
    property OnRequest: TFunc<string, string> read FOnRequest write FOnRequest;
  end;

implementation

{ TMCPServer }

constructor TMCPServer.Create;
begin
  inherited;
end;

function TMCPServer.ProcessRequest(const ARequest: string): string;
var
  LJSON, LResponse: TJSONObject;
  LMethod: string;
begin
  try
    LJSON := TJSONObject.ParseJSONValue(ARequest) as TJSONObject;
    try
      if not Assigned(LJSON) then
        raise Exception.Create('Invalid JSON request');

      LMethod := LJSON.GetValue<string>('method', '');

      if Assigned(FOnRequest) then
        Result := FOnRequest(ARequest)
      else
      begin
        LResponse := TJSONObject.Create;
        try
          LResponse.AddPair('jsonrpc', '2.0');
          LResponse.AddPair('error', TJSONObject.Create
            .AddPair('code', -32601)
            .AddPair('message', 'Method not found'));
          LResponse.AddPair('id', LJSON.GetValue('id', TJSONNull.Create));
          Result := LResponse.ToString;
        finally
          LResponse.Free;
        end;
      end;
    finally
      LJSON.Free;
    end;
  except
    on E: Exception do
    begin
      LResponse := TJSONObject.Create;
      try
        LResponse.AddPair('jsonrpc', '2.0');
        LResponse.AddPair('error', TJSONObject.Create
          .AddPair('code', -32603)
          .AddPair('message', E.Message));
        LResponse.AddPair('id', TJSONNull.Create);
        Result := LResponse.ToString;
      finally
        LResponse.Free;
      end;
    end;
  end;
end;

end.

2. Реализация сервиса погоды

unit WeatherService;

interface

uses
  System.Classes, System.SysUtils, System.JSON, System.Net.HttpClient,
  MCPServerCore;

type
  TWeatherService = class
  private
    FMCPServer: TMCPServer;
    FAPIKey: string;
    function HandleRequest(const ARequest: string): string;
    function GetWeather(const AParams: TJSONObject): TJSONObject;
  public
    constructor Create(const AAPIKey: string);
    destructor Destroy; override;
    property MCPServer: TMCPServer read FMCPServer;
  end;

implementation

{ TWeatherService }

constructor TWeatherService.Create(const AAPIKey: string);
begin
  inherited Create;
  FAPIKey := AAPIKey;
  FMCPServer := TMCPServer.Create;
  FMCPServer.OnRequest := HandleRequest;
end;

destructor TWeatherService.Destroy;
begin
  FMCPServer.Free;
  inherited;
end;

function TWeatherService.HandleRequest(const ARequest: string): string;
var
  LJSON, LResponse: TJSONObject;
  LMethod: string;
begin
  LJSON := TJSONObject.ParseJSONValue(ARequest) as TJSONObject;
  try
    LMethod := LJSON.GetValue<string>('method', '');

    if SameText(LMethod, 'weather.getCurrent') then
    begin
      LResponse := TJSONObject.Create;
      try
        LResponse.AddPair('jsonrpc', '2.0');
        LResponse.AddPair('result', GetWeather(LJSON.GetValue<TJSONObject>('params')));
        LResponse.AddPair('id', LJSON.GetValue('id', TJSONNull.Create));
        Result := LResponse.ToString;
      finally
        LResponse.Free;
      end;
    end
    else
    begin
      LResponse := TJSONObject.Create;
      try
        LResponse.AddPair('jsonrpc', '2.0');
        LResponse.AddPair('error', TJSONObject.Create
          .AddPair('code', -32601)
          .AddPair('message', 'Method not found'));
        LResponse.AddPair('id', LJSON.GetValue('id', TJSONNull.Create));
        Result := LResponse.ToString;
      finally
        LResponse.Free;
      end;
    end;
  finally
    LJSON.Free;
  end;
end;

function TWeatherService.GetWeather(const AParams: TJSONObject): TJSONObject;
var
  LHTTP: THTTPClient;
  LResponse: IHTTPResponse;
  LURL: string;
  LLocation: string;
begin
  if not AParams.TryGetValue<string>('location', LLocation) then
    raise Exception.Create('Location parameter is required');

  LURL := Format('http://api.weatherapi.com/v1/current.json?key=%s&q=%s', 
    [FAPIKey, TNetEncoding.URL.Encode(LLocation)]);

  LHTTP := THTTPClient.Create;
  try
    LResponse := LHTTP.Get(LURL);
    if LResponse.StatusCode <> 200 then
      raise Exception.CreateFmt('Weather API error: %d - %s', 
        [LResponse.StatusCode, LResponse.StatusText]);

    Result := TJSONObject.ParseJSONValue(LResponse.ContentAsString) as TJSONObject;
  finally
    LHTTP.Free;
  end;
end;

end.

3. Основная программа сервера

program WeatherMCPService;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.Classes, System.JSON, WeatherService;

var
  LService: TWeatherService;
  LInput: string;
begin
  try
    if ParamCount < 1 then
    begin
      Writeln('Usage: WeatherMCPService <WeatherAPI_Key>');
      Exit;
    end;

    LService := TWeatherService.Create(ParamStr(1));
    try
      Writeln('Weather MCP Service started. Ready for requests...');

      while True do
      begin
        Readln(LInput);
        if SameText(LInput, 'exit') then Break;

        try
          Writeln(LService.MCPServer.ProcessRequest(LInput));
        except
          on E: Exception do
            Writeln(Format('{"jsonrpc":"2.0","error":{"code":-32603,"message":"%s"},"id":null}', 
              [E.Message]));
        end;
      end;
    finally
      LService.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Альтернативный подход: клиентская реализация

Как отметил Rollo62: "Для использования агентов, не имело бы больше (или такого же) смысла иметь эти функции, встроенные в клиентский SDK (Delphi Code) с самого начала? Тогда ваше приложение имело бы локальный, полный контроль над всеми LLM и БД."

Действительно, для некоторых сценариев может быть предпочтительнее реализовать функциональность непосредственно в клиентском приложении. Вот пример унифицированного интерфейса для работы с разными LLM:

unit LLMInterface;

interface

type
  ILLMProvider = interface
    ['{8A5A8C0B-4D1F-4F5A-9E2D-3D3E4F5A6B7C}']
    function SendPrompt(const APrompt: string): string;
    function GetModelInfo: string;
  end;

  TLLMManager = class
  private
    FProviders: TArray<ILLMProvider>;
  public
    procedure RegisterProvider(const AProvider: ILLMProvider);
    function GetResponse(const APrompt: string; AProviderIndex: Integer = 0): string;
  end;

implementation

{ TLLMManager }

procedure TLLMManager.RegisterProvider(const AProvider: ILLMProvider);
begin
  SetLength(FProviders, Length(FProviders) + 1);
  FProviders[High(FProviders)] := AProvider;
end;

function TLLMManager.GetResponse(const APrompt: string; AProviderIndex: Integer): string;
begin
  if (AProviderIndex < 0) or (AProviderIndex >= Length(FProviders)) then
    raise Exception.Create('Invalid provider index');

  Result := FProviders[AProviderIndex].SendPrompt(APrompt);
end;

end.

Советы по реализации MCP-сервера на Delphi

  1. Используйте стандартные библиотеки: Для работы с JSON в Delphi есть отличные встроенные средства (System.JSON).

  2. Обработка ошибок: MCP требует строгого соблюдения формата JSON-RPC 2.0, включая обработку ошибок.

  3. Производительность: Для высоконагруженных серверов рассмотрите возможность использования Indy или другого асинхронного серверного фреймворка.

  4. Безопасность: Реализуйте аутентификацию и авторизацию, если ваш сервер будет доступен извне.

  5. Логирование: Добавьте детальное логирование всех входящих запросов и ответов для отладки.

Заключение

Реализация MCP-сервера на Delphi — вполне выполнимая задача, как демонстрирует пример Geoffrey Smith. Такой сервер может стать мостом между вашими Delphi-приложениями и современными ИИ-системами.

Как отметили участники обсуждения, альтернативой может быть клиентская реализация с прямым доступом к API различных LLM. Выбор между серверным и клиентским подходом зависит от конкретных требований вашего проекта.

Для дальнейшего развития проекта рассмотрите:

  1. Добавление поддержки дополнительных методов MCP
  2. Реализацию более сложных сценариев взаимодействия
  3. Интеграцию с другими API и сервисами
  4. Оптимизацию производительности для работы в высоконагруженных сценариях

Delphi продолжает оставаться мощным инструментом для создания современных решений, включая интеграцию с передовыми технологиями, такими как MCP и LLM.

Создано по материалам из источника по ссылке.

Статья описывает реализацию MCP-сервера на Delphi для интеграции приложений с ИИ-системами через стандартизированный интерфейс JSON RPC 2.0.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: API реализация ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-17 08:08:14/0.004321813583374/0