« Aucun résultat trouvé pour cette recherche » : ce message, minimal et sans piste de correction, s’affichait initialement dans l’interface de recherche interne d’un site de presse locale, avant que l’équipe technique ne décide d’exposer cette recherche comme une capacité déclarée via l’Abilities API de WordPress, disponible depuis l’été 2025 avec la sortie de WordPress 6.9.
Le site publiait déjà plusieurs centaines d’articles par an, organisés par commune et par thématique. L’objectif de ce chantier : permettre à un agent de recherche interne, utilisable depuis l’interface d’administration comme depuis certains outils compatibles MCP, d’interroger le contenu du site de façon structurée, tout en gardant un retour utilisateur clair côté interface publique pour la recherche classique.
Étape 1 : déclarer la capacité avec un résultat structuré
La capacité, enregistrée avec la fonction wp_register_ability(), renvoie un tableau structuré plutôt qu’un simple texte, ce qui permet à l’interface de distinguer le contenu du résultat de son état (succès, aucun résultat, erreur).
wp_register_ability( 'presse-locale/rechercher-articles', array(
'label' => __( 'Rechercher des articles', 'presse-locale' ),
'description' => __( 'Recherche des articles par commune et par thématique.', 'presse-locale' ),
'input_schema' => array(
'type' => 'object',
'properties' => array(
'commune' => array( 'type' => 'string' ),
'thematique' => array( 'type' => 'string' ),
),
),
'execute_callback' => 'presse_locale_rechercher_articles',
'permission_callback' => '__return_true',
) );
La fonction de rappel presse_locale_rechercher_articles renvoie systématiquement trois champs : la liste des articles trouvés, un compteur de résultats, et un champ etat qui vaut succes, vide ou erreur selon le cas.
Étape 2 : relier la capacité à un retour d’interface annoncé
Côté interface publique, le champ de recherche existant a été relié à cette capacité via une requête vers le point de terminaison REST associé, et le champ etat renvoyé détermine le message affiché et annoncé dans une région dédiée.
<div id="etat-recherche" aria-live="polite"></div>
fetch('/wp-json/abilities/v1/presse-locale/rechercher-articles', options)
.then((reponse) => reponse.json())
.then((donnees) => {
const region = document.getElementById('etat-recherche');
if (donnees.etat === 'vide') {
region.textContent =
'Aucun article trouvé pour cette commune. Essayez une thématique plus large.';
} else if (donnees.etat === 'erreur') {
region.textContent =
'La recherche a échoué. Réessayez dans un instant.';
} else {
region.textContent = `${donnees.compteur} article(s) trouvé(s).`;
}
});

Étape 3 : soigner le message d’absence de résultat autant que le succès
Le message « aucun résultat trouvé » d’origine ne proposait aucune piste : ni suggestion de thématique voisine, ni invitation à élargir la recherche. Avec la capacité désormais structurée, ce message a été enrichi pour suggérer une thématique proche, calculée côté serveur à partir des mots-clés les plus proches trouvés dans les articles existants.
- Le message d’absence de résultat propose systématiquement une piste concrète, jamais un simple constat d’échec.
- Le message d’erreur technique reste distinct du message d’absence de résultat, pour ne pas laisser croire à un problème de saisie quand il s’agit d’un problème serveur.
- Le compteur de résultats trouvés est toujours annoncé, même à zéro, pour confirmer que la recherche s’est bien exécutée.
Ce que cette étape ne couvre pas encore
La sécurisation du point de terminaison, en particulier la vérification des permissions selon le contexte d’appel (interface publique ou outil compatible MCP authentifié), relève d’un chantier distinct mené en parallèle et volontairement laissé hors du périmètre de cette étape, centrée uniquement sur le retour utilisateur.
Une capacité qui renvoie un état structuré plutôt qu’un simple texte libre permet à l’interface de choisir le bon message au bon moment, sans deviner le sens d’une chaîne de caractères imprévisible.
En résumé
Trois champs structurés, dont un champ d’état dédié, ont suffi à transformer une recherche interne au retour minimal en une expérience qui annonce clairement son résultat via une région live, qu’il s’agisse d’un succès, d’une absence de résultat ou d’une erreur technique. Décrire une capacité d’agent avec cette rigueur dès le départ facilite ensuite sa réutilisation, aussi bien par l’interface publique du site que par un outil externe compatible MCP.