Use with AI agents
Give coding agents the docs as Markdown, an Agent Skill, an MCP server, the rules they most often get wrong, and prompts that work.
Every page is available as plain Markdown. Coding agents read it more reliably than HTML.
| Resource | What it is |
|---|---|
/llms.txt | An index of every page, grouped by section, with links to the Markdown versions |
/llms-full.txt | All the docs in one Markdown file |
/docs/<page>.md | Any page: add .md to its URL, for example /docs/quick-start.md |
Accept: text/markdown | Any page URL returns Markdown when the request prefers it |
| Copy Markdown and Open in | Buttons at the top of every page. Send the page to ChatGPT, Claude, Cursor, and others |
The Markdown includes the type-checked example files and the generated type tables, so an agent sees the same code you do. The docs describe the latest beta; pin that version.
Install the skill
The package ships an Agent Skill with setup steps, code templates, and the rules below. It lives in node_modules/good-webhooks/skills/good-webhooks/, so it always matches your installed version.
npx skills add pplytas/good-webhooksConnect the MCP server
https://good-webhooks.dev/api/mcp is a Model Context Protocol server with three tools: list_pages, get_page, and search. No sign-in needed.
claude mcp add --transport http good-webhooks https://good-webhooks.dev/api/mcpOr add the rules to your project
Without the skill, paste this into your AGENTS.md, CLAUDE.md, or your editor's rules file. It points the agent at the docs and lists the mistakes agents make most often with this library.
## Good Webhooks
Docs: https://good-webhooks.dev/llms.txt (fetch the linked .md pages for details)
- Receivers must pass the raw request body (string or bytes) to `parseWebhook()`. Never parsed JSON.
- Receivers must record `event.id` in the same transaction as their change. Delivery is at least once.
- Respond 400 only for SIGNATURE_INVALID, SIGNATURE_EXPIRED, PAYLOAD_INVALID. Other errors are 500 so the sender retries.
- `publish()` only stores the event. Nothing is sent unless a worker runs `worker.run()` or `worker.runOnce()`.
- Load `WEBHOOK_ENCRYPTION_KEY` from secrets. Never call `generateEncryptionKey()` at startup.
- Apply SQL from `getPostgresMigration()` with the migration tool. The library never runs migrations.
- `forScope()` does not authorize. Check the caller's access before choosing a scope.
- Publish with `{ transaction: client }` when the business write uses the same database.
- `allowLocalhost: true` is for local development only.Prompts to try
Read https://good-webhooks.dev/docs/quick-start.md and follow it in a new
directory. Run the script and show me the output.Source
The docs source is in apps/docs/content/docs. The public API is in packages/good-webhooks/src and ships with type declarations.