# Point to a Poppy agent

> List a brand that supports the Personal Agent Protocol (Poppy) by pointing an OSD entry at the brand's poppy.json document.

Some brands support the [Personal Agent Protocol](https://personalagentprotocol.org/), called Poppy for short. A Poppy brand publishes a `poppy.json` document on its domain. The document tells assistants how to start a session, how customers sign in, and which APIs and support agent the brand offers.

Poppy starts from a domain the assistant already knows and doesn't say how the assistant finds it. With OSD, a registry search returns the brand's entry, the brand's own manifest confirms it, and the entry points at `poppy.json`. 

## How OSD and Poppy divide the work

| Question | Answered by |
| --- | --- |
| Which domain belongs to the brand the customer means, and does the brand endorse this listing? | OSD: registry search and the brand's `/.well-known/ard.json` |
| Which sign-in server, APIs, and support agent does that domain offer? | Poppy: the brand's `/.well-known/poppy.json` |
| Is that sign-in server allowed to act for the domain? | Poppy: `poppy_domains` in the sign-in server's metadata |


## Create the entry

Set `type` to `application/poppy+json` and point `url` at the brand's well-known Poppy URL:

```json
{
  "identifier": "urn:air:airline.example:support:poppy",
  "displayName": "Example Air Support",
  "description": "Support for cancelled flights and rebooking through the Personal Agent Protocol.",
  "representativeQueries": ["My flight was cancelled", "Help me rebook my flight"],
  "type": "application/poppy+json",
  "url": "https://airline.example/.well-known/poppy.json",
  "@context": { "osd": "https://opensupport.directory/ns#" },
  "osd:brandName": "Example Air",
  "osd:brandDomain": "airline.example"
}
```

- `url` must be `https://{osd:brandDomain}/.well-known/poppy.json`.
- Poppy doesn't define a media type for `poppy.json`, so OSD uses `application/poppy+json`.

## Publish it with the brand's other entries

Add the entry to the brand's manifest at `https://airline.example/.well-known/ard.json`. A brand can list a Poppy entry next to an MCP Server Card entry, so assistants without Poppy support can still connect:

```json
{
  "entries": [
    {
      "identifier": "urn:air:airline.example:support:assistant",
      "displayName": "Example Air Support",
      "description": "Support for cancelled flights and rebooking.",
      "representativeQueries": ["My flight was cancelled", "Help me rebook my flight"],
      "type": "application/mcp-server-card+json",
      "url": "https://support.airline.example/server-card.json",
      "@context": { "osd": "https://opensupport.directory/ns#" },
      "osd:brandName": "Example Air",
      "osd:brandDomain": "airline.example"
    },
    {
      "identifier": "urn:air:airline.example:support:poppy",
      "displayName": "Example Air Support",
      "description": "Support for cancelled flights and rebooking through the Personal Agent Protocol.",
      "representativeQueries": ["My flight was cancelled", "Help me rebook my flight"],
      "type": "application/poppy+json",
      "url": "https://airline.example/.well-known/poppy.json",
      "@context": { "osd": "https://opensupport.directory/ns#" },
      "osd:brandName": "Example Air",
      "osd:brandDomain": "airline.example"
    }
  ]
}
```

Validate the manifest and submit the entries to registries without changing them, as described in [Publish a support agent](https://docs.openservicedirectory.org/guides/publish-a-support-agent.md).

## Keep poppy.json consistent with the entry

For the assistant's checks to pass, the brand's `poppy.json` must name the same domain as the entry's `osd:brandDomain`. 

```json
{
  "protocol_version": "0.1",
  "organization": { "name": "Example Air", "domain": "airline.example" },
  "auth": {
    "issuer": "https://auth.airline.example",
    "direct": { "scopes": ["poppy:read", "poppy:write"] }
  },
  "agent": {
    "protocols": [
      { "type": "poppy", "endpoint": "https://api.airline.example/poppy/conversations" }
    ]
  },
  "apis": [
    {
      "type": "mcp",
      "url": "https://mcp.airline.example/mcp",
      "description": "Bookings, cancellations, and rebooking"
    }
  ]
}
```

The sign-in server named in `auth.issuer` publishes OAuth metadata at `https://auth.airline.example/.well-known/oauth-authorization-server`. Its `poppy_domains` array must include `airline.example`:

```json
{
  "issuer": "https://auth.airline.example",
  "authorization_endpoint": "https://auth.airline.example/oauth/authorize",
  "token_endpoint": "https://auth.airline.example/oauth/token",
  "revocation_endpoint": "https://auth.airline.example/oauth/revoke",
  "poppy_domains": ["airline.example"]
}
```

Poppy's [discovery section](https://personalagentprotocol.org/docs/spec#discovery) lists every `poppy.json` field and the metadata the sign-in server must publish.

## Check the entry before connecting

Find and verify the entry as described in [Discover support](https://docs.openservicedirectory.org/guides/discover-support.md). To search only for Poppy entries, add a `type` filter to the query:

```json
{
  "text": "Example Air cancelled flight rebooking",
  "filter": { "type": "application/poppy+json" }
}
```

A registry that doesn't support the filter returns an error.

The brand's endorsement covers the entry, not the contents of `poppy.json`. Before using the document, confirm two things:

1. Its `organization.domain` equals the entry's `osd:brandDomain`.
2. The sign-in server's metadata has the same `issuer` as `auth.issuer` and lists that domain in `poppy_domains`.

If either check fails, don't use the document. A Poppy-aware assistant also makes the rest of Poppy's [discovery checks](https://personalagentprotocol.org/docs/spec#discovery).

## Connect to the brand

A Poppy-aware assistant follows the [Poppy specification](https://personalagentprotocol.org/docs/spec#sessions) from here. It identifies itself, starts a session, signs the customer in, and uses the brand's APIs or support agent. The support agent uses Poppy's own [conversation protocol](https://personalagentprotocol.org/docs/spec#conversations).

An assistant without Poppy support can still use an MCP server listed in `apis`. Poppy lets a plain MCP client sign in with MCP's own authorization flow, and the brand treats that sign-in as a new signed-in session. The client doesn't get Poppy's signed-out sessions or a conversation with the support agent.
