Outils du client ACP — explication
De quoi s'agit-il ?
Un éditeur, ou tout programme qui pilote mm -acp, sait souvent des choses que l'agent ne peut pas atteindre : les buffers ouverts à l'écran, la sélection, les données d'une application, un appareil. Les outils du client ACP permettent à ce programme de prêter à l'agent ses propres fonctions. Le modèle les appelle comme bash ou read_file ; mm transmet chaque appel au client sous forme de requête ACP et rend la réponse au modèle. Le protocole exact est dans la référence ; cette page explique pourquoi il a cette forme.
Pourquoi mm avait besoin de sa propre convention
ACP a un mécanisme d'extension : chaque côté peut définir des méthodes dont le nom commence par _, et les annoncer dans l'objet _meta des capacités échangées à initialize. Cela suffit pour appeler une méthode, pas pour en faire un outil : un modèle a besoin d'un nom, d'une description et d'un schéma des arguments, et ACP ne définit aucun moyen de décrire tout cela. mm en définit donc un, sous son propre espace de noms (org.mini-me), en n'utilisant que ce qu'ACP fournit déjà — _meta pour l'annonce, les méthodes d'extension pour les appels. Un client qui n'en sait rien n'envoie rien, et rien ne change.
La description d'un outil reprend volontairement celle de MCP (name, description, inputSchema), et la réponse aussi (blocs content, isError). Quiconque a écrit un outil MCP connaît déjà les deux formes, et mm savait déjà présenter un schéma MCP à un petit modèle (le même nettoyage de required et enum s'applique, pour les mêmes raisons : voir Choix de conception MCP).
Deux modes de découverte, et pourquoi meta par défaut
meta: la liste voyage dansinitialize. Un seul message, rien à répondre, et la liste est connue avant qu'aucune session n'existe. La plupart des clients ont un jeu d'outils fixe, et pour eux c'est le moins de code à écrire. D'où le choix par défaut.request: le client dit seulement qu'il a des outils, et mm demande la liste à chaque ouverture, chargement ou reprise de session. C'est pour un client dont les outils dépendent de la session — son répertoire de travail, l'utilisateur derrière — ou changent avec le temps.
Le mode request a une contrainte à connaître : mm envoie la requête de liste pendant que le client attend encore sa réponse à session/new. Un client qui traiterait les requêtes une par une attendrait mm pendant que mm l'attend. Les SDK ACP (Go, TypeScript) traitent chaque requête entrante à part, donc cela ne leur coûte rien ; c'est écrit dans la spécification pour les clients qui font leur propre JSON-RPC.
Pourquoi la session voyage dans _meta, et les arguments au premier niveau
Les params de l'appel sont exactement les arguments du modèle. Cela permet d'utiliser telle quelle une méthode d'extension existante : un client qui répond déjà à _com.example/workspace/buffers {"language": "go"} peut l'exposer comme outil sans adaptateur. L'id de session n'est pas un argument choisi par le modèle : il va là où ACP met les données hors bande — _meta — et le modèle ne peut pas le falsifier : un _meta qu'il aurait inventé est remplacé.
Pourquoi les outils sont construits par session et jamais enregistrés
Genkit tient un registre d'outils nommés, et enregistrer deux fois le même nom est une erreur. Les outils du client changent selon la connexion (et selon la session en mode request) : mm les construit donc comme outils dynamiques (ai.NewTool), que Genkit enregistre dans un registre enfant le temps d'une génération. Deux sessions peuvent alors avoir un client_open_buffers défini différemment, et rien n'est à désenregistrer quand une session se termine.
Pourquoi les erreurs sont des réponses
Un client qui ne répond pas, répond Method not found ou signale un échec donne au modèle un texte [client tool error: …], et le tour continue. C'est la règle générale de mm (voir Architecture) : c'est le modèle qui doit réagir, c'est donc lui qui doit lire ce qui n'a pas marché. La même règle vaut pour une liste mal formée : une entrée inutilisable est ignorée avec une ligne sur stderr, et la session s'ouvre avec les autres. L'erreur d'un client ne doit pas coûter la conversation à l'utilisateur.
Permissions
Les outils du client suivent la règle des outils venus d'ailleurs, avec leur propre clé (acp.clientTools.permissions) : ask demande toujours, auto ne demande que si yolo est désactivé. La valeur par défaut est auto, là où celle de MCP est ask, parce que la confiance n'est pas la même : un serveur MCP est du code tiers, un outil client est une fonction du programme même que l'utilisateur a lancé pour parler à l'agent. Voir Mode yolo et permissions.
Alternatives écartées
- Utiliser les
mcpServersdesession/new. ACP permet à un client de donner à l'agent des serveurs MCP auxquels se connecter. Cela aurait obligé le client à faire tourner un serveur MCP — un second protocole, un second transport — pour exposer une fonction qu'il détient déjà dans le même processus, au bout du tuyau qu'il partage déjà avec mm. - Une méthode générique,
_org.mini-me/tools/call {name, arguments}. Plus simple à aiguiller, mais elle imposerait à chaque client le nom de méthode de mm ; unemethodpar outil permet à un client d'exposer des méthodes d'extension qu'il a déjà. - Déclarer les outils dans
agent.yaml. Le fichier d'agent ne sait pas quel client le lancera, et le même agent peut être piloté par un éditeur aujourd'hui et par un script demain. Les outils appartiennent au client : c'est au client de les annoncer. - Un seul mode de découverte.
metaseul ne peut pas servir des outils qui dépendent de la session ;requestseul impose à chaque client un handler de requête et un aller-retour pour une liste généralement fixe.
Lien avec le reste
- Les outils n'existent qu'en mode ACP : le terminal et la fenêtre n'ont pas de client pour les prêter.
- Une fois déclarés, ce sont des outils ordinaires pour le reste de mm : le routage des outils peut les écarter d'un tour quand un de ses groupes correspond à leur nom (
^client_), les hooks voient leurs appels, le détecteur de boucles les compte. demo.acp.sdk/go(Options.Tools) etdemo.acp.sdk/client-tools-nodejssont deux implémentations client ; Proposer des outils depuis votre client ACP en détaille une.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|