# Service discovery

> How LMSP clients find a local service through manual configuration, loopback probing and optional mDNS/DNS-SD, and how to read the well-known service description document.

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

## 3.1 Discovery methods {#methods}

A client discovers a service by trying these methods in order:

1. **Manual configuration.** The user enters the service address directly.
2. **Probing conventional local addresses.** The client requests `/.well-known/lmsp.json` from candidate addresses. The conventional candidates are `http://127.0.0.1:17832` and `http://[::1]:17832`.
3. **LAN discovery.** The client browses for `_lmsp._tcp.local.` with mDNS and DNS-SD.

A method succeeds when it yields a valid service description ([section 3.3](https://madeforagent.com/lmsp/1.0/discovery.md#service-description)). An address the user entered manually always takes precedence over discovered ones.

## 3.2 LAN advertisement {#mdns}

DNS-SD uses PTR records to find service instances, SRV records to get the host and port, and TXT records to carry a small amount of extra information. Combined with mDNS it provides zero-configuration discovery on a local network ([RFC 6763](https://www.rfc-editor.org/rfc/rfc6763), [RFC 6762](https://www.rfc-editor.org/rfc/rfc6762)).

An example advertisement:

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

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

| TXT key | Meaning |
| --- | --- |
| `v` | Version of the advertisement format. `1` for LMSP 1.0. |
| `id` | The service id, equal to `service.id` in the service description. |
| `path` | URL path of the service root. Clients request `{path}.well-known/lmsp.json`. |
| `auth` | Authentication hint. `pairing` means a client must pair before using the service. |

Rules:

- A service **MUST NOT** put access tokens, model lists, file paths or any other sensitive information in the TXT record. The record only locates the service. Real capabilities **MUST** be read from the service description.
- A service **MUST** keep mDNS advertisement disabled by default. It is enabled only when the user explicitly turns on LAN discovery. A service used only on the local machine does not advertise.
- A service that advertises on the LAN has to listen beyond loopback, which is only allowed in LAN mode ([section 10.5](https://madeforagent.com/lmsp/1.0/security.md#lan)).
- A client **MUST** treat the TXT record as an unverified hint, and confirm the service by reading its description.

## 3.3 Service description {#service-description}

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

A service **MUST** serve this document as `application/json` without requiring authentication.

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

| Field | Meaning |
| --- | --- |
| `protocol` | Always `"lmsp"`. |
| `versions` | The LMSP versions the service supports, as `major.minor` strings. |
| `service` | `id` is a stable service identifier, `name` a display name, and `version` the version of the service software. |
| `interfaces` | The interfaces on offer. Each has a `kind` (`lmsp`, `openai` or `ollama`), a `version`, a base `url` and a `transport`. For `openai`, `version` names the API families served, such as `responses+chat`. |
| `capabilities` | Boolean feature flags, listed below. |
| `authentication` | `type` is `bearer`. `pairing_url` is where clients exchange a pairing code for a token ([section 10.2](https://madeforagent.com/lmsp/1.0/security.md#pairing)). |
| `openapi` | URL of the OpenAPI document that describes the LMSP interface. |

Capability flags:

| Flag | Meaning |
| --- | --- |
| `streaming` | Responses can be streamed as server-sent events. **MUST** be `true` in 1.0. |
| `tasks` | Asynchronous tasks are available. **MUST** be `true` in 1.0. |
| `event_resume` | Task event streams can be subscribed to and resumed (`GET /lmsp/v1/tasks/{task_id}/events`). |
| `conversations` | The service stores responses, so `store` and `previous_response_id` work and `GET /lmsp/v1/responses/{response_id}` is available. |
| `model_management` | Models can be loaded and unloaded explicitly. |

## 3.4 Client behavior {#client-behavior}

A client:

- **SHOULD** select the highest version in `versions` that it also supports.
- **SHOULD** select the LMSP interface or the OpenAI interface from `interfaces`, according to what it can speak.
- **MUST** use only the capabilities the description declares. A missing flag means `false`.
- **MUST** ignore extension fields it does not recognize.
- **SHOULD** re-read the service description periodically and when a request fails, instead of caching it forever.
- **SHOULD** remember a chosen service by `service.id` rather than by address, because addresses can change.
