notefeed

Oct 29

  1. notefeed 0.34.0

    Released 2026-10-29 · on GitHub

    The operator can take down one post instead of the whole feed (#159, ADR 0052). With "scope": "note", POST /api/operator/takedown takes a note's read URL, an image URL or <read id>/<note id> (what a report carries). It removes the post: the note, the text it was posted with, and every picture posted with that text. Their images go on the blocklist, as with a feed takedown. In the post's place, the feed shows a mark: "Removed by the operator: this broke the content rules of this instance.", linked to the terms page when there is one. Whoever can post to the feed can delete the mark, but the post does not come back. The removed notes answer 410 (removed) in the API, MCP and their file links, also once the mark is deleted. Readers only learn of removals they could have seen: a removed draft, or a removed post dated later, is a missing note to them. Without scope, the takedown removes the whole feed, as before.

    In the APIs and clients the mark is a note with removed: true and the type application/x-notefeed-removed. It has the removed note's id and date and no content. Getting or editing it answers 410 (removed), and deleting it works like for any note.

    Every note now counts against a feed's limits: texts, pictures and marks alike. On a free feed, the newest notes kept include pictures kept from a license that ran out, and the oldest note to go may be a picture or a mark. NOTEFEED_MAX_NOTES_PER_FEED counts every note too; NOTEFEED_MAX_IMAGES_PER_FEED still limits pictures on their own. Takedowns of posts are counted in notefeed_notes_deleted_total with reason="takedown".

    Breaking: NOTEFEED_MAX_NOTES_PER_FEED counted only text notes and now counts pictures as well. On an instance that sets it, a feed with many pictures reaches the limit sooner and further posts answer 507 (note_limit). Raise the value if that matters to you. A free feed's cap counts pictures too: a feed that kept pictures after its license ran out drops its oldest notes sooner.

    Upgrading: on SQLite and PostgreSQL the first start adds a table (migration 008_note_tombstones); take a backup first. No setting changes.

    MCP: list_notes and get_note mark the operator's marks with removed: true; get_note and edit_note refuse a removed note, and delete_note deletes a mark. Assistants see this after reconnecting (Claude: a new chat, or remove and add the connector; Claude Code: restart).

Oct 28

  1. notefeed 0.33.1

    Released 2026-10-28 · on GitHub

    Drafts and scheduled notes no longer show a Report link (#327). No reader can see them, so there is nothing to report, and the operator could not open them from a report; whoever sees one can remove it. A note gets its Report link once readers see it. On notefeed.me the terms, privacy page and imprint say the link is on every published note.

    Upgrading: nothing to do.

  2. notefeed 0.33.0

    Released 2026-10-28 · on GitHub

    A note can be a draft (#265, ADR 0051). Whoever can post to the feed sees it on the feed page, marked as a draft, and edits it like any note; readers don't see it anywhere: not on the read link, in RSS or in the read API, and its address and its pictures' files answer 404. Publishing it changes nothing else: it keeps its id, its links and its date, so a draft dated in the past takes its place there and one dated in the future becomes a scheduled note. A published note can be made a draft again. Pictures posted with a note follow it. A draft picture can't be the feed's title image, and a note whose picture is the title image can't become a draft. In the web UI it is the Draft box in the compose box and in a note's edit form; in the API X-Note-Draft: true on a post and draft in a PATCH; in the clients draft when posting and updating, and notefeed post --draft, notefeed update --draft / --publish.

    The post-to-notefeed skill asks where your drafts live: in the conversation, on the feed itself, or in a second feed whose read link you can send to a reviewer.

    The report form asks for what the EU's Digital Services Act says a notice holds (Art. 16(2)): an optional name beside the optional e-mail address, and a box to confirm you report in good faith (#319).

    Upgrading: on SQLite and PostgreSQL the first start adds a column to the notes table and rebuilds its index (migration 007_note_draft); take a backup first. With NOTEFEED_REPORT_ENDPOINT set, the report page now also posts name and good_faith (Yes): an inbox that refuses unknown fields needs them before the upgrade. notefeed.me's inbox has them.

    MCP: post_note, post_file and edit_note take draft; list_notes and get_note mark drafts with draft: true. Assistants see them after reconnecting (Claude: a new chat, or remove and add the connector; Claude Code: restart).

  3. notefeed 0.32.0

    Released 2026-10-28 · on GitHub

    A license key no longer opens the payment provider's customer portal. That portal shows the buyer's e-mail address, payment method and invoices, and every license they bought with its key, so one key handed to a co-author or put into a script could reach the buyer's data and their other feeds (#316, ADR 0050). Buyers now manage their purchases at Creem themselves: sign in at https://creem.io/my-orders/login with the e-mail address you bought with, or use the link in the receipt. The license page links there under "Manage your purchases".

    Scripts and agents can ask what licenses are sold, where to buy one and where buyers manage them: GET /api/v1/licenses, the MCP tool get_licenses, and licenses() in both client packages.

    Upgrading: nothing to do.

    MCP: a new tool, get_licenses. Assistants see it after reconnecting (Claude: a new chat, or remove and add the connector; Claude Code: restart).

  4. notefeed 0.31.1

    Released 2026-10-28 · on GitHub

    The page that says what notefeed stands for has moved to https://docs.notefeed.me/values/ (it was /vision/ for a few hours). The footer's "Values" link and the start page point there.

    Upgrading: nothing to do.

  5. notefeed 0.31.0

    Released 2026-10-28 · on GitHub

    Pictures can be shared to notefeed from the phone. On Android, notefeed installed from Chrome takes pictures, text and links from the share sheet: pick a feed and they wait in its compose box until you post (Samsung Internet's installed app does not yet, #314). On the iPhone, a Shortcut does the same; the new docs page "Sharing from a phone" has the recipe. Pictures in one post may now share a file name, unless the text refers to it.

    Every image is now shrunk, turned upright and stripped of its metadata (location, camera) on the server, whatever posted it: the web page, a script, the clients or an assistant over MCP. It is stored at most 2560 px wide or high, in its own format; animations stay. An upload may be up to 10 MiB (was 5), so a phone photo goes as it is (ADR 0049).

    A title image uploaded in the feed's settings is the feed's own and no longer shows up as a post: PUT / DELETE /api/v1/feeds/{feed}/image, MCP set_feed_image, and setFeedImage / removeFeedImage (JS), set_feed_image / remove_feed_image (Python). Title images uploaded before stay posts until set again.

    The version an instance runs is shown in the footer and the ⓘ menu, and /health says it. A note's page shows the feed with a large "All notes" beside it on a wide screen, and pictures in a note are kept to a sensible size.

    notefeed has a page that says what it stands for: no accounts, no personal data, publishing rather than interacting, and what follows from that (https://docs.notefeed.me/vision/). Every page links to it from the footer ("Values").

    Breaking: a file that only starts like an image but is none is now refused with 415, an image over 100 megapixels with 413. When the server is busy processing images it answers 503 with Retry-After, which both clients raise as RateLimitedError.

    Upgrading: NOTEFEED_SHRINK_IMAGE_BYTES is gone (the browser no longer shrinks pictures; the server does); a start with it set logs a warning. NOTEFEED_MAX_IMAGE_BYTES now defaults to 10 MiB, which is also its most. notefeed.me sets neither.

    MCP: a new tool, set_feed_image; post_note's pictures may share a name unless the markdown refers to it. Assistants see the new tool after reconnecting (Claude: a new chat, or remove and add the connector; Claude Code: restart).

Oct 27

  1. notefeed 0.30.0

    Released 2026-10-27 · on GitHub

    A feed can be created without posting a note, to reserve its name with a password, a license and a read id: POST /api/v1/feeds/{feed}, MCP create_feed, createFeed / create_feed in the clients, or "Create feed without a note" in a new feed's card. Where licenses are sold it needs a license key, which goes on the new feed (ADR 0047).

    A lost feed password can be reset with the feed's license key from scripts and agents too: POST /api/v1/feeds/{feed}/password/recover, MCP recover_feed_password, recoverFeedPassword / recover_feed_password in the clients. In the web UI, a browser that is still unlocked finds the same under "Forgot the current password?" in the feed's settings. Changing a password now says so next to the password row ("Password changed."), instead of a small "Saved." at the top of the page.

    Feeds with an active license are no longer rate limited on posts, edits and deletes; wrong passwords and keys still are (ADR 0046).

    The page uses the whole width of the window. Mermaid diagrams are drawn in the feed's timeline too, and a click opens one enlarged.

    Each release now posts the agent skills to notefeed.me's skills feed: curl -O https://notefeed.me/r/skills/post-to-notefeed.md always gets the newest.

    Upgrading: nothing to do. notefeed.me reserves the new skills feed in notefeed-ansible (NOTEFEED_RESERVED_FEEDS).

    MCP: two new tools, create_feed and recover_feed_password. Assistants see them after reconnecting (Claude: a new chat, or remove and add the connector; Claude Code: restart).

  2. notefeed 0.29.0

    Released 2026-10-27 · on GitHub

    Tags can be changed after posting: the edit form, PATCH with tags, MCP edit_note and notefeed update --tags in both clients. Tags that are numbers sort as numbers.

    An open feed can be claimed by setting a password (ADR 0044): whoever has the feed's name may set the first one, on the settings page, with PUT /api/v1/feeds/{feed}/password, MCP update_feed new_password or the clients. A license can go on a feed without a password, when the feed is created or later (ADR 0043). Where licenses are sold, a lapsed key is now refused with 402, and an unknown key counts against the per-IP limit like a wrong password.

    Long notes read better: heading anchors, a table of contents from three headings on, picture sizes (![](shot.png#width=480)), code highlighting on the page and in RSS, and Mermaid diagrams. A note posted with a name (X-Note-Name, MCP post_note name) is served by that name under the read link: /r/<read id>/<name> (ADR 0045).

    For operators: the footer links only the feeds in NOTEFEED_FOOTER_FEEDS, in that order; unset, it links none (it used to link every reserved feed). Reserved feeds no longer hit the free tier's limits. Euro prices show as 1.99 €.

    Dependencies: Next.js 16.4.3, the MCP server 2.3.1 and zod 4.6.7 with security fixes.

    Breaking: where licenses are sold, a lapsed license key is refused with 402 when attached or used to create a feed; it used to be accepted and did nothing. An unknown key now counts against the per-IP limit like a wrong password.

    Upgrading: the footer links only the feeds in NOTEFEED_FOOTER_FEEDS, in that order. Unset, it links none; it used to link every reserved feed.

    MCP: post_note takes name; edit_note takes tags; update_feed takes license_key and new_password, and its title and description are optional. Assistants see the new parameters only after reconnecting: in Claude, start a new chat (or remove and add the notefeed connector); restart Claude Code.

Oct 26

  1. notefeed 0.28.0

    Released 2026-10-26 · on GitHub

    A note's date is its own now, no longer part of its id (ADR 0042). A note posted with a date in the future is scheduled: readers see it only from that time on, on the read page, in RSS and in the read API. Its owner sees it marked as scheduled. A note's date can be changed at any time: PATCH with date, the MCP tool edit_note, notefeed update --date in both clients, or the edit form on the note's page. Images posted with a text move with it.

    Breaking: the time of a post is X-Note-Date (was X-Note-Created, which is now refused with a 400), and date everywhere else (was created_at in MCP and Python, createdAt in JS, --created in the CLIs). There is no alias.

    Note ids are random now. On its first start, 0.28.0 gives every existing note a new id and keeps its date. Links to single notes and files with the old ids stop working, and links from one feed to another are not rewritten. Back up the data and the images before upgrading.

    • #246: Opaque note ids, scheduled notes, changing a note's date (ADR 0042)
  2. notefeed 0.27.0

    Released 2026-10-26 · on GitHub

    A note can be posted with a time other than now: X-Note-Created on a post takes an ISO 8601 date-time with its offset, or a date alone, from 1970 up to now. The note's id and time come from it, so the feed, its read link and RSS place it there. The MCP tool post_note takes created_at, the JS client createdAt and notefeed post --created, the Python client created_at and --created, and the compose box has a date-and-time field next to Tags.

    The footer and the ⓘ menu link to notefeed's own feeds: the release notes and the blog.

    • #237: Footer and ⓘ menu link to the reserved feeds
    • #239: Post a note with a time other than now (X-Note-Created)

Oct 25

  1. notefeed 0.26.0

    Released 2026-10-25 · on GitHub

    A note shows its text as written, in the list and on its own page (ADR 0040): only a title of its own, set when posting or editing, is a heading above it, and no line of the text is dropped for a guessed title any more. A click anywhere on a note's card opens the note; its time is the link itself. The "Notes tagged" line above a filtered list is gone: the feed's tags show which one filters.

    In RSS, an item's description is the note's text as HTML, rendered as the page renders it, so readers show pictures instead of markdown (ADR 0041). The first picture of a note is the item's image (Media RSS), and a picture without a title is titled by its alternative text, its file's name, or "Picture" and its time, never its id.

    • #232: Notes show their text as written; a click anywhere on a card opens it (ADR 0040)
    • #234: RSS: descriptions are HTML, the first picture is the item's image, no ids as titles (ADR 0041)
  2. notefeed 0.25.0

    Released 2026-10-25 · on GitHub

    The operator gets usage on /metrics (ADR 0039): how many feeds, notes, images and bytes the instance holds, how many feeds were active in the last day, week and month, how many free feeds are near or at the note cap, the licenses by state, and on a database its size (and on PostgreSQL its connections). Counted at most every five minutes, never per scrape. Next to them, counters for feeds created and removed, notes posted, edited and deleted, and license events. No metric names a feed, a read id or a key, and none is per feed.

    Every kind of note follows one rule for clicks (ADR 0038): in a list, everything on a note's card opens the note; on a note's own page, a picture opens the picture's own page.

    • #229: Feed: a note's picture opens the note first, then the picture's own note
    • #230: UI: note kinds in one registry, one click rule for every kind
    • #231: Metrics: usage gauges and event counters for the operator

Oct 24

  1. notefeed 0.24.0

    Released 2026-10-24 · on GitHub

    A picture posted with a markdown note shows once: inside the note, no longer again as a note of its own in the feed, the read-only view and RSS. Clicking it opens the picture's own page, from the feed and from the note's page. A picture is only left out of a list that also holds the note showing it, so a tag filter that lists the picture alone still shows it; the API lists every note as before.

    On an instance that sells licenses, the license page's tiles line up: prices, features and buttons sit at the same height whatever the plans' names and badges, and the free tile's price gets the plans' currency ("€0").

    • #227: License page: the tiles line up (#223)
    • #228: A note's pictures show once: inside the note, linking to their own pages
  2. notefeed 0.23.1

    Released 2026-10-24 · on GitHub

    Deleting a note now asks in a dialog at every screen width. On wide screens the question used to appear as a card under the note, out of sight below a tall picture or a long note. The page is dimmed, Escape or a click beside the dialog cancels, and Cancel has the focus, so a stray Enter deletes nothing. Editing a note is unchanged.

    • #226: Note page: delete asks in a dialog

Oct 21

  1. notefeed 0.23.0

    Released 2026-10-21 · on GitHub

    On an instance that sells licenses, a lost feed password is recovered with the feed's license key: the unlock screen of a protected feed has "Forgot the password?", where the key attached to the feed and a new password set it anew (an active license is needed, like for any change), or an empty new password removes it (a lapsed license's key may do that too). A wrong key counts as a wrong password. The key, which the payment provider puts in the buyer's receipt and portal, is the proof of owning the feed; the password stays the secret to share. Instances without a payment provider show nothing new; the docs now describe how the operator removes a lost password with the SQL storage too.

    • #225: A lost feed password is recovered with the feed's license key (ADR 0037)
  2. notefeed 0.22.1

    Released 2026-10-21 · on GitHub

    A protected feed's settings page can enter a license key again: it posted to /api/licenses/attach, where the feed's unlock cookie is never sent, and was refused. It now posts and deletes under /<feed>/license. A new key also replaces a lapsed (refunded or run-out) license on the feed instead of being refused until the old one is detached.

    • #224: License: a protected feed's settings page can enter a key again; a new key replaces a lapsed one
  3. notefeed 0.22.0

    Released 2026-10-21 · on GitHub

    License keys now come from the payment provider: Creem issues the key, and it is also in the buyer's receipt e-mail and Creem's customer portal, so a lost key can be found again. notefeed still stores only its hash. After paying, the buyer comes back to /license?checkout_id=…, and the page asks the new POST /api/licenses/key for the key bought in that checkout. Each Creem product needs Creem's license key delivery; a completed checkout without a key is rejected. The license page shows an optional fine print below the tiles (fineprint in the operator's license.md), and the plan tiles no longer show the product's description, which is left to the provider's checkout. Self-hosted instances without a payment provider need no change.

    • #222: License keys from Creem; license page: fine print, short tiles (#218)
  4. notefeed 0.21.0

    Released 2026-10-21 · on GitHub

    A late subscription.expired or subscription.unpaid from the payment provider no longer lapses a license that has already been renewed past that period: an ending now carries the period it ends, and only ends the license if no later period was paid. Creem's renewal, a cancel at the period's end (which Creem carries out hours before that end, as a plain subscription.canceled) and a pause are tested against the deliveries of a sandbox run. Instances without a payment provider need no change.

    • #221: A late subscription.expired does not lapse a renewed license; the daily sandbox run as a test (#218)

Oct 19

  1. notefeed 0.20.0

    Released 2026-10-19 · on GitHub

    The license page of an instance that sells licenses now takes its words from the operator: a Markdown file with YAML front matter named by NOTEFEED_LICENSE_FILE holds the intro, the free tile and what every plan tile shows, and notefeed does not serve without it while a payment provider is set. Each plan's name, description and price are read from the configured Creem products and kept for five minutes, so a change in Creem shows without a deploy, and the yearly discount is computed from the two amounts. NOTEFEED_LICENSE_PRICE and NOTEFEED_LICENSE_PRICE_YEARLY are no longer read. Every instance can show a Support link in its footer with NOTEFEED_SUPPORT_EMAIL. Self-hosted instances without a payment provider need no change.

    • #220: License page: words from license.md, plans from Creem's products; a Support link (#218)

Oct 18

  1. notefeed 0.19.0

    Released 2026-10-18 · on GitHub

    Encryption at rest on the database backends: with NOTEFEED_ENCRYPTION_KEY, or with the main key in OpenBao (NOTEFEED_KMS=openbao), notefeed encrypts every feed's notes, images, metadata, settings and password with a data key of its own before they reach the database or the image store, and stores names and read ids only as fingerprints. A copy of the database, a dump or a bucket shows neither the notes nor a way into a feed. With OpenBao the main key never reaches notefeed, every unwrap is in OpenBao's audit log, and an unreachable OpenBao is a maintenance page (503 with the code unavailable from the API) rather than an error. A note that can't be decrypted is listed as a damaged note in its place instead of breaking its feed, and notefeed's own pages replace Next's plain not-found and error pages.

    • #211: Settings: the REST API first under Posting
    • #214: CLAUDE.md: commands, architecture and the production repos
    • #216: Encryption at rest: envelope encryption on the database backends (#212)
    • #217: Key service: the main key in OpenBao (#215)

Oct 17

  1. notefeed 0.18.0

    Released 2026-10-17 · on GitHub

    A new feed's password and license key sit in a "Protect this feed" section next to the feed, not under the compose box. The license page shows a tile per plan, with what the yearly one saves, and the start page warns plainly that a feed's name is its key. The settings are in a clearer order, with a Posting section for scripts, AI agents over MCP, the client libraries and the REST API, each with its docs. On a phone the page fits the screen, and the note bar has a camera button. A creation that lost a race to a feed deleted at the same moment no longer leaves the name listed without its directory.

    • #199: NOTEFEED #198: Two doors into the docs, notefeed.me and your own server
    • #201: NOTEFEED #200: Trim the docs to the necessary content
    • #204: NOTEFEED #202 #203: Phone page fits the screen; camera button in the note bar
    • #206: NOTEFEED #205: Feed password and license key in the sidebar
    • #207: Mention MCP as a way to post
    • #208: License page: a tile per plan; a prominent warning about the feed's name
    • #209: Settings in a clearer order; note page aligned with the feed page
    • #210: A creation that lost to a feed deleted meanwhile no longer lists the name

Oct 16

  1. notefeed 0.17.0

    Released 2026-10-16 · on GitHub

    A protected feed can be created on notefeed.me: the first note takes the license key next to the password, in the web UI, the API, the clients and MCP. A post refused for the lack of a license gets a banner that says what to do. The docs keep the hosted service's free tier and licenses on their own pages.

    • #196: NOTEFEED #193: Create a protected feed with its license key in one post
    • #197: Docs: keep the hosted service's free tier and licenses on their own pages
  2. notefeed 0.16.0

    Released 2026-10-16 · on GitHub

    A yearly license next to the monthly one.

    • #194: NOTEFEED #42: Sell a yearly license next to the monthly one

Oct 15

  1. notefeed 0.15.0

    Released 2026-10-15 · on GitHub

    v0.15.0: a free feed shows its notes against the cap

    Nothing to do when upgrading. Only instances that sell licenses (NOTEFEED_PAYMENT_PROVIDER set) see a change; self-hosted instances without one are as before.

    Web UI

    • Free tier usage: on an instance that sells licenses, the License row in a feed's settings reads "Free tier · N of 1000 notes" with a usage bar. The feed's page warns from 90 % of the cap and, at the cap, says that each new note drops the oldest one, with a link to the license page. Shown to whoever can post, never in RSS or on the read pages (#183).

    API and clients

    • GET /api/v1/feeds/{feed} and the MCP server's feed tools return free_tier: { notes, cap }, or null for a licensed feed or an instance that sells no licenses. The JS and Python clients carry the new field.

    Docs

    • ADR 0031: configuration stays in environment variables (#189).
    • ADR 0032: notefeed stays outside the EU Cyber Resilience Act, and the four facts that keep it there (#42).

    Pull requests

    • #190 ADR 0031, configuration stays in environment variables
    • #191 Show a free feed's notes against the cap, and say so on the feed near it
    • #192 ADR 0032, notefeed stays outside the Cyber Resilience Act

Oct 14

  1. notefeed 0.14.0

    Released 2026-10-14 · on GitHub

    v0.14.0: pictures shrink before upload

    Nothing to do when upgrading. A new optional setting, NOTEFEED_SHRINK_IMAGE_BYTES, sets the size the web pages shrink a picture to before uploading it: 1 MiB by default, 0 sends pictures as they are, never more than NOTEFEED_MAX_IMAGE_BYTES.

    Web UI

    • Pictures shrink before upload: the title image, the compose box and the note editor scale a picture down (to JPEG if need be) until it fits NOTEFEED_SHRINK_IMAGE_BYTES, so a photo straight from a phone's camera is taken. GIFs are sent as they are.
    • Title image: works from a phone; the row shows "Uploading…" and its own refusals, which were at the foot of the page, out of a phone's view. A hint says the feed's pictures can be picked there.

    API and clients

    • The API is unchanged; the client packages take the version of the release.

    Pull requests

    • #188 NOTEFEED #187: Shrink pictures before upload; title image works from a phone
  2. notefeed 0.13.0

    Released 2026-10-14 · on GitHub

    v0.13.0: a redesigned web app

    Nothing to do when upgrading: no settings, storage or API changes. Operators may want their privacy page to mention that the browser now remembers the feeds it opened (local storage, never sent to the server; see ADR 0030).

    Web UI

    • A new look with the same identity: notes as cards, icons where an icon is clear, light and dark.
    • Feed page: on a wide screen, your feeds and the About & legal menu on the left, the composer and the timeline in the middle, and the feed's details, read link and tags on the right. On a phone, a chat-style bar at the bottom posts a note directly; + opens the full composer.
    • Your feeds: the feeds a browser opened are listed in a switcher, the left column and on the start page, remembered in the browser only.
    • Settings as grouped rows (Profile, Sharing, Privacy & access, License, Danger zone), still working without JavaScript.
    • Single note: Edit, Copy link, Report and Delete in an action bar, docked on a phone, in the right column on a wide screen. One Preview toggle replaces the Write and Preview tabs.
    • License, imprint, privacy and terms pages redesigned. The footer links are also behind an About & legal menu.
    • Android: an installed notefeed is in the share sheet for text and links, and opens the chosen feed's composer with them.

    API and clients

    • The client packages are unchanged and take the version of the release.

    Pull requests

    • #184 NOTEFEED #42: the sandbox's cancel and refund deliveries as tests
    • #186 NOTEFEED #185: redesign the web app
  3. notefeed 0.12.1

    Released 2026-10-14 · on GitHub

    v0.12.1: managing a license subscription, cancel at the provider on refund

    Nothing to do when upgrading. A self-hosted instance without a payment provider is unchanged.

    Hosted service

    • Manage subscription by key: on an instance that sells licenses, /license opens the provider's customer portal for whoever has the key (cancel, payment method, invoices), through POST /api/licenses/portal.
    • A refund also cancels the subscription at the provider, which otherwise keeps a refunded subscription running.
    • /license shows the free and licensed tiers and the price, and the footer links it while licenses are sold; the feed settings confirm an entered key.

    API and clients

    • The client packages are unchanged and take the version of the release.

    Pull requests

    • #182 NOTEFEED #42: manage a subscription by key, cancel at Creem on refund, price on the license page

Oct 13

  1. notefeed 0.12.0

    Released 2026-10-13 · on GitHub

    v0.12.0: /health also checks the image store, a terms page, and licenses per feed for the hosted service

    Nothing to do when upgrading: without new settings an instance behaves as before, except for the two points under "Read before upgrading".

    Read before upgrading

    • /health can now answer 503 because of the image store: with NOTEFEED_IMAGES set to fs or s3, the check also asks that store (a folder read, or one listing of at most one object, capped at 3 seconds). An instance whose bucket or keys are wrong was ok before and is unavailable now. With S3 billed per request, a probe every 30 seconds is about 2,900 listings a day.
    • terms and license are reserved feed names: posting to them answers 400. A feed that already has one of these names is no longer reachable under it.

    For operators

    • /health says which part failed: the body gains checks (storage, images), each ok or unavailable. See Health check.
    • A terms page: NOTEFEED_TERMS_FILE names a Markdown file shown at /terms and linked in the footer, next to the imprint and the privacy page. See Imprint, privacy page and terms.

    Hosted service

    • Licenses per feed (ADR 0029): the server can now tell a licensed feed from a free one. This is for notefeed.me and is off unless a payment provider is configured; a self-hosted instance has no limits and nothing changes for it.

    API and clients

    • A new answer 402 license_required on posting a note, editing a note and changing the feed password, only on an instance that sells licenses. The OpenAPI description and the JS and Python clients are regenerated for it; the client packages are otherwise unchanged and take the version of the release.

    Pull requests

    • #181 NOTEFEED #42: licenses per feed on the hosted service
    • #180 NOTEFEED #174: GET /health also checks the image store

Oct 12

  1. notefeed 0.11.0

    Released 2026-10-12 · on GitHub

    v0.11.0: a distroless image (read before upgrading), a security fix in Next, a security policy and an SBOM per release

    This is the server of 0.10.2 and 0.10.3 under the number it should have had: the image changes in ways an operator can notice, so it is a minor release. 0.10.2 and 0.10.3 stay published and are the same server.

    Read before upgrading

    • The image is distroless: Node and the server, no shell, npm or package manager (ADR 0028), so a scan of it reports what notefeed brings and nothing else. Two things stop working: a healthcheck: of your own in the compose file that calls wget or curl (remove its test: line; the image's own check does the same), and docker exec <container> sh. The data folder, PUID/PGID and user: behave as before.

    Security

    • Next.js 16.3.8 closes six advisories in 16.3.7, among them cache poisoning of statically rendered pages and a server-side request forgery in image optimisation (GHSA-cjq9-62q9-8jv4, GHSA-4jqv-mc3x-m676, GHSA-mcj8-r9mp-w47p and three with less reach). Upgrade.
    • A security policy: SECURITY.md says how to report a vulnerability privately and that only the newest release gets fixes.

    For operators

    • An SBOM per release: two CycloneDX files are attached below, one for the server's npm dependencies and one for what is in the image; the image carries an SBOM and a provenance attestation as well. See Security fixes and SBOM.
    • A daily check of the dependencies and the published image for known vulnerabilities runs in the repository.

    The client packages are unchanged; they take the version of the release.

Oct 11

  1. notefeed 0.10.3

    Released 2026-10-11 · on GitHub

    v0.10.3: the release of 0.10.2 with its client packages

    0.10.2 was tagged with a stale uv.lock, so its client packages were never published. The server is the same; the notes of 0.10.2 apply and are repeated here.

    Security

    • Next.js 16.3.8 closes six advisories in 16.3.7, among them cache poisoning of statically rendered pages and a server-side request forgery in image optimisation (GHSA-cjq9-62q9-8jv4, GHSA-4jqv-mc3x-m676, GHSA-mcj8-r9mp-w47p and three with less reach). Upgrade.
    • A security policy: SECURITY.md says how to report a vulnerability privately and that only the newest release gets fixes.

    For operators

    • The image is distroless: Node and the server, no shell, npm or package manager (ADR 0028), so a scan of it reports what notefeed brings and nothing else. Two things stop working: a healthcheck: of your own in the compose file that calls wget or curl (remove its test: line; the image's own check does the same), and docker exec <container> sh. The data folder, PUID/PGID and user: behave as before.
    • An SBOM per release: two CycloneDX files are attached below, one for the server's npm dependencies and one for what is in the image; the image carries an SBOM and a provenance attestation as well. See Security fixes and SBOM.
    • A daily check of the dependencies and the published image for known vulnerabilities runs in the repository.

    The client packages are unchanged; they take the version of the release.

  2. notefeed 0.10.2

    Released 2026-10-11 · on GitHub

    v0.10.2: a security fix in Next, a distroless image, a security policy and an SBOM per release

    Security

    • Next.js 16.3.8 closes six advisories in 16.3.7, among them cache poisoning of statically rendered pages and a server-side request forgery in image optimisation (GHSA-cjq9-62q9-8jv4, GHSA-4jqv-mc3x-m676, GHSA-mcj8-r9mp-w47p and three with less reach). Upgrade.
    • A security policy: SECURITY.md says how to report a vulnerability privately and that only the newest release gets fixes.

    For operators

    • The image is distroless: Node and the server, no shell, npm or package manager (ADR 0028), so a scan of it reports what notefeed brings and nothing else. Two things stop working: a healthcheck: of your own in the compose file that calls wget or curl (remove its test: line; the image's own check does the same), and docker exec <container> sh. The data folder, PUID/PGID and user: behave as before.
    • An SBOM per release: two CycloneDX files are attached below, one for the server's npm dependencies and one for what is in the image; the image carries an SBOM and a provenance attestation as well. See Security fixes and SBOM.
    • A daily check of the dependencies and the published image for known vulnerabilities runs in the repository.

    The client packages are unchanged; they take the version of the release.

  3. notefeed 0.10.1

    Released 2026-10-11 · on GitHub

    v0.10.1: a health check, and 410 for a removed feed

    For operators

    • A health check: GET /health answers 200 {"status":"ok"} when the instance and its storage answer, 503 {"status":"unavailable"} when the storage does not. Always on, no password or token, logged at debug. POST /health answers 405 now.
    • The image has a HEALTHCHECK on it, so docker ps and monitors that read Docker's health status (such as Beszel) show healthy or unhealthy without any setup.

    API

    • The read API answers 410 for a feed the operator removed.

    Docs

    • A page that compares notefeed to ntfy, Gotify, chat webhooks and note-taking apps.
    • The hosted service's docs say how to report content and what happens then.

    Client packages 0.10.1 (PyPI and npm notefeed)

    • See the pull requests below.

Oct 10

  1. notefeed 0.10.0

    Released 2026-10-10 · on GitHub

    v0.10.0: a report page, the operator's takedown, and private files

    For operators

    • A Report link on every note (NOTEFEED_REPORT_URL, a URL template with {read_id}, {note_id} and {file}), on the feed page, the note page and the read-only view. Unset: no link. notefeed stores no reports.
    • A report page of notefeed's own: NOTEFEED_REPORT_ENDPOINT names the endpoint of a form in an inbox you run (such as noticebox), and /report shows the form and posts there, with the note's ids in hidden fields. With the endpoint set and no template, the Report link opens this page.
    • The operator's takedown: POST /api/operator/takedown removes a feed for good, leaves a tombstone and blocklists its images' hashes.
    • NOTEFEED_IMAGE_UPLOADS=0 refuses every image upload with 403 images_off.
    • POST /api/operator/images/move moves image bytes into the configured store.
    • Files are served private, no-cache, never from a shared cache.
    • One log line per request, without the feed name.

    Web UI

    • Write and Preview tabs on the compose box and the editor.
    • The note box places the cursor behind a new picture's reference in the same step.

    Client packages 0.10.0 (PyPI and npm notefeed)

    • See the pull requests below.

    Pull requests since v0.9.3

    • #169 NOTEFEED #156: a report page of notefeed's own that posts to the operator's inbox
    • #168 NOTEFEED #155: the operator's takedown, with a tombstone for the feed and a blocklist for its images
    • #167 NOTEFEED #154: a Report link on every note, from the NOTEFEED_REPORT_URL template
    • #166 NOTEFEED #152: NOTEFEED_IMAGE_UPLOADS=0 refuses every image upload with 403 images_off
    • #162 NOTEFEED #146: Write and Preview tabs on the compose box and the editor
    • #165 NOTEFEED #164: the note box places the cursor behind a new picture's reference in the same step, not a frame later
    • #163 NOTEFEED #128: POST /api/operator/images/move moves image bytes into the configured store
    • #161 NOTEFEED #153: files are served private, no-cache, never from a shared cache
    • #151 NOTEFEED #150: one log line per request, without the feed name

Oct 8

  1. notefeed 0.9.3

    Released 2026-10-08 · on GitHub

    v0.9.3: a notice on the start page, and a GitHub link in the footer

    For operators

    • A notice on the start page: NOTEFEED_NOTICE_FILE names a Markdown file of your own. Its text is shown as a red warning banner on the start page, above the introduction: the place to say that a service is still being built, or what you do not promise. It follows the rules of the imprint and the privacy page: read on every request, at most 256 KiB, raw HTML stays text, and the start-up log names the setting when its file cannot be read. Without a file, or with an empty one, the start page is unchanged.

    Web UI

    • Footer: a link to the project on GitHub, after Docs.

    Client packages 0.9.3 (PyPI and npm notefeed)

    • No changes; the version follows the server's.
  2. notefeed 0.9.2

    Released 2026-10-08 · on GitHub

    v0.9.2: the imprint and the privacy page are your own files

    The imprint and the privacy page come from the operator

    • Two new settings, NOTEFEED_IMPRINT_FILE and NOTEFEED_PRIVACY_FILE, each name a Markdown file. With a readable file, /imprint or /privacy shows it and the footer links to it.
    • Without a file there is no such page and no footer link. The image no longer contains the texts of the hosted service.
    • The file is read on every request, so an edit shows at once.
    • imprint and privacy are now reserved feed names.

    If you run your own instance

    Until now your instance showed the imprint and the privacy text of notefeed.me. After this update both pages are gone until you set the two settings. See "Imprint and privacy page" in the self-hosting docs.

Oct 6

  1. notefeed 0.9.1

    Released 2026-10-06 · on GitHub

    v0.9.1: notefeed has moved to its own organisation

    Nothing changes in how notefeed works. This release exists so that everything is published from the new home.

    The project moved

    • Repository: github.com/notefeed/notefeed (was Marceltov/notefeed). The old address redirects; issues and pull requests kept their numbers.
    • Container image: ghcr.io/notefeed/notefeed, from this release on. ghcr.io/marceltov/notefeed stays at 0.9.0 and gets no more updates: change the image: line in your compose file to keep upgrading. Nothing else in your setup changes.
    • Docs: still at https://docs.notefeed.me.

    Client packages 0.9.1 (PyPI and npm notefeed)

    • No code changes. The packages' repository and issue links point to the new address.
  2. notefeed 0.9.0

    Released 2026-10-06 · on GitHub

    v0.9.0: a note and its pictures in one request, storage in a database, images in an object store

    A note with its pictures is one request

    • Multipart posts: POST /api/v1/feeds/{feed}/notes (and POST /{feed}) and PUT on a note also accept multipart/form-data: an optional text part, up to 10 file parts and alt.<filename> fields. The server checks everything before the first write and removes what it stored if a later write fails. A raw single-file request is unchanged.
    • Every caller uses it: MCP post_note, both clients (attachments), both CLIs (--attach) and the web compose box and editor.
    • Stricter text rules: names, titles, alt texts, tags and feed settings are one line with no control or text-direction override characters. A text sent with pictures is read in a worker with a time limit (NOTEFEED_PARSE_TIMEOUT_MS).
    • Changed answers: a malformed multipart body is 400; a title or alt text with a forbidden character is 400; the MCP request body limit is 16 MiB.

    Storage backends (new)

    • NOTEFEED_STORAGE chooses where feeds and notes are kept: fs (default, unchanged), sqlite or postgres. The database backends need NOTEFEED_SECRET; with PostgreSQL several containers can share the data. A new instance on a database starts empty: moving between backends is not built.
    • NOTEFEED_IMAGES chooses where a database backend keeps image bytes: db (default), fs (a folder) or s3 (any S3-compatible object store; there is no default endpoint). Going from db to fs or s3 needs no move.
    • Cleaning up the image store: with NOTEFEED_OPERATOR_TOKEN set, GET /api/operator/images/unreferenced reports the image files or objects that no note refers to, and DELETE removes them.
    • Reading costs less on the file backend: a feed's folder is listed once per request, and a stray folder or link in it no longer breaks the listing.

    Operations

    • Metrics: GET /metrics in the Prometheus format, off unless NOTEFEED_METRICS=1, with an optional NOTEFEED_METRICS_TOKEN. The docs include a Prometheus and Grafana setup.
    • Docs are restructured into sections with short pages.
    • Web UI fix: adding an image no longer takes the focus back from the title or tags field.

    Client packages 0.9.0 (PyPI and npm notefeed)

    • post() sends the text and its attachments in one request; content may be empty for pictures only. The clients no longer check file names themselves: the server decides.
    • Upgrade: a 0.9.0 client needs a 0.9.0 server (an older server answers 415 to multipart). post() with alt or name together with attachments is a ConfigError.

    The container image is moving. This is the last release published as ghcr.io/marceltov/notefeed. Later releases are published as ghcr.io/notefeed/notefeed; change the image line in your compose file when you next upgrade.

Oct 3

  1. notefeed 0.8.0

    Released 2026-10-03 · on GitHub

    v0.8.0: a note is a file, pictures are notes, and a note can bring its pictures

    A note is a file (breaking)

    • One API for every type. POST /api/v1/feeds/{feed}/notes (and POST /{feed}) takes the file's bytes as the body and its exact Content-Type (text/markdown, image/png, image/jpeg, image/gif or image/webp); the body is checked against the type. Metadata is X-Note-* headers. PUT replaces a note's content and PATCH changes its title and alt text. The JSON and form post bodies are gone, so a script that relied on curl's default type needs -H "Content-Type: text/markdown".
    • Pictures are notes of their own, listed in the feed, shown on the note page and sent to RSS readers as enclosures. A note's JSON has type, file, file_url, size, title and, for text types, content; kind and markdown are gone. Every note can have a title.
    • Storage: content is kept as posted with its metadata in a sidecar file, and note ids carry a UUID v7 so notes of the same second keep their order.
    • Feeds: a feed's read id can be chosen when it is created and changed later; files are served under it, and relative ![](file) links follow it, also in RSS.
    • Web UI: the compose box and the editor post and edit every note through this API (it needs JavaScript), and a tags field sits next to the Add image button.

    Pictures with a note (new)

    • Attachments: attachments on post() in both clients, notefeed post --attach PATH in both CLIs and attachments on the MCP post_note tool post the pictures first, one note each, then the text, with ![](name) swapped for each file name (a picture the text never refers to is added at the end). Everything checkable is checked before the first request. If an upload fails, the error names the picture and lists those already posted; the text is not posted and nothing is rolled back.
    • MCP: post_file posts any accepted file and replaces upload_image.

    Client packages 0.8.0 (PyPI and npm notefeed)

    • post(content, type=…), edit(id, content) and update(id, title, alt) work for every kind of note; notefeed post --file replaces notefeed image. post() returns attachments (empty without any).
    • Upgrade: these clients speak the file API, so a 0.8.0 client needs a 0.8.0 server. Compare the exact result of post() in tests: it now has attachments.

Oct 2

  1. notefeed 0.7.0

    Released 2026-10-02 · on GitHub

    Tags on notes, per-feed passwords, editing and deleting, images, feed settings, and optional sign-in.

    Tags

    • Label a note when you post it: a tags array in a JSON body, a repeated tags form field, the X-Note-Tags header for a raw body, or the MCP post_note tags argument. At most 10 per note, each 1 to 32 characters of lowercase letters, digits, -, _, . and : (so env:prod works); capitals are folded and duplicates dropped.
    • Filter with ?tag=ci on the note list, the read API, MCP list_notes, the feed and read-only pages, and the RSS feed (/r/<read id>/feed.xml?tag=ci), so a reader can subscribe to one kind of note.
    • Shown next to the title as links, in the API's note JSON (tags) and as <category> in RSS. Tags are free labels, not verified, and public with the note. An edit keeps them; they can't be changed after posting.

    Notes and feeds

    • Per-feed passwords: a feed can have its own password, set by its first post.
    • Edit and delete notes, over the API, the web UI and MCP.
    • Feed settings and deletion: a title, description and title image, and deleting a whole feed. New feeds get a stored random read id.
    • Images in notes, uploaded to a feed and served under its read id.
    • Reserved feeds with a stable read id.
    • Web UI: a settings page, header icons, a footer with docs, imprint and data privacy pages, a web manifest, favicon and share image.

    Sign-in

    • Optional OIDC sign-in with a verified sender on notes, with several providers at once. Private by default: without it nothing about a person is stored.
    • Logging through pino across the backend.

    Client packages 0.7.0 (PyPI and npm notefeed)

    • post takes tags, notes and read_notes / readNotes take tag, and notefeed post --tag / notefeed notes --tag do the same. Note has a tags list.
    • Also new since 0.6.0: edit, delete, image upload, feed settings and per-feed passwords in the clients and the command.
    • Upgrade: Note.tags is always present in the API, so a 0.7.0 client expects a 0.7.0 server.

Oct 1

  1. notefeed 0.6.0

    Released 2026-10-01 · on GitHub

    An MCP endpoint, with OAuth login for locked instances.

    MCP

    • AI assistants can post and read notes at /mcp. Three tools: post_note, list_notes and get_note. The feed name is a parameter of each tool, so one endpoint serves every feed. Posting follows the same rules as the HTTP API: size limit, rate limit, caps, and the first post creates the feed.
    • Claude Code: claude mcp add notefeed --transport http https://notes.example.com/mcp. On an instance with a password, add --header "Authorization: Bearer <password>".
    • Claude.ai and Claude Desktop: add a custom connector with the /mcp URL.
    • The endpoint speaks MCP 2026-07-28 and nothing older. An older client gets a 400 naming the supported version.

    OAuth 2.1 login

    • For clients that can't send a header. On an instance with a password, a connector opens notefeed's own login page, which names the client and the host it returns to. Enter the instance password and press Allow. On an open instance these endpoints answer 404.
    • Nothing is stored. Client ids, codes and tokens are signed with a key derived from the server secret and the password. Changing NOTEFEED_PASSWORD signs every client out.
    • Lifetimes: a code lasts 5 minutes and works once, an access token 1 hour, a refresh token 30 days and is replaced each time it's used.
    • OAuth needs the instance's public https:// address: set PUBLIC_URL, or NOTEFEED_TRUST_PROXY=1 behind a reverse proxy.

    Changed: forwarded headers need NOTEFEED_TRUST_PROXY

    • Without PUBLIC_URL, notefeed used to build links from X-Forwarded-Proto and X-Forwarded-Host on any connection, so a client could pick the host in RSS links, API responses and redirects. It now uses them only with NOTEFEED_TRUST_PROXY=1, and otherwise the Host header over http.
    • Behind a reverse proxy without PUBLIC_URL: set NOTEFEED_TRUST_PROXY=1 or PUBLIC_URL, or links will come out as http://.

    Client packages 0.6.0 (PyPI and npm notefeed)

    • No changes since 0.5.0. The version follows the release.

    Under the hood

    • oauth is a reserved feed name.
    • ADR 0007 records the MCP endpoint and OAuth decisions.
  2. notefeed 0.5.0

    Released 2026-10-01 · on GitHub

    Feeds, read links and a REST API.

    Breaking: this release replaces the single token-protected feed of 0.3. NOTEFEED_TOKEN, /api/notes and /feed.xml are gone, and the client packages change accordingly (see "Upgrading" in the client docs).

    Feeds

    • One instance, many feeds. A feed is identified by its name: post to POST /<feed>, read it at /<feed>. There are no accounts. The name is the write key, so pick one that's hard to guess (the start page suggests one).
    • Read links. Every feed has a read-only link, /r/<read id>, plus RSS at /r/<read id>/feed.xml. They show the notes but never the feed's name, so they're safe to share or put in a feed reader.
    • Optional instance password (NOTEFEED_PASSWORD): it locks posting and the web UI, while read links stay public. Wrong passwords are rate-limited, and after logging in you return to the page you came from.
    • Limits for public instances:
      • posts are rate-limited per client (NOTEFEED_RATE_LIMIT, NOTEFEED_TRUST_PROXY behind a proxy)
      • NOTEFEED_MAX_FEEDS and NOTEFEED_MAX_NOTES_PER_FEED are optional caps
      • bodies are capped while they stream in

    REST API

    • Versioned and documented under /api/v1: post notes, list a feed's notes as JSON with paging (limit, before → next), get one note, and read by read id without a password. Errors are JSON with a stable code.
    • Self-describing: each instance serves its OpenAPI description at /api/v1/openapi.json, and docs.notefeed.me renders it. It's generated from the server's code.
    • curl -F markdown=@note.md works, and so does curl -d. HEAD works on every GET endpoint.

    Client packages 0.5.0 (PyPI and npm notefeed)

    • Generated from the API description, with a small Client on top: post, notes() (walks every page), note, the read-id variants, and from_env() / fromEnv(). Errors are classes mapped from the API's code, and a redirect or a non-API answer is an error, never a silent success.
    • New command: notefeed notes [--limit N] [--json].
    • Python now needs 3.11 or newer and depends on httpx. Node still has no dependencies.

    Web UI

    • A start page to open a feed, a page per feed, and read-only views.
    • The compose box works without JavaScript and shows errors inline with it.

    Under the hood

    • The server code is a framework-free backend behind a single boundary module.
    • Every POST is handled by one write path, routed by method and path.
    • Architecture decisions are recorded in docs/adr (0001–0006).
    • End-to-end tests run in a real browser against the production build.

Sep 30

  1. notefeed 0.3.0

    Released 2026-09-30 · on GitHub

    New license, new home.

    • The notefeed server (web app and Docker image) is now licensed under AGPL-3.0. Self-hosting stays free. Anyone running a modified version as a service must publish their changes.

    • The client packages (PyPI and npm notefeed) are licensed under Apache-2.0.

    • Versions up to 0.2.x remain under the MIT License.

    • The documentation moved to https://notefeed.me.

    • The package metadata now has homepage, issues and changelog links, and keywords.

    • The Docker image no longer bundles the unused sharp image library, so it is about 70 MB smaller (264 MB).

  2. notefeed 0.2.0

    Released 2026-09-30 · on GitHub

    First tagged release of notefeed.

    • Post markdown notes over HTTP (POST /api/notes, bearer token) or in the web UI; read them back as RSS at /feed.xml.

    • Every note is a plain .md file. With the ./data bind mount the files belong to you, so you can grep them or keep them in git.

    • Client packages for Python (pip install notefeed) and Node (npm install notefeed), each with a notefeed post command.

    • Documentation: https://marceltov.github.io/notefeed/

    • The URL and token are set once, when you create the Client. The libraries no longer read NOTEFEED_URL / NOTEFEED_TOKEN; only the notefeed command does.

    • The top-level post() helper was removed. Use Client(...).post(markdown).