Qu'est-ce que le Model Context Protocol ?
Le Model Context Protocol (MCP) est le standard ouvert d'Anthropic pour exposer outils, données et templates de prompts aux modèles d'IA. Pensez-y comme à de l'USB pour l'IA : n'importe quel serveur MCP peut être branché à n'importe quel client MCP (Claude Desktop, Cursor, Continue, votre propre application Delphi, les clients d'OpenAI), et le modèle découvre immédiatement quels outils sont disponibles et comment les appeler.
Avant MCP, chaque intégration IA signifiait câbler des définitions d'outils, des schémas JSON et des dispatchers d'appels dans chaque application individuelle. MCP condense cela en un seul protocole : écrivez le serveur une fois, chaque modèle peut l'utiliser. Pour les shops Delphi qui ont déjà une pile d'API métier — requêtes ERP, recherches CRM, générateurs de fichiers, fonctions de facturation — MCP est le chemin le moins cher pour rendre ces API accessibles à l'IA.
Ce tutoriel passe en revue la construction d'un serveur MCP en Delphi avec le composant TsgcAI_MCP_Server, l'exposition d'un outil get_weather fonctionnel, et sa connexion à Claude Desktop via les transports stdio et HTTP.
Un peu d'histoire met MCP en contexte. Anthropic a publié la spec fin 2024 en réponse à la prolifération des formats d'appel d'outils incompatibles — le JSON function-calling d'OpenAI, les outils de grounding Gemini de Google, le schéma sur mesure de chaque éditeur. Au moment où vous lisez ceci, le support MCP est livré dans Claude Desktop, Cursor, Continue, Zed et la plupart des IDE IA modernes ; OpenAI a annoncé la compatibilité début 2026. Autrement dit : construire un serveur MCP aujourd'hui est un investissement unique qui paie sur tous les clients que vos clients pourraient utiliser, aujourd'hui et demain.
Briques de construction MCP
Un serveur MCP peut exposer trois types de capacités :
| Outils Fonctions appelables avec entrées typées. Le modèle décide quand les invoquer. Exemple : get_weather(city), create_invoice(customer, lines). |
Ressources Données en lecture seule que le modèle peut récupérer. Chaque ressource a un URI. Exemple : file:///docs/handbook.md, db://customers/12345. |
Prompts Templates de prompts réutilisables que l'utilisateur (pas le modèle) sélectionne. Exemple : un template « Traduire en espagnol formel » ou « Résumer des notes de réunion ». |
Le protocole utilise JSON-RPC 2.0 sur l'un des deux transports : stdio (le serveur est un processus enfant ; les messages passent par stdin/stdout) ou HTTP avec Server-Sent Events pour le flux serveur-vers-client. Stdio est le défaut pour les intégrations bureau comme Claude Desktop ; HTTP est le bon choix quand le serveur tourne sur une autre machine ou sert plusieurs clients.
Le composant cache les deux transports derrière une seule API. Vous écrivez votre handler d'outil une fois, puis choisissez le transport au démarrage. Le même code tourne comme helper Claude Desktop, comme service HTTP joignable sur le réseau, ou les deux en même temps dans un seul processus. Nous avons des shops qui font tourner 30+ serveurs MCP sur une seule machine, multiplexés sur différents ports et un ou deux binaires stdio, tous servant la même base de code Delphi.
Mise en place du projet
Ajoutez sgcAI_MCP_Server à votre uses clause, déposez un TsgcAI_MCP_Server sur la fiche (ou créez-le en code pour une application console), câblez les événements et démarrez-le. Le composant fait le framing JSON-RPC, le routage de messages et l'annonce de capacités pour vous.
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;
Implémenter un outil : get_weather
Un outil a besoin de deux handlers. OnListTools indique au client quels outils existent et quels arguments ils acceptent. OnCallTool exécute réellement l'appel. Les deux handlers sont des événements Delphi simples — pas de construction JSON manuelle.
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;
C'est l'implémentation complète. Le composant prend en charge la validation des entrées contre le schéma, le formatage des erreurs et l'enveloppe JSON-RPC sous-jacente. Vous vous concentrez sur la logique métier.
Quelques principes pour concevoir de bons outils, appris à la dure :
- Un verbe par outil. « get_weather » est meilleur que « weather_operations » avec un paramètre de sous-action. Le modèle choisit le bon outil plus vite quand chaque nom décrit exactement un résultat.
- Soyez impitoyable avec les descriptions. La description du schéma est votre seule chance d'apprendre au modèle ce que l'outil fait et ne fait pas. Détaillez les cas limites, les unités, les formats et les prérequis.
- Mettez des valeurs par défaut partout où vous le pouvez. Les paramètres optionnels avec des défauts sensés permettent au modèle d'appeler votre outil avec succès même quand il ne connaît que la moitié du contexte.
- Retournez des payloads petits et ciblés. Une réponse texte de 50 lignes convient ; un dump de 5 000 lignes gonfle la fenêtre de contexte et la facture. Résumez côté serveur.
- Échouez explicitement. Retournez un message d'erreur structuré (« City not recognised. Did you mean Madrid or Madras? ») au lieu de retourner silencieusement des résultats vides.
Exposer des ressources
Les outils sont pour les actions ; les ressources sont pour les données que le modèle peut lire. Un handler de ressource retourne le contenu pour un URI donné. Un serveur de documentation pourrait exposer chaque fichier Markdown sous docs/ comme ressource.
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
Choisissez le transport en fonction de l'endroit où le serveur tourne et de qui l'utilise.
| Transport | Cas d'usage | Avantages | Inconvénients |
| Stdio | Outils bureau locaux (Claude Desktop, Cursor) | Aucune config, pas de ports, l'OS gère le cycle de vie du processus | Un client par processus, pas d'accès distant |
| HTTP / SSE | Serveurs d'entreprise partagés, clients web, multi-tenant | Plusieurs clients, joignable sur le réseau, TLS, auth | Nécessite hébergement, gestion de ports, conception d'auth |
Changer de transport tient en une ligne :
// 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;
Se connecter depuis Claude Desktop
Pour stdio, éditez claude_desktop_config.json et ajoutez une entrée pointant vers votre .exe compilé. Claude Desktop lancera le processus à la demande.
{
"mcpServers": {
"weather": {
"command": "C:\\Tools\\weather-mcp.exe",
"args": []
}
}
}
Redémarrez Claude Desktop et vous verrez une petite icône d'outils dans la zone de prompt. Demandez « What is the weather in Tokyo? » et Claude appellera votre outil Delphi.
Pour HTTP, pointez n'importe quel client compatible MCP sur https://your-host:8080/mcp. Le même serveur Delphi gère heureusement une instance Claude Desktop, une session Cursor et un client Delphi MCP personnalisé en même temps.
Prompts : la troisième capacité sous-utilisée
Les outils et les ressources reçoivent toute l'attention ; les prompts sont la bête de somme silencieuse. Un prompt MCP est un template réutilisable — « résumer cette réunion », « extraire les actions », « traduire en espagnol formel » — que l'utilisateur invoque depuis un menu UI dans son client MCP. Le modèle exécute ensuite ce prompt sur le contexte que l'utilisateur fournit.
Pour l'outillage interne, c'est de l'or. Votre équipe support obtient une liste organisée de prompts approuvés par l'entreprise dans Claude Desktop. Votre équipe commerciale obtient un prompt « rédiger un email de relance » qui connaît déjà votre ton. Aucun d'eux n'a à apprendre le prompt engineering — ils choisissent simplement le 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;
Considérations de production
Quelques éléments à budgétiser avant de livrer un serveur MCP en production :
- Authentification : stdio hérite de la confiance niveau OS, mais HTTP a besoin de bearer tokens ou mTLS. Utilisez
OnHTTPAuthenticatepour valider. - Limitation de débit : un modèle bavard peut tirer des appels d'outils en boucles serrées. Associez le serveur MCP à
TsgcWebSocketHTTPServer_RateLimiterou à votre propre logique de quota. - Journalisation : branchez
OnLogpour capturer chaque appel d'outil. Vous en aurez besoin quand un utilisateur signalera « Claude a fait quelque chose de bizarre ». - Discipline de schéma : plus vos schémas JSON sont précis (descriptions, enums, exemples), mieux le modèle choisit le bon outil avec les bons arguments.
- Idempotence : les outils peuvent être appelés deux fois si le modèle réessaie. Marquez les opérations d'écriture comme idempotentes ou ajoutez un paramètre d'ID de transaction.
Astuces de débogage
MCP tourne invisiblement à l'intérieur du client IA, ce qui rend le débogage délicat la première fois que quelque chose se passe mal. Trois habitudes vous épargneront des heures :
- Stderr est votre console. En mode stdio, stdout appartient à JSON-RPC. Tout ce que vous y écrivez casse le protocole. Loggez sur stderr (que Claude Desktop capture dans ses fichiers de log) ou dans un fichier de log latéral avec un suffixe d'ID de processus.
- Utilisez l'Inspector MCP. Anthropic livre un outil gratuit (
npx @modelcontextprotocol/inspector) qui vous laisse pointer une UI sur votre serveur, cliquer sur chaque outil, voir la requête/réponse brute et valider les schémas sans impliquer un client IA du tout. - Ajoutez un outil « diagnostic ». Un simple outil
server_infoqui retourne la date de build, l'hôte et la version rend trivial de confirmer dans le client IA que vous parlez au bon serveur. Nous ajoutons cela à chaque serveur MCP de production.
Pour conclure
MCP transforme une API Delphi interne en quelque chose que chaque client IA moderne peut utiliser, sans câblage par client. Le composant TsgcAI_MCP_Server gère le framing JSON-RPC, le transport et l'annonce de capacités, vous laissant écrire le vrai corps d'outil. Commencez avec un outil en lecture seule, voyez comment le modèle l'utilise, puis étendez aux écritures, ressources et prompts.
Notre plus grand enseignement après avoir déployé MCP en interne : la valeur n'est pas « Claude peut maintenant utiliser nos API ». La valeur est « n'importe qui dans l'entreprise peut utiliser nos API via du langage naturel, sans apprendre l'API ». Cela change qui peut faire quoi, et c'est là que vient le vrai gain de productivité.
Vous voulez le client correspondant ? Voir TsgcAI_MCP_Client pour construire des applications Delphi qui consomment n'importe quel serveur MCP. Et si vous êtes nouveau sur les composants IA, le hub Premiers pas vous guide à travers l'installation en cinq minutes.