# Descubrimiento de servicios

> Cómo los clientes LMSP encuentran un servicio local mediante configuración manual, sondeo de loopback y mDNS/DNS-SD opcional, y cómo leer el documento de descripción del servicio en la dirección conocida.

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

## 3.1 Métodos de descubrimiento {#methods}

Un cliente descubre un servicio probando estos métodos por orden:

1. **Configuración manual.** El usuario introduce directamente la dirección del servicio.
2. **Sondeo de direcciones locales convencionales.** El cliente solicita `/.well-known/lmsp.json` a las direcciones candidatas. Las candidatas convencionales son `http://127.0.0.1:17832` y `http://[::1]:17832`.
3. **Descubrimiento en la LAN.** El cliente explora `_lmsp._tcp.local.` con mDNS y DNS-SD.

Un método tiene éxito cuando produce una descripción de servicio válida ([sección 3.3](https://madeforagent.com/es/lmsp/1.0/discovery.md#service-description)). Una dirección que el usuario haya introducido manualmente siempre tiene prioridad sobre las descubiertas.

## 3.2 Anuncio en la LAN {#mdns}

DNS-SD usa registros PTR para encontrar instancias de servicio, registros SRV para obtener el host y el puerto, y registros TXT para transportar una pequeña cantidad de información adicional. Combinado con mDNS, ofrece descubrimiento sin configuración en una red local ([RFC 6763](https://www.rfc-editor.org/rfc/rfc6763), [RFC 6762](https://www.rfc-editor.org/rfc/rfc6762)).

Un ejemplo de anuncio:

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

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

| Clave TXT | Significado |
| --- | --- |
| `v` | Versión del formato del anuncio. `1` para LMSP 1.0. |
| `id` | El id del servicio, igual a `service.id` en la descripción del servicio. |
| `path` | Ruta URL de la raíz del servicio. Los clientes solicitan `{path}.well-known/lmsp.json`. |
| `auth` | Indicación de autenticación. `pairing` significa que un cliente debe emparejarse antes de usar el servicio. |

Reglas:

- Un servicio **NO DEBE** poner tokens de acceso, listas de modelos, rutas de archivos ni ninguna otra información sensible en el registro TXT. El registro solo localiza el servicio. Las capacidades reales **DEBEN** leerse de la descripción del servicio.
- Un servicio **DEBE** mantener desactivado por defecto el anuncio mDNS. Solo se activa cuando el usuario habilita explícitamente el descubrimiento en la LAN. Un servicio que se usa solo en la máquina local no se anuncia.
- Un servicio que se anuncia en la LAN tiene que escuchar más allá de loopback, algo que solo se permite en modo LAN ([sección 10.5](https://madeforagent.com/es/lmsp/1.0/security.md#lan)).
- Un cliente **DEBE** tratar el registro TXT como una pista sin verificar, y confirmar el servicio leyendo su descripción.

## 3.3 Descripción del servicio {#service-description}

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

Un servicio **DEBE** servir este documento como `application/json` sin exigir autenticación.

```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"
}
```

| Campo | Significado |
| --- | --- |
| `protocol` | Siempre `"lmsp"`. |
| `versions` | Las versiones de LMSP que admite el servicio, como cadenas `major.minor`. |
| `service` | `id` es un identificador estable del servicio, `name` un nombre para mostrar y `version` la versión del software del servicio. |
| `interfaces` | Las interfaces ofrecidas. Cada una tiene un `kind` (`lmsp`, `openai` u `ollama`), una `version`, una `url` base y un `transport`. Para `openai`, `version` nombra las familias de API servidas, como `responses+chat`. |
| `capabilities` | Indicadores booleanos de funciones, enumerados a continuación. |
| `authentication` | `type` es `bearer`. `pairing_url` es donde los clientes canjean un código de emparejamiento por un token ([sección 10.2](https://madeforagent.com/es/lmsp/1.0/security.md#pairing)). |
| `openapi` | URL del documento OpenAPI que describe la interfaz LMSP. |

Indicadores de capacidad:

| Indicador | Significado |
| --- | --- |
| `streaming` | Las respuestas se pueden transmitir como eventos enviados por el servidor. **DEBE** ser `true` en 1.0. |
| `tasks` | Hay tareas asíncronas disponibles. **DEBE** ser `true` en 1.0. |
| `event_resume` | Los flujos de eventos de las tareas se pueden suscribir y reanudar (`GET /lmsp/v1/tasks/{task_id}/events`). |
| `conversations` | El servicio almacena respuestas, por lo que `store` y `previous_response_id` funcionan y `GET /lmsp/v1/responses/{response_id}` está disponible. |
| `model_management` | Los modelos se pueden cargar y liberar de la memoria de forma explícita. |

## 3.4 Comportamiento del cliente {#client-behavior}

Un cliente:

- **DEBERÍA** seleccionar la versión más alta de `versions` que también admita.
- **DEBERÍA** seleccionar la interfaz LMSP o la interfaz OpenAI de `interfaces`, según lo que sepa hablar.
- **DEBE** usar solo las capacidades que declara la descripción. Un indicador ausente significa `false`.
- **DEBE** ignorar los campos de extensión que no reconozca.
- **DEBERÍA** volver a leer la descripción del servicio periódicamente y cuando una solicitud falle, en lugar de conservarla en caché para siempre.
- **DEBERÍA** recordar un servicio elegido por `service.id` y no por su dirección, porque las direcciones pueden cambiar.
