# Découverte de services

> Comment les clients LMSP trouvent un service local par configuration manuelle, sondage de loopback et mDNS/DNS-SD facultatif, et comment lire le document de description de service à l’adresse bien connue.

Source: https://madeforagent.com/fr/lmsp/1.0/discovery/
Language: fr
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 3.1 Méthodes de découverte {#methods}

Un client découvre un service en essayant ces méthodes dans l’ordre :

1. **Configuration manuelle.** L’utilisateur saisit directement l’adresse du service.
2. **Sondage des adresses locales conventionnelles.** Le client demande `/.well-known/lmsp.json` à des adresses candidates. Les candidates conventionnelles sont `http://127.0.0.1:17832` et `http://[::1]:17832`.
3. **Découverte sur le réseau local.** Le client recherche `_lmsp._tcp.local.` avec mDNS et DNS-SD.

Une méthode réussit lorsqu’elle fournit une description de service valide ([section 3.3](https://madeforagent.com/fr/lmsp/1.0/discovery.md#service-description)). Une adresse saisie manuellement par l’utilisateur l’emporte toujours sur celles qui sont découvertes.

## 3.2 Annonce sur le réseau local {#mdns}

DNS-SD utilise des enregistrements PTR pour trouver les instances de service, des enregistrements SRV pour obtenir l’hôte et le port, et des enregistrements TXT pour transporter un peu d’information supplémentaire. Combiné à mDNS, il permet une découverte sans configuration sur un réseau local ([RFC 6763](https://www.rfc-editor.org/rfc/rfc6763), [RFC 6762](https://www.rfc-editor.org/rfc/rfc6762)).

Voici un exemple d’annonce :

```text
Service type:   _lmsp._tcp.local.
Instance name:  Workstation LMSP._lmsp._tcp.local.

TXT record:
  v=1
  id=svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2
  path=/
  auth=pairing
```

| Clé TXT | Signification |
| --- | --- |
| `v` | Version du format d’annonce. `1` pour LMSP 1.0. |
| `id` | L’identifiant du service, égal à `service.id` dans la description du service. |
| `path` | Chemin d’URL de la racine du service. Les clients demandent `{path}.well-known/lmsp.json`. |
| `auth` | Indication d’authentification. `pairing` signifie qu’un client doit s’appairer avant d’utiliser le service. |

Règles :

- Un service **NE DOIT PAS** placer de jetons d’accès, de listes de modèles, de chemins de fichiers ni aucune autre information sensible dans l’enregistrement TXT. L’enregistrement sert seulement à localiser le service. Les capacités réelles **DOIVENT** être lues dans la description du service.
- Un service **DOIT** laisser l’annonce mDNS désactivée par défaut. Elle n’est activée que lorsque l’utilisateur active explicitement la découverte sur le réseau local. Un service utilisé uniquement sur la machine locale ne s’annonce pas.
- Un service qui s’annonce sur le réseau local doit écouter au-delà de loopback, ce qui n’est permis qu’en mode LAN ([section 10.5](https://madeforagent.com/fr/lmsp/1.0/security.md#lan)).
- Un client **DOIT** traiter l’enregistrement TXT comme une indication non vérifiée, et confirmer le service en lisant sa description.

## 3.3 Description du service {#service-description}

```http
GET /.well-known/lmsp.json
```

Un service **DOIT** servir ce document avec le type `application/json`, sans exiger d’authentification.

```json
{
  "protocol": "lmsp",
  "versions": ["1.0"],
  "service": {
    "id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
    "name": "Workstation Local Models",
    "version": "1.0.0"
  },
  "interfaces": [
    {
      "kind": "lmsp",
      "version": "1.0",
      "url": "http://127.0.0.1:17832/lmsp/v1",
      "transport": "http+json"
    },
    {
      "kind": "openai",
      "version": "responses+chat",
      "url": "http://127.0.0.1:17832/v1",
      "transport": "http+json"
    }
  ],
  "capabilities": {
    "streaming": true,
    "tasks": true,
    "event_resume": true,
    "conversations": true,
    "model_management": true
  },
  "authentication": {
    "type": "bearer",
    "pairing_url": "http://127.0.0.1:17832/lmsp/v1/pair"
  },
  "openapi": "http://127.0.0.1:17832/lmsp/v1/openapi.json"
}
```

| Champ | Signification |
| --- | --- |
| `protocol` | Toujours `"lmsp"`. |
| `versions` | Les versions de LMSP prises en charge par le service, sous forme de chaînes `major.minor`. |
| `service` | `id` est un identifiant de service stable, `name` un nom d’affichage et `version` la version du logiciel du service. |
| `interfaces` | Les interfaces proposées. Chacune a un `kind` (`lmsp`, `openai` ou `ollama`), une `version`, une `url` de base et un `transport`. Pour `openai`, `version` nomme les familles d’API servies, comme `responses+chat`. |
| `capabilities` | Indicateurs booléens de fonctionnalités, énumérés ci-dessous. |
| `authentication` | `type` vaut `bearer`. `pairing_url` est l’adresse où les clients échangent un code d’appairage contre un jeton ([section 10.2](https://madeforagent.com/fr/lmsp/1.0/security.md#pairing)). |
| `openapi` | URL du document OpenAPI qui décrit l’interface LMSP. |

Indicateurs de capacité :

| Indicateur | Signification |
| --- | --- |
| `streaming` | Les réponses peuvent être diffusées sous forme d’événements envoyés par le serveur. **DOIT** valoir `true` dans la version 1.0. |
| `tasks` | Les tâches asynchrones sont disponibles. **DOIT** valoir `true` dans la version 1.0. |
| `event_resume` | On peut s’abonner aux flux d’événements des tâches et les reprendre (`GET /lmsp/v1/tasks/{task_id}/events`). |
| `conversations` | Le service stocke les réponses : `store` et `previous_response_id` fonctionnent et `GET /lmsp/v1/responses/{response_id}` est disponible. |
| `model_management` | Les modèles peuvent être chargés et déchargés explicitement. |

## 3.4 Comportement du client {#client-behavior}

Un client :

- **DEVRAIT** sélectionner la version la plus élevée de `versions` qu’il prend lui aussi en charge.
- **DEVRAIT** choisir l’interface LMSP ou l’interface OpenAI dans `interfaces`, selon ce qu’il sait parler.
- **DOIT** utiliser uniquement les capacités que la description déclare. Un indicateur absent signifie `false`.
- **DOIT** ignorer les champs d’extension qu’il ne reconnaît pas.
- **DEVRAIT** relire périodiquement la description du service, ainsi que lorsqu’une requête échoue, au lieu de la mettre en cache indéfiniment.
- **DEVRAIT** mémoriser un service choisi par `service.id` plutôt que par son adresse, car les adresses peuvent changer.
