Docs

what changed? keeps one private log of what your agents and team ship, and sends the releases you approve. It has no AI of its own and makes no model calls. Your agents talk to it through MCP.

Your first release

  1. Create a product, or open one you can edit.
  2. Record changes by hand, through MCP or from GitHub. Imports never publish or notify anyone.
  3. Pick the changes users should hear about and draft a release. Your agent can write the draft.
  4. Choose destinations and connect your own publishing accounts.
  5. Approve the current revision, then publish or schedule it. Check each destination's receipt.

Editing a release after approval cancels the approval, so the next revision needs approving again. Editing a log entry never rewrites a release. Public feeds, RSS, embeds and widgets read what you published, not your log. Publishing after a deploy is off until you turn it on, and then it only sends a release you approved and queued for that deploy.

Connect your agents

In the app, open Agents and create a token for one product. Read and write is enough for an agent that records changes and drafts releases. Give publish permission only to an agent that should approve or send releases. Keep the token in your client's secret store and revoke it when you no longer need it.

MCP accepts HTTP POST at /api/mcp. Client setup varies, so treat this as a general example and fill in your own values:

{
  "mcpServers": {
    "what-changed": {
      "type": "http",
      "url": "https://YOUR_HOST/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_PRODUCT_TOKEN" }
    }
  }
}

Catch up before working

Call entry.list with since set to the last time the agent worked on the product, in Unix milliseconds. It returns the newest changes first, each with its author: a person, an agent token, GitHub or a KRNL OS member. Page backwards with before set to the returned nextBefore.

{"productId": "PRODUCT_ID", "since": 1760724000000}

Record a change

Pass this to entry.create. The source reference stops the same change from being recorded twice.

{"productId": "PRODUCT_ID", "data": {
  "title": "Receipt exports",
  "body": "Receipts can now be exported as CSV.",
  "kind": "feature",
  "sources": [{"type": "mcp", "id": "receipt-export-1"}]
}}

Draft a release

Use the entry ids in release.create. You or your agent write the body. The service never generates it.

{"productId": "PRODUCT_ID", "data": {
  "title": "Receipt exports",
  "body": "Download receipts as CSV from the billing page.",
  "audience": "public",
  "entryIds": ["ENTRY_ID"]
}}

Approving uses release.approve with {productId, id, revision}. Publishing uses release.publish with {productId, id, revision, destinationIds}. Both need publish permission. release.schedule takes a future scheduledAt in Unix milliseconds.

Agent instructions

Paste this into AGENTS.md, CLAUDE.md or your client's instructions so every agent checks in the same way:

## Changelog
- Before you start, call entry.list with since set to the last time
  you worked here (Unix ms). Read what the others changed.
- When you finish something a user would notice, call entry.create
  with a plain title and a sentence on what changed for them.
- Record internal work with kind "internal". It stays private.
- Never publish a release. A person approves those.

The same commands work over plain HTTP at /api/command with a body of {command, args} and the same bearer token. Responses are {ok: true, data} or a structured error.

Destinations

The hosted changelog and widget use your published releases. Every other destination uses your own account and keys. Saving credentials does not prove the account can publish, so check the first delivery's receipt.

  • GitHub needs contents write access and a tag or version on the release.
  • Email uses your Resend key and a verified sender. Subscribers confirm first, and every email has an unsubscribe link. Sent email can't be edited.
  • Slack and Discord use an incoming webhook for the channel you choose.
  • LinkedIn needs approved publishing access and the right author URN. X needs a developer account and a user token with tweet.write. Neither edits posts after sending.
  • Payload, WordPress, Webflow, Ghost, Contentful and Sanity need write access and a content model that fits. Required custom fields can make the provider reject a post.
  • Custom webhooks need an HTTPS endpoint and a signing secret. Your receiver should check the signature and ignore repeated delivery ids.

Each destination has its own receipt. Retry a failure without sending the others again. A delivery marked "needs checking" may already exist at the provider, so confirm it before sending again. Releases for a restricted audience can't go to public social or CMS destinations.

KRNL OS

Each KRNL OS project can link to one product. A project owner or admin links it from the project's Releases screen with a product token. After that, the project has its own Releases screen inside KRNL OS, built from the same records as this app.

  • The project's log shows what people, agents and GitHub changed since you last looked, with each change credited to whoever made it.
  • Finished issues can go into the log with one click, credited to the person who finished them.
  • Project members draft and edit releases in KRNL OS. Approving and publishing follow their KRNL OS role and the token's permissions.
  • Product settings, tokens, destinations and audiences stay in this app.

Publishing to KRNL OS is a separate destination. It writes a document into the project with a document write key, and it does not post in chat.

Run your own instance

The source repository is private while its licence is undecided. Self-hosting needs an authorised checkout.

The app is a Next.js app that runs on Vercel with Postgres and WorkOS sign-in, and needs Node.js 22.13 or later. The checkout includes SELFHOSTING.md, the migrations and an environment reference. Before deploying, set up a database role, a WorkOS environment, an encryption key and the public origin.

Scheduled releases need a scheduler that calls the authenticated delivery worker. On Vercel, the included cron does this every minute. Opening the app does not run them. You also own backups, monitoring and outbound network rules.

Open the app, read the privacy notice or write to team@krnl.studio.