# Ajouter une compétence à un hub

> Installez, mettez à jour ou retirez une compétence sur un hub depuis l'application, l'API, les SDK, la CLI ou MCP, sans redémarrer le hub.

Source: https://docs.thalovant.com/fr/manage/add-a-skill-to-a-hub/

---
{/* Last Edit: Claude Opus 5.5 - 2026-09-28 - Motive: Canadian French translation of manage/add-a-skill-to-a-hub.mdx. */}

Ouvrez l'onglet Skills d'un hub pour installer une compétence sur le groupe de runtime qui lui est rattaché. Chaque hub qui partage ce groupe reçoit le changement. L'installation s'applique normalement à chaud, sans redémarrer le runtime; suivez son état pour confirmer qu'elle a réussi.

Le même changement tient en un seul appel depuis l'API, les sept SDK gérés, la CLI `thalovant` et le serveur MCP : un agent ou un script peut donc, lui aussi, ajouter une compétence à un hub.

Cette page installe une compétence sur le groupe de runtime derrière un hub. Ouvrez le hub, puis l'onglet **Skills**, puis **Add skill**. C'est terminé quand la ligne indique **installed** et que le hub répond aux phrases de la compétence.

## Compétences de hub et ensembles de compétences

Un [ensemble de compétences](/fr/concepts/skill-sets/) regroupe des compétences que plusieurs hubs partagent. Modifiez l'ensemble de compétences, et chaque hub qui l'utilise change aussi.

Un appel de compétence adressé à un hub résout le groupe de runtime rattaché à ce hub et modifie les compétences rattachées à ce groupe. Ajouter, mettre à jour ou retirer une compétence touche donc chaque hub desservi par le groupe. Utilisez un groupe de runtime distinct quand des hubs ont besoin de compétences installées différentes.

Un hub peut démarrer sans aucune compétence et en gagner un à la fois. Un nouveau hub devient ainsi un appareil vierge que vous remplissez au fur et à mesure, au lieu de devoir choisir un ensemble de compétences complet dès le premier jour.

Les changements s'appliquent à chaud. Le hub prend en compte une compétence ajoutée, mise à jour ou retirée en environ 15 secondes, sans redémarrer.

## Un groupe de runtime, un forfait payant, un jeton

Vérifiez les points suivants :

