{"id":50496939,"url":"https://github.com/abdul-abdi/agent-feed","last_synced_at":"2026-06-02T08:30:24.799Z","repository":{"id":354381276,"uuid":"1223377487","full_name":"abdul-abdi/agent-feed","owner":"abdul-abdi","description":"The agentic web's git log. Signed /.well-known/agent-feed.xml protocol + drift observatory across MCP/A2A registries.","archived":false,"fork":false,"pushed_at":"2026-04-28T09:27:27.000Z","size":598,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-28T11:27:02.903Z","etag":null,"topics":["a2a","agentic-web","agents","atom","bun","did-web","ed25519","ietf-draft","mcp","protocol","typescript","well-known"],"latest_commit_sha":null,"homepage":"https://abdul-abdi.github.io/agent-feed/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abdul-abdi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-28T09:08:49.000Z","updated_at":"2026-04-28T09:27:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/abdul-abdi/agent-feed","commit_stats":null,"previous_names":["abdul-abdi/agent-feed"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/abdul-abdi/agent-feed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdul-abdi%2Fagent-feed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdul-abdi%2Fagent-feed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdul-abdi%2Fagent-feed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdul-abdi%2Fagent-feed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abdul-abdi","download_url":"https://codeload.github.com/abdul-abdi/agent-feed/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdul-abdi%2Fagent-feed/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33814306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a2a","agentic-web","agents","atom","bun","did-web","ed25519","ietf-draft","mcp","protocol","typescript","well-known"],"created_at":"2026-06-02T08:30:23.780Z","updated_at":"2026-06-02T08:30:24.793Z","avatar_url":"https://github.com/abdul-abdi.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agent-feed\n\n\u003e **The agentic web's git log.** A signed, append-only announcement layer at `/.well-known/agent-feed.xml`, plus a public observatory of how the existing ecosystem disagrees with itself.\n\n**[Live site → abdul-abdi.github.io/agent-feed](https://abdul-abdi.github.io/agent-feed/)** · [Drift dashboard](https://abdul-abdi.github.io/agent-feed/dashboard.html) · [SPEC.md](https://abdul-abdi.github.io/agent-feed/spec.html) · [IETF draft](https://abdul-abdi.github.io/agent-feed/ietf-draft.html) · [MCP SEP](https://abdul-abdi.github.io/agent-feed/mcp-sep.html)\n\n[![tests](https://github.com/abdul-abdi/agent-feed/actions/workflows/test.yml/badge.svg)](https://github.com/abdul-abdi/agent-feed/actions/workflows/test.yml)\n[![pages](https://github.com/abdul-abdi/agent-feed/actions/workflows/pages.yml/badge.svg)](https://github.com/abdul-abdi/agent-feed/actions/workflows/pages.yml)\n[![status: v0](https://img.shields.io/badge/status-v0-7ee787?style=flat-square)](./CHANGELOG.md)\n[![spec: 1190 lines](https://img.shields.io/badge/spec-1190%20lines-58a6ff?style=flat-square)](./SPEC.md)\n[![ietf: draft-00](https://img.shields.io/badge/ietf-draft--abdi--agent--feed--00-58a6ff?style=flat-square)](./docs/IETF-DRAFT.md)\n[![license: MIT](https://img.shields.io/badge/license-MIT-7d8590?style=flat-square)](./LICENSE)\n\nAgent endpoints in 2026 are described across MCP server cards, A2A registries, agents.json, llms.txt, and a half-dozen GitHub catalogs. They drift. They disagree. When an API mutates underneath an agent, the agent breaks silently — there is no `robots.txt`-equivalent for telling agents the world has moved.\n\n**This is that announcement layer** — plus a public observatory of where the existing standards already disagree about the same agent endpoint.\n\n---\n\n## See it\n\n**Live**: \u003chttps://abdul-abdi.github.io/agent-feed/\u003e — homepage, full SPEC viewer, IETF draft, MCP SEP, drift dashboard (in `[STATIC DEMO]` mode by default; configure a backend to make it live, see below).\n\n**Locally**, with a real backend:\n\n```bash\nbun install\nPORT=4300 SEED=1 DB_PATH=/tmp/corpus.sqlite bun apps/corpus/src/server.ts \u0026   # observatory + drift dashboard API\nPORT=4200 DB_PATH=/tmp/agg.sqlite           bun apps/aggregator/src/server.ts \u0026   # signed-feed search engine\nPORT=4100                                   bun apps/web/src/server.ts \u0026           # marketing site\n\nopen http://localhost:4100\n```\n\nYou'll see:\n\n- `http://localhost:4100/` — homepage with a real cross-source divergence in the hero\n- `http://localhost:4100/dashboard.html` — paste any GitHub repo or origin → see all observations + highlighted divergences + a draft signed-feed entry to publish\n- `http://localhost:4100/spec.html` — RFC-style SPEC viewer with sticky TOC\n- `http://localhost:4100/docs.html` — CLI / library / adapter quickstart\n- `http://localhost:4100/search.html` — signed-feed aggregator (honest empty state until publishers exist)\n\nThe corpus seeds itself from real public sources on first boot: 500 servers from the official MCP registry, 50 agents from the A2A registry, 2,200+ entries from the awesome-mcp-servers GitHub catalog. After it warms up, paste `https://github.com/Auctalis/nocturnusai` into the dashboard — it'll show you the same server described two different ways by two different sources.\n\n## What's actually shipped\n\n|                                                                        | Status                                                                                                                                   |\n| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| **Spec (v0)** — [SPEC.md](./SPEC.md)                                   | 1,190 lines · reader contract before producer schema                                                                                     |\n| **Library** — TypeScript reference                                     | `src/` · canonicalize · sign/verify · build/parse · Reader                                                                               |\n| **CLI** — `agent-feed init / sign / verify / lint / snapshot`          | [src/cli.ts](./src/cli.ts)                                                                                                               |\n| **Publisher adapters**                                                 | [Next.js](./adapters/next) · [FastAPI](./adapters/fastapi) (cross-language verified) · [Cloudflare Worker](./adapters/cloudflare-worker) |\n| **Aggregator** — search engine for signed feeds                        | [apps/aggregator](./apps/aggregator) · SQLite + FTS5 + REST + UI                                                                         |\n| **Corpus observatory** — third-party drift detection                   | [apps/corpus](./apps/corpus) · MCP registry + A2A registry + GitHub READMEs · cross-source divergence as headline                        |\n| **Web** — homepage + dashboard + spec + docs                           | [apps/web](./apps/web) · 5 pages from a Claude design handoff                                                                            |\n| **IETF draft**                                                         | [docs/IETF-DRAFT.md](./docs/IETF-DRAFT.md) · 2,691 lines · `draft-abdi-agent-feed-00`                                                    |\n| **MCP SEP** — `agent-feed` as the streaming layer beneath Server Cards | [docs/MCP-SEP-agent-feed.md](./docs/MCP-SEP-agent-feed.md)                                                                               |\n| **78 conformance tests** across 13 files                               | `bun test`                                                                                                                               |\n\n## Two doctrinal commitments\n\n### Snapshot ≠ stream\n\nEvery origin gets two artifacts at two URLs:\n\n| URL                            | Mutability        | Answers                                 |\n| ------------------------------ | ----------------- | --------------------------------------- |\n| `/.well-known/agent-card.json` | mutable, replaced | \"what is true _now_\"                    |\n| `/.well-known/agent-feed.xml`  | append-only       | \"how did we get here, and what changed\" |\n\nYou cannot reconstruct a stream from samples of state. They are different epistemic objects. Mixing them is why migrations break agents silently.\n\n### Signed ≠ observed\n\nEvery fact in this system is one of two kinds:\n\n- **Signed** — first-party, `did:web`-rooted, Ed25519-attested. Testimony.\n- **Observed** — third-party, sourced, _always_ tagged `UNSIGNED`. Photograph.\n\nThe protocol is signed-only. The corpus observatory is observed-only. Storage may join, surfaces never blur. Every observation row carries `source` + `sourceFetchedFrom` + `observedAt`. The dashboard renders unsigned tags loudly, in red, on every observation card. Differently-shaped facts; not a quality gradient.\n\n## How it composes with what you already run\n\n```\nagent ↔ agent     MCP · A2A · ANP                how agents talk\nagent ↔ api       OpenAPI · agents.json           how agents act\nagent ↔ context   llms.txt                        how agents read\nagent ↔ change    agent-feed                      how the world announces it moved   ← this project\n```\n\n`agent-feed` is _the change-history layer_ beneath those protocols. Bring your own MCP / A2A / ANP / OpenAPI; we announce when they mutate. We are not trying to be the agentic web. The web doesn't live in DNS; we don't either.\n\n## Library quickstart\n\n```ts\nimport { Reader, withFeedRecovery } from \"agent-feed\";\n\nconst reader = new Reader();\nreader.on(\"mismatch\", (e) =\u003e console.warn(\"schema mismatch\", e));\nreader.on(\"unverified-entry\", (e) =\u003e console.warn(\"bad signature\", e));\nreader.on(\"feed-migrated\", (e) =\u003e console.log(\"publisher moved\", e.migratedTo));\n\nawait reader.ingest({ origin, xml, didDocument });\n\n// after every live API call, hand the response to the reader so it can detect drift\nreader.observeLiveResponse({ origin, endpointId: \"orders-api\", body });\n\n// the 404-killer: when an agent gets a 404, consult the feed for a replacement\nconst fetch2 = withFeedRecovery(reader, fetch, { origin });\nconst res = await fetch2(\"https://api.example.com/v1/orders\");\n```\n\n## CLI quickstart\n\n```bash\n# Generate keypair + did.json + empty feed\nbun src/cli.ts init -o https://example.com -d ./public/.well-known\n\n# Append a signed schema-change entry\nbun src/cli.ts sign -d ./public/.well-known -t schema-change -p '{\n  \"effective-at\": \"2026-04-27T13:00:00Z\",\n  \"endpoint-id\": \"orders-api\",\n  \"from-version\": \"1.0\",\n  \"migration\": { \"add\": [\"currency\"] },\n  \"to-version\": \"1.1\"\n}'\n\n# Verify and lint a remote feed\nbun src/cli.ts verify -o https://example.com\nbun src/cli.ts lint   -o https://example.com\n```\n\n## End-to-end demo (no servers needed)\n\n```bash\nbash scripts/full-demo.sh\n```\n\nPrints a step-by-step walk: agent calls a v1.0 endpoint successfully → origin migrates to v1.1 and signs a `schema-change` entry → agent re-ingests the feed, reads the migration, and survives the breaking change without redeployment.\n\n## Repository layout\n\n```\nagent-feed/\n├── SPEC.md                  # the v0 protocol — 1,190 lines, reader contract first\n├── ROADMAP.md               # tiered, every item carries its kill-criterion\n├── CHANGELOG.md             # shipped items moved here per the roadmap discipline\n├── docs/\n│   ├── IETF-DRAFT.md        # draft-abdi-agent-feed-00\n│   ├── MCP-SEP-agent-feed.md # snapshot ≠ stream proposal\n│   └── design-brief.md       # design handoff brief\n├── src/                     # reference TypeScript library + CLI\n├── tests/                   # 78 tests + conformance vectors\n├── adapters/\n│   ├── next/                # @agent-feed/next  (44 LOC)\n│   ├── fastapi/             # agent-feed-fastapi (Python; cross-language verified)\n│   └── cloudflare-worker/   # @agent-feed/cloudflare-worker\n├── apps/\n│   ├── aggregator/          # signed-feed search engine — SQLite + FTS5\n│   ├── corpus/              # observatory — MCP registry + A2A + READMEs\n│   └── web/                 # homepage + dashboard + spec + docs (5 pages)\n├── examples/                # publisher fixture + consumer-survives-schema-change demo\n├── scripts/\n│   ├── full-demo.sh         # one-command end-to-end demo\n│   └── build-vectors.ts     # regenerate conformance vectors\n└── design materials/        # Claude-design handoff: source HTML/CSS for apps/web/\n```\n\n## Roadmap\n\nSee [ROADMAP.md](./ROADMAP.md) — four tiers, every item has explicit kill-criteria. Shipped items move to [CHANGELOG.md](./CHANGELOG.md) per the roadmap discipline. Highlights:\n\n- **Tier 1** (close the loop): WebSub push, did:web key rotation, HTTP `Cache-Control` honoring.\n- **Tier 2** (adoption): hosted conformance checker site, npm/JSR publish.\n- **Tier 3** (standards posture): IETF dialogue, MCP TC engagement, A2A extension, Rust + Go ports, formal TLA+ model.\n- **Tier 4** (the bets): the 30-year archive, the regulatory wedge, IDE/browser integration, ML training corpus, time-travel debugging — all gated on real-world signal.\n\n## What this is not\n\n- **Not a registry.** No central index. Discovery is by origin URL.\n- **Not a discovery protocol.** MCP Server Cards / A2A Agent Cards already cover state-snapshot discovery; agent-feed is the temporal-history layer beneath them.\n- **Not a status page.** Operational telemetry has different time-constants and consumers.\n- **Not a policy engine.** Pricing, rate limits, ToS belong in a separate slow-changing document.\n- **Not the agentic web.** It's a layer, not a runtime. The web doesn't live in DNS; this doesn't either.\n\n## Hosting your own backend\n\nThe web app is fully static and lives on GitHub Pages. The drift dashboard's _live_ mode requires the corpus app reachable somewhere on the public internet. Two ready-to-go paths:\n\n```bash\n# Fly.io (recommended — Bun-native, persistent volume for SQLite)\nfly launch --no-deploy --copy-config        # uses apps/corpus/fly.toml\nfly volumes create corpus_data --size 1\nfly deploy\n\n# Or Docker anywhere\ndocker build -f apps/corpus/Dockerfile -t agent-feed-corpus .\ndocker run -p 4300:4300 -v $PWD/data:/data agent-feed-corpus\n```\n\nAfter deploy, point the dashboard at it by setting `window.__CORPUS_ORIGIN__ = \"https://your-corpus-host\"` in a `\u003cscript\u003e` tag before the dashboard's existing inline script. The live `[STATIC DEMO]` banner disappears and the form starts hitting the real API.\n\n## Stewardship\n\nIndependent. MIT-licensed. The two architecture roundtables that produced the trust-plane separation (`pg`+`carmack`+`taleb`+`hickey` for the protocol; `hickey`+`carmack`+`taleb`+`karpathy` for the corpus) are committed to this repo as design provenance. No company. No funding. No signup. `agent-feed.dev`, not `app.agent-feed.dev`.\n\n## License\n\n[MIT](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdul-abdi%2Fagent-feed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdul-abdi%2Fagent-feed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdul-abdi%2Fagent-feed/lists"}