# Point to a Poppy agent

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 discovery requires the assistant to know the brand's domain. OSD fills that gap: a registry search by brand name or support need discovers candidate brand domains and support entries. The assistant selects the intended brand, checks that its manifest endorses the selected entry, and follows the entry to `poppy.json`.

## How OSD and Poppy divide the work

| Question | Answered by |
| --- | --- |
| How can the assistant discover brand domains and support listings from a brand name or support need? | OSD registry search |
| Which candidate matches the business the customer means? | The assistant, using the customer's context and its host's trust policy |
| Does that business endorse this listing? | OSD: compare the complete candidate entry with the intended 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://openservicedirectory.org/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://openservicedirectory.org/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://openservicedirectory.org/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](/0.3.0/docs/guides/publish-a-support-agent/).

## 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](/0.3.0/docs/guides/discover-support/). 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.