Le serveur MCP n'a pas un outil par fonctionnalité. Grâce à trois outils généraux, un client IA accède à toutes les opérations de l'API REST (en anglais), sauf l'envoi de fichiers, toujours en votre nom et avec vos droits. Un quatrième outil renvoie votre propre profil. Quand l'API s'enrichit d'une fonctionnalité, les clients peuvent l'utiliser tout de suite.
| Outil | Titre affiché par les clients | Ce qu'il fait |
|---|---|---|
search_api | Search the API | Trouve des opérations de l'API et les décrit |
api_read | Read from the API | Envoie un GET à une opération de l'API |
api_write | Write to the API | Envoie un POST, un PATCH ou un DELETE |
get-current-user-tool | Get current user | Renvoie votre profil |
Trois outils ne font que lire. Write to the API est signalé comme un outil qui peut modifier des données : les clients vous demandent donc de l'approuver par défaut. La plupart des clients vous laissent l'autoriser pour une conversation ou de façon permanente. La page Droits et sécurité explique ce qu'un client a le droit de faire.
Comment un client utilise les outils
Chaque client reçoit aussi du serveur une courte série d'instructions. Elles décrivent trois étapes : trouver l'opération avec search_api, lire ce qu'elle accepte, puis l'appeler avec api_read ou api_write. Elles indiquent aussi au client que :
- les chemins des éléments de travail acceptent des clés comme
ACM-12 - les filtres sur les utilisateurs acceptent
me - supprimer demande
confirm: true, envoyé seulement après votre accord, et ne fonctionne que si votre organisation l'autorise - du texte s'ajoute à un document Drive avec
mode: append, car sans cette option le document entier est remplacé
search_api
Trouve des opérations de l'API et les décrit. Il ne renvoie que la documentation de l'API elle-même, jamais de données de votre organisation.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
query | string | non | Des mots-clés, comme link ou log . |
operation_id | string | non | Un id issu d'un résultat de recherche, comme work-items.links.store. |
- Avec
query, il renvoie au plus 12 correspondances sous la forme{id, method, path, summary}, plus unhintpour l'étape suivante. - Avec
operation_id, il décrit cette opération : sa description, le droit nécessaire, les paramètres de chemin, les paramètres de requête, les filtres, les tris, les inclusions, les champs du corps, la fonctionnalité dont elle fait partie, et un ou deux exemples. L'identifiant fonctionne avec ou sans le préfixeapi.v2.. - Sans aucun des deux, il liste tous les identifiants d'opération, regroupés par partie de plnnrly.
Les opérations que votre organisation ne peut pas utiliser sont laissées de côté : celles des parties de plnnrly que votre organisation n'utilise pas, les suppressions tant que Autoriser les actions destructives est désactivé, et l'envoi de fichiers.
api_read
Envoie un GET à n'importe quelle opération de l'API.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
path | string | oui | Le chemin sous /api, avec ses variables remplies, comme work-items. |
query | object | non | Les paramètres de requête, comme {"filter": . |
Chemins et paramètres de requête
- Un chemin vide liste les ressources que propose l'API.
- Le chemin peut commencer par
/api/v2; ce préfixe est ignoré. - Le chemin complet fait au plus 256 caractères. Ses segments n'utilisent que des lettres, des chiffres,
-et_, et chaque variable doit être remplie. - Les chemins des éléments de travail acceptent des clés, comme
work-items/ACM-12. Les filtres sur les utilisateurs acceptentme. - Les objets de requête s'imbriquent sur trois niveaux au plus, comme
filter[due_date][gte], avec 60 paramètres au plus en tout. - Les valeurs nulles sont omises. Les listes deviennent des valeurs séparées par des virgules.
Listes et pagination
Les listes sont renvoyées par pages de 10 dans la vue résumée, sauf si l'appel demande autre chose. Pour obtenir la page suivante, passez le meta.page.next_cursor de la réponse précédente comme cursor. Quand next_cursor vaut null, il n'y a plus de page.
Certaines listes acceptent aussi un numéro de page. Leur meta.page contient toujours current_page et last_page, qui valent null sauf si l'appel envoie page. Un appel qui envoie page reçoit toujours next_cursor: null. La dernière page est celle où current_page atteint last_page.
api_write
Envoie un POST, un PATCH ou un DELETE à n'importe quelle opération de l'API.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
method | string | oui | POST, PATCH ou DELETE. |
path | string | oui | Le chemin sous /api, comme work-items. |
query | object | non | Les paramètres de requête, comme {"view": . |
body | object | non | Le corps JSON, comme {"link_type": . |
confirm | boolean | non | true pour une suppression ou un écrasement, et seulement après votre accord. |
Les règles de chemin et de paramètres de requête de api_read s'appliquent ici aussi. Le corps est vérifié exactement comme l'API REST le vérifie : un champ que l'opération n'accepte pas est refusé nommément, jamais ignoré.
Une suppression exige deux conditions : Autoriser les actions destructives doit être activé pour votre organisation, et l'appel doit inclure confirm: true. S'il en manque une, rien n'est supprimé. Ce qui compte comme une suppression liste les opérations concernées. Sur DELETE /projects/{project}, le paramètre de requête {"force": true} supprime le projet définitivement, au lieu d'une suppression réversible.
Remplacer tout le texte d'un document Drive demande aussi confirm: true, car cela efface la mise en forme et tout ce que d'autres ont tapé depuis que le client a lu le document. Ajouter du texte avec {"mode": "append"} dans le corps ne demande aucune confirmation.
api_write refuse ces appels avant que quoi que ce soit ne s'exécute :
| Refus | Type d'erreur |
|---|---|
| Une suppression tant que Autoriser les actions destructives est désactivé | forbidden-by-policy |
Une suppression ou un écrasement sans confirm: | validation-failed |
| Un envoi de fichier | endpoint-not-found |
| Une méthode que l'opération n'accepte pas | method-not-allowed |
Aucun des deux premiers refus ne lit l'enregistrement avant de refuser : un refus n'indique donc jamais si l'enregistrement existe.
Les écritures via MCP ne sont pas protégées contre les doublons. Un en-tête Idempotency-Key n'est ni nécessaire ni utilisé : un client qui ne sait pas si une écriture a abouti doit relire les données avant de réessayer.
Si l'identification d'une application demandait aussi des autorisations sur l'API REST, l'application reste limitée à ces autorisations via MCP également. Les autorisations obtenues par identification n'incluent jamais la suppression : une telle application ne peut donc pas supprimer via MCP.
get-current-user-tool
Renvoie votre propre profil. Il ne prend aucun paramètre.
{
"id": 34,
"name": "Jamie Doe",
"email": "jamie@acme.example",
"email_verified_at": "2026-02-03T09:15:00+00:00",
"timezone": "Europe/Amsterdam",
"locale": "en",
"job_title": "Project manager",
"date_employed": "2025-09-01",
"roles": ["Project manager"],
"created_at": "2025-08-28T14:02:11+00:00"
}
Les horodatages incluent un décalage de fuseau horaire. date_employed est une date (YYYY-MM-DD). Les champs sans valeur valent null.
Réponses
Une réponse réussie est le corps de réponse de l'API elle-même, avec deux changements :
- Une clé
statusvient en premier, avec le statut HTTP que l'API a renvoyé, comme200ou201. - Chaque objet
linksest retiré. Un client poursuit une liste avecmeta.page.next_cursor, et appelle les autres enregistrements par leur chemin.
La réponse à une suppression n'a pas de corps : l'outil renvoie alors {"status": 204}.
Une réponse peut contenir environ 30 000 caractères. La limite se mesure en octets : une réponse qui contient des accents ou des emojis compte donc un peu moins de caractères. Une réponse plus longue est raccourcie, jamais sans le signaler : meta.mcp_truncated indique ce qui a été coupé. Quand des lignes ont été retirées d'une liste, next_cursor est vidé, car le suivre ferait sauter ces lignes. Le hint explique comment poursuivre la pagination sans rien manquer. Voici l'objet meta d'une liste raccourcie :
{
"page": {
"per_page": 10,
"next_cursor": null,
"prev_cursor": null,
"total": null
},
"mcp_truncated": {
"reason": "response_budget",
"returned": 6,
"omitted": 4,
"hint": "Only the first 6 of 10 rows fit. Repeat this request with per_page=6 (and the same cursor, if any) to page through without gaps."
}
}
Quand c'est un seul long texte qui pose problème, mcp_truncated liste plutôt les champs raccourcis, chacun avec son pointer, le nombre de caractères conservés (kept) et la longueur d'origine (length).
Erreurs
Un appel refusé revient sous forme d'erreur d'outil. Elle contient le même document d'erreur (problem+json) que l'API REST, avec le même statut et le même type ; le guide Erreurs et nouvelles tentatives (en anglais) décrit chaque type. Ce que vous n'avez pas le droit de voir renvoie 404, exactement comme via HTTP.
{
"type": "https://developers.plnnrly.com/api/v2/problems/forbidden-by-policy",
"title": "Forbidden by policy",
"status": 403,
"detail": "This organisation does not allow AI clients to delete data. An administrator can turn on Allow destructive actions under Settings › Administration › MCP & API.",
"instance": "/api/v2/work-items/ACM-12",
"request_id": "01M4WVYY50K7T2B9QH3D6N8RXP"
}
Un chemin ou un paramètre de requête que les outils ne peuvent pas utiliser renvoie l'erreur malformed-request. Son errors[].code vaut invalid (un chemin ou une valeur non autorisés), too_many (plus de 60 paramètres de requête) ou too_deep (plus de trois niveaux d'imbrication).
Limites
- Chaque utilisateur peut envoyer 60 requêtes MCP par minute. Toutes les requêtes que le client envoie au serveur comptent, y compris celles qui établissent la connexion et listent les outils, pas seulement les appels d'outils. Un client qui dépasse la limite reçoit
429. - Les limites de débit et les unités de débit propres à l'API REST ne s'appliquent pas aux appels passés via MCP.
- Une réponse contient au plus environ 30 000 caractères.
- Le client renouvelle son identification toutes les heures. Un client inutilisé pendant 30 jours doit s'identifier de nouveau.
La page Limites en un coup d'œil (en anglais) liste toutes les limites de l'API REST.
Ce que MCP ne permet pas
- Envoyer des fichiers. Ajouter une pièce jointe ou un fichier Drive demande un envoi d'octets que les clients MCP ne savent pas faire. Utilisez l'API REST avec un token API ; voir Fichiers : envoi et téléchargement (en anglais).
- Supprimer tant que le réglage est désactivé. Les suppressions ne fonctionnent que si votre organisation autorise les actions destructives.