Personal Agent Protocol 0.1

Let personal agents use your site.

Poppyseed implements the Poppy protocol in Next.js. Describe your tools and add one route: agents find your site, sign people in with their consent, and buy only what they approve.

npm install poppyseed zod
Quickstart
import { definePoppyseed, memoryStore, tool } from "poppyseed";import { z } from "zod";export const poppyseed = definePoppyseed({  organization: { name: "Seed Café", domain: "seed.cafe" },  secret: process.env.POPPYSEED_SECRET!,  store: memoryStore(),  tools: {    menu: tool({      description: "Drinks on the menu today",      scope: null, // anyone, signed in or not      input: z.object({ size: z.enum(["small", "large"]) }),      run: ({ size }) => ({ drinks: menu(size) }),    }),  },});
app/api/poppyseed/[...path]/route.ts
import { toNextHandlers } from "poppyseed/next";import { poppyseed } from "@/poppyseed.config";export const dynamic = "force-dynamic";export const { GET, POST, DELETE } = toNextHandlers(poppyseed);
import { withPoppyseed } from "poppyseed/next/config";// Only /.well-known/poppy.json, /oauth/*, /mcp and /poppy/*// go to Poppyseed. Every other URL stays yours.export default withPoppyseed({});
personal agent
$ npx poppyseed-agent http://localhost:3000 menu
▸ discovered Seed Café
▸ signed-out DPoP session
▸ MCP and OpenAPI: 1 tool
▸ called menu
{
  "drinks": [{ "Flat white", 4.2 }]
}
  • /.well-known/poppy.json discovery
  • /oauth/token agent sign-in, DPoP
  • /mcp + /poppy/openapi.json your tools

Grows with you

Start with one tool. Switch on the rest.

Each feature of the protocol is a few lines in the same config. Pick one and watch what it adds.

FeaturesEvery feature, in the guides →
poppyseed.config.ts
export const poppyseed = definePoppyseed({  organization: { name: "Poppy Travel", domain: "poppy.travel" },  secret: process.env.POPPYSEED_SECRET!,  store: memoryStore(),  store: postgresStore(pool),  accounts: { current: yourLogin, signInUrl: (to) => `/login?return_to=${to}` },  signIn: { device: { scopes: ["poppy:read", "poppy:write"] } },  conversations: { agent: claudeAgent({ instructions: "Help travelers." }) },  tools: {    search_flights: tool({      description: "Search one-way flights",      scope: null,      input: z.object({ from: z.string(), to: z.string(), date: z.iso.date() }),      run: (input) => ({ offers: searchFlights(input) }),    }),    my_trips: tool({      description: "Your upcoming trips",      scope: "poppy:read",      input: z.object({}),      run: (_, ctx) => ({ trips: tripsOf(ctx.account.id) }),    }),    book_flight: tool({      description: "Book a flight offer",      scope: "poppy:write",      input: z.object({ offer_id: z.string() }),      operation: {        propose: ({ offer_id }) => quote(offer_id), // { summary, terms }        perform: ({ id, terms }, ctx) => book(ctx.account.id, terms, id),      },    }),  },});

See it work

A real agent books a trip on this site

This site also runs Poppy Travel, a demo company built with Poppyseed. Run the agent: it discovers the company, signs Maya in with a device code, proposes a flight, books it once she approves, and asks support about it, through the real endpoints.

A real personal agent, against this site's real protocol endpoints.

    Verified

    Checked against every rule of the spec

    Every rule of PAP 0.1 is a numbered requirement, and a conformance suite checks them over HTTP through a real Next.js server. Each check is proven by breaking its rule on purpose and watching it fail. Run it against your own site.

    98checks pass over HTTP
    147spec rules they verify
    100%fail when their rule breaks
    npx poppyseed-conformance https://your.site

    FAQ

    Questions

    What is the Poppy protocol?

    The Personal Agent Protocol: an open protocol for personal agents, assistants that act for one person, to work with sites. A site publishes /.well-known/poppy.json, and agents use it to find the site's tools, sign the person in with their consent, and get the person's approval before anything costs money. Poppyseed implements the site's side.

    Do I need an AI model?

    No. Tools, sign-in and approvals are plain code. Only conversations need a Company Agent, and that can be claudeAgent() or your own function.

    Which agents can use my site?

    Any personal agent that speaks the protocol. While you build, poppyseed-agent plays one from your terminal: npx poppyseed-agent http://localhost:3000.

    Where does it run?

    Any Next.js 15 App Router deployment. On serverless or several instances, use postgresStore() so every instance shares Sessions and approvals.

    Ready for personal agents by this afternoon.

    npm install poppyseed zod
    Quickstart