Checklist · Poppy · Personal Agent Protocol draft 0.1

The Poppy (PAP) compliance checklist

Every requirement a company must meet to support the Personal Agent Protocol draft 0.1, grouped by what you are building and ordered so you can ship in steps.

The key idea

Ship in four steps. Publish poppy.json, wire up sessions and sign-in in your OAuth server, enforce scopes everywhere, then add interfaces one at a time. Each step is useful on its own.

This checklist turns the requirements a company must meet in Personal Agent Protocol draft 0.1 into steps. Items marked must are required; the rest are the protocol’s recommendations. Anything the checker can test from outside is marked (checked).

Step 1: Be discoverable

  • Must publish /.well-known/poppy.json over https, as JSON. (checked)
  • Must set protocol_version to "0.1". (checked)
  • Must set organization.name, and organization.domain to the host agents request (www. aside). (checked)
  • Must list at least one of web, apis or agent. (checked)
  • Must only redirect the well-known URL to https URLs. (checked)
  • Send HTTP caching headers. (checked)

With "web": {} and nothing else, you are done with step 1: agents can find you and browse signed out. The poppy.json guide has starter files.

Step 2: Sessions and sign-in

  • Must add auth.issuer, an https URL, once you list apis, agent or a browser-session endpoint. (checked)
  • Must publish RFC 8414 metadata at the issuer with the same issuer. (checked)
  • Must list every domain that names the issuer in poppy_domains. (checked)
  • Must publish token_endpoint and revocation_endpoint, plus authorization_endpoint for direct sign-in and device_authorization_endpoint for device sign-in. (checked)
  • Must identify agents by their client_id URL, check its document, and verify private_key_jwt client assertions with its keys.
  • Must start signed-out sessions from the JWT bearer grant, verify the assertion’s iss, aud, expiry and unused jti, and return session_id and signed_in.
  • Must renew a session’s token only for the same agent and user; answer invalid_session when it has ended.
  • Must bind session tokens to the agent’s DPoP key, and accept tokens in the Authorization header without cookies, never in a URL.
  • Must offer at least one of direct, device or mediated sign-in if users should connect accounts, listing each type’s scopes. (checked)
  • Must for direct sign-in: PKCE, an exact redirect_uri match against the agent’s redirect_uris, and iss in every redirect.
  • Must for device sign-in: never approve just because the link was opened.
  • Must for mediated sign-in: rate-limit attempts and never return credentials.
  • Must return the Account Token as a refresh token, accept it only at the token and revocation endpoints and only from its own agent, and never grant more scopes than requested and allowed.
  • Must revoke on sign-out and sign out every session that used the Account Token.
  • Must answer agents’ errors with the protocol’s codes: invalid_client, invalid_grant, invalid_session, account_mismatch, invalid_dpop_proof, use_dpop_nonce, rate_limited. (partly checked)
  • Must answer 429 with Retry-After when you rate-limit an agent.

The OAuth setup guide explains each item and what to do if your provider lacks one.

Step 3: Enforce what users granted

  • Must decide which operations need poppy:read and which need poppy:write, and check each one separately.
  • Must enforce the same scopes on your website, APIs and company agent, including any person at your company who takes over a conversation.
  • Must describe custom scopes in auth.custom_scopes, and keep the poppy: prefix for the protocol’s own. (checked)
  • Give users an account settings page listing connected agents, with Disconnect.
  • Show the agent’s client_id domain, the account and each scope on the consent page.

Step 4: Interfaces

Add these one at a time. Agents prefer APIs and company agents to browsing.

Website

  • Must for browser_session_endpoint: accept a form POST with the agent’s browser assertion, verify it (type, signature, audience, 60-second lifetime, unused jti, active session, return_to on your domain), then set your own Secure, HttpOnly, SameSite=Lax (or None) cookie and redirect with 303. Anything invalid gets 400 and no cookie. (checked)
  • Must make the cookie follow the session’s state and never outlive it.

OpenAPI

  • Must serve an OpenAPI 3.0 or 3.1 description at the listed url. (checked)
  • Must accept DPoP session tokens and answer invalid_token (401), sign_in_required or insufficient_scope (403) in WWW-Authenticate.

MCP

  • Must use Streamable HTTP with MCP 2025-06-18 or later.
  • Must accept Bearer session tokens issued for this server’s URL only, and enforce their scopes. (checked: requires a token)
  • Must publish protected resource metadata (RFC 9728) whose authorization_servers includes your issuer. (checked)

Company agent (conversations)

  • Must serve the conversation API at the listed endpoint: start, send, read events, hand off, close. (checked: requires a token)
  • Must keep each conversation to the agent, user or account that started it; treat retried message IDs as the same message.
  • Must return status and responder on every response, and mark each of your messages sender: agent or human.
  • Must ask for sign-in with an authorization event, and check scopes before every account read or change, whoever is answering.

Optional: the operations extension

For actions with a business effect (an exchange, a booking change, a cancellation): propose an operation with a plain-language summary and fixed terms, issue a new revision when terms change, perform only the confirmed revision, and never perform it twice. List it under extensions with its endpoint, and return operations only to agents that list the extension.

Good practice

  • Let signed-out agents do what signed-out visitors can; limit abuse by rate limits per client_id, user and session.
  • Keep conversation events at least 30 days.
  • Revoke Account Tokens when a user resets their password.
  • Never log tokens, assertions, proofs, codes or credentials.

How long it takes

Step 1 takes an afternoon. Step 2 is most of the work: days if your OAuth server already supports DPoP and the JWT bearer grant, a few weeks if you need a gateway in front of it. Step 3 depends on how many places your product checks permissions. Step 4 is as large as the interfaces you choose; listing an MCP server you already run is the smallest.

Start with the checker to see where you are.

Free Poppy checker

See what your domain needs for the Personal Agent Protocol, one step at a time.

Check your domain

Written against Personal Agent Protocol (Poppy, PAP) draft 0.1, which may change. Flow is not affiliated with the protocol's authors.