Model Context Protocol (MCP) — это новый протокол, разработанный для унификации взаимодействия между клиентскими приложениями и различными моделями искусственного интеллекта (ИИ), такими как LLM (Large Language Models). MCP предоставляет стандартизированный способ обнаружения и доступа к инструментам и контенту через JSON RPC 2.0 API.
Как отмечают участники форума, MCP пока что кажется ориентированным в первую очередь на Claude от Anthropic, но другие системы, такие как Cursor, уже начали адаптировать этот протокол, что может свидетельствовать о его становлении в качестве отраслевого стандарта.
Зачем реализовывать MCP-сервер на Delphi?
Основные причины для реализации MCP-сервера на Delphi:
Интеграция Delphi-приложений с современными ИИ-системами
Предоставление доступа к данным и функциональности вашего приложения через стандартизированный интерфейс
Участие в экосистеме инструментов, поддерживающих 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
Используйте стандартные библиотеки: Для работы с JSON в Delphi есть отличные встроенные средства (System.JSON).
Обработка ошибок: MCP требует строгого соблюдения формата JSON-RPC 2.0, включая обработку ошибок.
Производительность: Для высоконагруженных серверов рассмотрите возможность использования Indy или другого асинхронного серверного фреймворка.
Безопасность: Реализуйте аутентификацию и авторизацию, если ваш сервер будет доступен извне.
Логирование: Добавьте детальное логирование всех входящих запросов и ответов для отладки.
Заключение
Реализация MCP-сервера на Delphi — вполне выполнимая задача, как демонстрирует пример Geoffrey Smith. Такой сервер может стать мостом между вашими Delphi-приложениями и современными ИИ-системами.
Как отметили участники обсуждения, альтернативой может быть клиентская реализация с прямым доступом к API различных LLM. Выбор между серверным и клиентским подходом зависит от конкретных требований вашего проекта.
Для дальнейшего развития проекта рассмотрите:
Добавление поддержки дополнительных методов MCP
Реализацию более сложных сценариев взаимодействия
Интеграцию с другими API и сервисами
Оптимизацию производительности для работы в высоконагруженных сценариях
Delphi продолжает оставаться мощным инструментом для создания современных решений, включая интеграцию с передовыми технологиями, такими как MCP и LLM.
Статья описывает реализацию MCP-сервера на Delphi для интеграции приложений с ИИ-системами через стандартизированный интерфейс JSON RPC 2.0.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.