- le hub appartient à un groupe de runtime (sans groupe, il n'y a pas encore d'onglet **Skills**);
- votre espace de travail est sur un forfait payant, parce qu'ajouter, mettre à jour et retirer des compétences de hub sont des actions payantes;
- pour l'API, les SDK, la CLI ou MCP, vous avez un [jeton d'API](/fr/account/api-tokens/) avec `hubs:write`, ou `hubs:inspect` pour lister seulement (`hubs:read` l'inclut); un jeton restreint doit couvrir chaque hub qui partage le groupe de runtime touché;
- vous connaissez l'**id** du hub, et non son slug, quand vous travaillez depuis du code.

## Ajouter une compétence dans l'application

1. Ouvrez le hub depuis **Hubs**.
2. Ouvrez l'onglet **Skills**.
3. Choisissez **Add skill**.
4. Choisissez la compétence et une version. **Latest** est la valeur par défaut.
5. Confirmez. La ligne affiche l'état de l'installation jusqu'à ce qu'elle se stabilise sur **installed**.

Chaque ligne offre **Update** et **Remove**. **Update** vous laisse choisir une version; **Remove** retire la compétence de l'ensemble de compétences rattaché, ce qui touche chaque hub qui l'utilise. Les deux s'appliquent normalement pendant que le runtime continue de tourner, et affichent leur progression sur la ligne.

  Rien ne redémarre. Ajoutez la première compétence à un hub vide, essayez-la, puis ajoutez la suivante.

## Depuis l'API et les SDK

Chaque appel désigne le hub par son id. Ces routes n'acceptent pas les slugs. L'installation, la mise à jour et le retrait répondent HTTP 202 avec un `operation_id`; le changement est ensuite appliqué sur le hub pendant que vous interrogez l'opération ou attendez.

### Appeler l'API

Lister les compétences d'un hub :

```bash
curl --fail-with-body \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  "https://api.thalovant.com/v1/hubs/$HUB_ID/skills"
```

```json
{
  "hub_id": "8d1c2f4e-5b6a-4c7d-9e8f-0a1b2c3d4e5f",
  "runtime_group_id": "3f9a7b21-6c4d-4e8f-a1b2-c3d4e5f60718",
  "observed_at": "2026-09-09T14:02:11Z",
  "source": "runtime",
  "data": [
    {
      "skill": "skill-weather",
      "title": "Weather",
      "marketplace_skill_id": "b7e2c9d0-1f3a-4b5c-8d6e-7f8091a2b3c4",
      "package_name": "thalovant-skill-weather",
      "source_type": "catalog",
      "install_source": "marketplace",
      "version": "1.1.0",
      "version_pin": "1.1.0",
      "installed_version": "1.1.0",
      "observed_version": "1.1.0",
      "previous_version": "1.0.4",
      "latest_version": "1.2.0",
      "available_version": "1.2.0",
      "update_available": true,
      "changelog": "Adds hourly forecasts.",
      "active": true,
      "state": "installed",
      "last_transition_at": "2026-09-09T14:02:11Z"
    }
  ]
}
```

Les lignes se trouvent sous `data`, un tableau vide quand rien n'est installé de cette façon. `observed_at` et `source` indiquent quand et d'où la liste a été observée pour la dernière fois. L'enveloppe et chaque ligne portent aussi les champs de phase, de message et de dernière erreur du runtime, omis de l'exemple ci-dessus; ils valent `null` quand le runtime n'a rien à signaler. `installed_version` est ce qui tourne, `version_pin` est ce que vous avez demandé, et `update_available` vaut true quand une version plus récente existe.

Le `state` de chaque ligne prend l'une de ces valeurs :

| État | Signification |
| --- | --- |
| `pending` | Un changement est en cours. L'installation, la mise à jour et le retrait affichent tous cet état jusqu'à ce que le changement soit appliqué. |
| `installed` | La compétence tourne à la version demandée. |
| `failed` | Le runtime n'a pas pu installer ni mettre à jour la compétence. Son champ de dernière erreur en donne la raison. |
| `removing` | La compétence est en train d'être retirée. |
| `drifted` | La version qui tourne diffère de celle qui a été demandée. |
| `quarantined` | Le runtime a désactivé la compétence après des échecs répétés. |
| `unmanaged` | La compétence tourne, mais n'est pas gérée par cette route. |

Installer une compétence. `version` est toujours envoyé et vaut `latest` par défaut :

```bash
curl --fail-with-body -X POST \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"skill": "skill-weather", "version": "latest"}' \
  "https://api.thalovant.com/v1/hubs/$HUB_ID/skills"
```

```json
{
  "operation_id": "op_01J9Q0S2M5H8ZC3VQK7T1XB4RD",
  "hub_id": "8d1c2f4e-5b6a-4c7d-9e8f-0a1b2c3d4e5f",
  "runtime_group_id": "3f9a7b21-6c4d-4e8f-a1b2-c3d4e5f60718",
  "skill": "skill-weather",
  "version": "latest",
  "previous_version": null,
  "state": "installing"
}
```

Envoyer une compétence déjà installée à une autre version effectue une mise à jour, et `previous_version` porte alors la version remplacée. Envoyer la même version répond HTTP 409.

Mettre à jour vers une version précise. `version` est obligatoire ici :

```bash
curl --fail-with-body -X PATCH \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"version": "1.2.0"}' \
  "https://api.thalovant.com/v1/hubs/$HUB_ID/skills/skill-weather"
```

Retirer la compétence :

```bash
curl --fail-with-body -X DELETE \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  "https://api.thalovant.com/v1/hubs/$HUB_ID/skills/skill-weather"
```

```json
{
  "operation_id": "op_01J9Q0T7NA2KX4D9RW6PZ8E3HM",
  "hub_id": "8d1c2f4e-5b6a-4c7d-9e8f-0a1b2c3d4e5f",
  "runtime_group_id": "3f9a7b21-6c4d-4e8f-a1b2-c3d4e5f60718",
  "skill": "skill-weather",
  "version": null,
  "previous_version": "1.2.0",
  "state": "removing"
}
```

La mise à jour répond avec un corps de même forme et `"state": "updating"`. Chaque écriture a son propre `operation_id`. Interrogez cette opération jusqu'à ce qu'elle soit `ready`, `failed` ou `timed_out` :

```bash
curl --fail-with-body \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  "https://api.thalovant.com/v1/operations/$OPERATION_ID"
```

`ready` signifie que le hub a convergé : la compétence est `installed` après une installation ou une mise à jour, et absent après un retrait. Consultez [Opérations](/fr/developers/operations/) pour la séquence d'états complète.

### Utiliser un SDK ou la CLI

Les sept SDK gérés prennent en charge la gestion et l'historique des compétences de hub. Utilisez Python `0.6.0`, Node.js `0.4.0`, Go et Rust `0.6.0`, ou Kotlin, Swift et .NET `0.4.0`. Passez `wait` pour interroger toutes les 2 secondes, avec un budget d'interrogation de 120 secondes par défaut. Aucune nouvelle lecture d'état ne commence à cette échéance ou après; l'échéance d'interrogation n'annule pas une requête déjà en cours. Une lecture d'état qui échoue conserve l'identifiant de l'opération acceptée : reprenez l'interrogation de cette opération au lieu de soumettre l'écriture de nouveau. La CLI `thalovant` est livrée avec le SDK Python et lit `THALOVANT_API_TOKEN`.

  

```python

from thalovant import ThalovantControlPlane

api = ThalovantControlPlane(access_token=os.environ["THALOVANT_API_TOKEN"])

skills = api.list_hub_skills("hub-id")  # HubSkillList
print(skills.source, skills.observed_at)
for skill in skills.data:
    print(skill.skill, skill.installed_version, skill.state, skill.update_available)

result = api.install_hub_skill("hub-id", "skill-weather", version="latest", wait=True)
print(result.state)  # installed

api.update_hub_skill("hub-id", "skill-weather", version="1.2.0", wait=True)
api.remove_hub_skill("hub-id", "skill-weather", wait=True)
```

  
  

```ts

const api = new ThalovantControlPlane(undefined, {
  accessToken: process.env.THALOVANT_API_TOKEN,
});

const skills = await api.listHubSkills("hub-id"); // { data, source, observed_at, ... }
console.log(skills.source, skills.observed_at);
for (const skill of skills.data) {
  console.log(skill.skill, skill.installed_version, skill.state, skill.update_available);
}

const result = await api.installHubSkill("hub-id", "skill-weather", { version: "latest", wait: true });
console.log(result.state); // installed

await api.updateHubSkill("hub-id", "skill-weather", { version: "1.2.0", wait: true });
await api.removeHubSkill("hub-id", "skill-weather", { wait: true });
```

  
  

```bash
export THALOVANT_API_TOKEN="tvpat_..."

thalovant skills list --hub <hub-id>
thalovant skills add --hub <hub-id> skill-weather --version latest --wait
thalovant skills update --hub <hub-id> skill-weather --version 1.2.0
thalovant skills remove --hub <hub-id> skill-weather

# Machine-readable output for scripts:
thalovant --json skills list --hub <hub-id>
```

  

L'appel de liste renvoie la même enveloppe que la route : `HubSkillList` en Python et `{ data, source, observed_at, ... }` en Node.js, avec les lignes sous `data`. Chaque écriture renvoie l'opération acceptée avec `operation_id`, `skill`, `version`, `previous_version` et `state`. Sans `wait`, l'installation, la mise à jour et le retrait répondent immédiatement, et vous interrogez l'opération avec `get_operation` ou `getOperation`. Go, Rust, Kotlin, Swift et .NET offrent des appels et des fonctions de reprise équivalents; consultez les [guides par langage](/fr/developers/sdks/). Lisez l'historique du runtime partagé avec `list_hub_skill_history(hub_id, limit=50)` en Python ou `listHubSkillHistory(hubId, { limit: 50 })` en Node. La limite est un entier de 1 à 200.

### Utiliser le serveur MCP

À partir de MCP `0.1.23`, le [serveur MCP](/fr/developers/mcp/) expose les quatre mêmes actions sous forme d'outils : `thalovant_list_hub_skills`, `thalovant_install_hub_skill`, `thalovant_update_hub_skill` et `thalovant_remove_hub_skill`. Les quatre prennent `hubId`; les trois outils d'écriture prennent aussi `skill`, ainsi que `version`, `wait` et `timeoutMs` quand l'action en a besoin. Les trois outils d'écriture exigent `hubs:write` et sont masqués en mode lecture seule. MCP `0.2.0` utilise le SDK Node `0.4.0` et ajoute l'outil en lecture seule `thalovant_list_hub_skill_history`, avec un `limit` entier facultatif de 1 à 200. Les échecs d'interrogation conservent l'identifiant de l'opération acceptée.

## En cas d'échec

Les erreurs reviennent sous forme de JSON de problème RFC 7807, avec `code` et `message` à la racine du corps. Les SDK Python et Node.js placent les deux dans le texte de l'erreur sous la forme `HTTP <status>: <message> (<code>)`, par exemple `HTTP 409: Skill version already installed. (skill_version_already_installed)`; l'erreur n'a pas encore d'attribut de code distinct.

| Réponse | Ce que ça signifie | Quoi faire |
| --- | --- | --- |
| HTTP 402 | L'espace de travail est sur le forfait Free. La vérification du forfait passe avant celle de la portée : un appel sur le forfait Free aboutit donc toujours ici, jamais à 403. | Passez l'espace de travail à un forfait supérieur, puis réessayez. La liste fonctionne toujours. |
| HTTP 403 | Le forfait est payant, mais le jeton ne porte pas `hubs:write`. | Créez un jeton avec `hubs:write` sur la [page API Tokens](/fr/account/api-tokens/). |
| HTTP 404, `hub_without_runtime_group` | Le hub n'est pas encore dans un groupe de runtime. | Ajoutez-le à un groupe de runtime, puis réessayez. |
| HTTP 404 sans `code` | L'id est inconnu, ou la compétence n'y est pas installée. | Vérifiez que vous avez passé l'id et non le slug, puis listez les compétences installées. |
| HTTP 409, `skill_version_already_installed` | Le hub a déjà cette compétence à cette version. | Rien à faire, ou choisissez une autre version. |
| HTTP 422 | `latest` n'a pas pu être résolu en une version, ou la chaîne de version est invalide. | Passez une version que la compétence publie, comme `1.2.0`. |
| État `failed` | Le runtime n'a pas pu installer ni mettre à jour la compétence. | Lisez l'erreur sur la ligne, le champ de dernière erreur de la ligne ou le `error_message` de l'opération; corrigez la cause et réessayez. Le reste du hub continue de tourner. |

Une compétence qui reste à `pending` bien au-delà de 15 secondes signifie habituellement que le hub lui-même n'est pas en bonne santé. Vérifiez son état en direct dans [Hubs](/fr/concepts/hubs/) avant de réessayer.

## La compétence est prête quand

- la ligne affiche **installed** et la version que vous avez choisie;
- `GET /v1/hubs/$HUB_ID/skills` le liste sous `data` avec `"state": "installed"`;
- l'opération indique `ready`;
- le hub répond aux intentions de la compétence.

## Publier une version de votre compétence

Pour installer de cette façon une compétence que vous avez écrite, il lui faut une version publiée. Les auteurs de compétences en publient une avec un `POST` multipart vers `/v1/marketplace/skills/{id}/versions`, avec les champs `version` et `channel`, un `changelog` facultatif et le wheel construit comme partie de fichier `wheel` :

```bash
curl --fail-with-body -X POST \
  -H "Authorization: Bearer $THALOVANT_API_TOKEN" \
  -F "version=1.2.0" \
  -F "channel=stable" \
  -F "changelog=Adds hourly forecasts." \
  -F "wheel=@dist/thalovant_skill_weather-1.2.0-py3-none-any.whl" \
  "https://api.thalovant.com/v1/marketplace/skills/$SKILL_ID/versions"
```

Un téléversement réussi renvoie HTTP 201 avec l'ID de la compétence, le nom du paquet, la version, le canal et la somme de contrôle. Vous pouvez ensuite choisir cette version au moment d'installer ou de mettre à jour la compétence.

Pour écrire votre première compétence, suivez le [tutoriel Pocket Quiz](/fr/developers/skillkit-tutorial/). Pour l'installer directement depuis votre propre dépôt Git ou un paquet Python, suivez [Ajouter votre propre compétence](/fr/manage/add-your-own-skill/).

## Étape suivante

Pour créer le hub et son runtime depuis du code, consultez [Provisionner des hubs](/fr/developers/provisioning/), et pour comprendre le fonctionnement des ensembles de compétences partagés, consultez [Les compétences](/fr/concepts/skill-sets/).

Les compétences rattachées appartiennent au groupe de runtime du hub sélectionné. Chaque hub qui partage
ce groupe reçoit le changement; un jeton restreint doit couvrir tous les hubs desservis.
