Quickstart
A dense one-pager. Install. Five CLI commands. Two library shapes. Three publisher adapters. No tutorial — copy what you need, the names are stable across v0.
§ 01Install
# bun (preferred — runtime + bundler in one) $ bun add agent-feed # or with npm / pnpm / yarn $ npm i agent-feed $ pnpm add agent-feed $ yarn add agent-feed # python $ pip install agent-feed $ uv add agent-feed
§ 02Your first feed, in three commands
The shortest path from "i run a thing" to a signed, well-known
agent-feed.xml. --from-corpus
pre-fills from whatever the public world already says about you.
$ bunx agent-feed init --from-corpus example.com # reviewing 3 observations · drafting agent-feed.xml $ bunx agent-feed sign --key did:web:example.com#k0 # wrote agent-feed.xml · sig Ed25519 · 1 entry $ cp agent-feed.xml ./public/.well-known/ # done. on next crawl, your origin is authoritative.
§ 03CLI
Five commands. All accept --feed PATH
(default ./agent-feed.xml) and
--quiet.
init [--from-corpus]
agent-feed.xml with the v0 schema. --from-corpus <origin> pre-fills from the highest-confidence observation.sign --key <did>
did:web document. Idempotent — re-signs only changed entries.verify <origin>
did:web, exit 0 if valid + entries do not break a pin you supply with --since.lint
snapshot
agent-card.json snapshot from the current feed head. Snapshots are derived; the feed is the source of truth.
Exit codes: 0 ok ·
1 validation failed ·
2 signature failed ·
3 network/IO ·
64 usage error.
§ 04Library — TypeScript
The TS package mirrors the CLI. All async; all return discriminated unions
({ ok: true, … } | { ok: false, error }) — we
do not throw on validation failure.
agent-feed.xml from disk. No verification — pair with verify().did:web document, verify every entry signature, return per-entry results.Feed.agent-card.json snapshot.import { load, verify, sign } from "agent-feed"; const feed = await load("./agent-feed.xml"); const result = await verify(feed); if (!result.ok) { console.error(result.error); // signed: false, reason: "did-not-resolve" process.exit(2); } // add a deprecation, sign, write const next = await sign( { ...feed, entries: [...feed.entries, { type: "deprecated", ref: "/v1/orders", successor: "/v2/orders", since: "2026-04-12", }] }, "did:web:example.com#k0" );
§ 05Library — Python
from agent_feed import load, verify, sign, Entry feed = load("./agent-feed.xml") result = verify(feed) if not result.ok: raise SystemExit(result.error) next_feed = sign( feed.with_entry(Entry.deprecated( ref="/v1/orders", successor="/v2/orders", since="2026-04-12", )), key="did:web:example.com#k0", ) next_feed.write("./public/.well-known/agent-feed.xml")
§ 06Three publisher adapters
Drop-in middleware for the runtimes most agent-facing services already
run. Each one serves /.well-known/agent-feed.xml
and /.well-known/agent-card.json with correct
caching headers.
route.ts handler under /.well-known/. ISR-friendly; revalidates when your feed source file changes.app.include_router(agent_feed_router). Reads the feed once at startup, watches the file for changes.fetch handler bound to two routes. Stores feed bytes in Workers KV; signs on the worker, never at the edge.Next.js · app/.well-known/agent-feed.xml/route.ts
import { handler } from "@agent-feed/next"; export const GET = handler({ source: "./agent-feed.xml" }); export const revalidate = 60;
FastAPI
from fastapi import FastAPI from agent_feed.fastapi import agent_feed_router app = FastAPI() app.include_router(agent_feed_router(source="./agent-feed.xml"))
Cloudflare Worker
import { workerHandler } from "@agent-feed/cf-worker"; export default { fetch: workerHandler({ kv: env.AGENT_FEED_KV, key: "agent-feed.xml", }), };
§ 07Corpus API
The dashboard is backed by a small public read API. Schemas-only, no prose; respects robots.txt at crawl time.
GET /api/corpus/counts
GET /api/corpus/origin/:o
GET /api/corpus/divergences
?since=.POST /api/corpus/optout
Names are stable across v0. Anything that breaks before v1 will be listed in CHANGELOG.md with a kill-criterion. Issues and PRs: github.com/agent-feed/agent-feed.