Point to a Poppy agent
Some brands support the Personal Agent Protocol, 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
Section titled “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
Section titled “Create the entry”Set type to application/poppy+json and point url at the brand’s well-known Poppy URL:
{ "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"}urlmust behttps://{osd:brandDomain}/.well-known/poppy.json.- Poppy doesn’t define a media type for
poppy.json, so OSD usesapplication/poppy+json.
Publish it with the brand’s other entries
Section titled “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:
{ "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.
Keep poppy.json consistent with the entry
Section titled “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.
{ "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:
{ "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 lists every poppy.json field and the metadata the sign-in server must publish.
Check the entry before connecting
Section titled “Check the entry before connecting”Find and verify the entry as described in Discover support. To search only for Poppy entries, add a type filter to the query:
{ "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:
- Its
organization.domainequals the entry’sosd:brandDomain. - The sign-in server’s metadata has the same
issuerasauth.issuerand lists that domain inpoppy_domains.
If either check fails, don’t use the document. A Poppy-aware assistant also makes the rest of Poppy’s discovery checks.
Connect to the brand
Section titled “Connect to the brand”A Poppy-aware assistant follows the Poppy specification 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.
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.
