Changelog
Releases land here, newest first. This page also feeds the site's RSS at /rss.xml.
Agents that read, flag, and connect
The MCP server gained three tools: list_docs and get_page let a connected agent read the whole documentation set as Markdown, and submit_feedback lets it flag a page that is wrong, non-destructively (the path is checked and the rate is capped). Every page's actions menu now offers Open in ChatGPT, Claude, or Perplexity with the page preloaded, plus one-click Add to Cursor and Add to VS Code that connect this site's MCP server. Which items appear is yours to set with contextual.options.
Banner, Expandable, and badges with icons
Three component additions: Banner for a top-of-page announcement (optionally dismissible, and it stays dismissed across pages), Expandable for lightweight nested disclosure, and Badge now takes an icon. Each draws from the bundled icon set.
Icons, group tags, and tab menus
The bundled Lucide icon set is now available to Icon, resolved to inline SVG at build time (no runtime, no CDN). Navigation gained group icons and tags, a default-expanded flag, and dropdown menus on tabs. The docs.json compatibility layer carries all of these across on migration.
Try it: the interactive API playground
Every API operation can now be called from its reference page. The Try It playground builds the request from the spec, sends it through an SSRF-safe proxy (or directly from the browser when the target allows CORS), and renders the real response, with the curl sample kept exactly in sync. Reader credentials stay in the browser and are never logged.
Brand assets follow the served URL
A host-assigned site URL now re-derives logo and favicon paths too: config resolution prefixes root-relative brand images with the authored URL's base path, and the override previously left that stale prefix in place, so a site authored for a subpath but served at a domain root pointed at brand images that did not exist.
Builds that explain themselves
Deployments now carry their build diagnostics: a failed build records why (parse errors, fetch failures, a hash mismatch), and a published build keeps its warnings, so "live, but three pages complained" is visible in any dashboard without log archaeology.
Instance AI defaults and host model tiers
Two small seams for operators of multi-site installs: READSMITH_AI_DEFAULTS
(JSON, the same shape as docs.yaml ai:) applies instance-wide when a site
configures nothing, and getAiServicesForSite accepts an ai override so a
host that owns model selection can serve tiers. Self-host behavior is
unchanged: a site's own config always wins over the instance default.
Search and Ask AI for every site
The AI stack now composes per site: getAiServicesForSite builds search,
Ask AI, and the MCP endpoint for any deployed site (rebuilt exactly when
its deployment changes), indexing runs against the site a publish names,
and reader signals record under the right site. A multi-site host serves
every tenant's AI through the same code path the single-site app uses;
single-site installs are unchanged.
Text surfaces for every site
The agent and crawler surfaces (llms.txt, llms-full.txt, robots.txt,
sitemap.xml, rss.xml, skill.md, the /md/ raw-Markdown mirror, and
/.well-known/skills) are now pure functions over a site's bundle in
@readsmith/serve, so a multi-site host serves them per tenant through
the exact code path the single-site app uses. Single-site output is
unchanged.
Immutable asset URLs
Pages now reference their images and downloads by fingerprinted URLs
(mark.3f9c2e1a04.svg), rewritten at build time from the same hashes the
asset manifest already carries. A fingerprinted URL names exact bytes, so
it is served with year-long immutable caching and can never go stale: a
changed image changes the URL, and the very next deployment's pages point
at it. Authored paths keep working with short freshness for links that
live outside the site.
Also in this release: asset storage is scoped per site, and retention now garbage-collects assets referenced only by pruned deployments, so rollback history keeps exactly what it needs.
Deployments carry their assets
Git-deployed sites now serve their images, fonts, and downloads. The build
ships a manifest of content-addressed asset keys inside the bundle, the
deploy stores each asset once (identical bytes are shared across
deployments), and serving streams them with strong ETags, so a repeat
visit revalidates without moving bytes. Local installs keep serving from
public/ exactly as before.
Webhooks route by repository
Push webhooks now enqueue a build for every site connected to the pushed repository and branch, not just the default site. A single-site install behaves exactly as before; a multi-site install fans out. Installation events likewise record the installation on every matching connection.
Multi-site builds
Two additions for installs that serve more than one site; single-site self-hosting is unchanged.
- Host-assigned site URLs: a host that owns where sites are reachable
(assigning domains to tenants) can override
site.urlper build, so the authored config never moves a site and a domain change is exactly one rebuild. Page URLs, base path, canonicals, and social metadata all follow - The git poller sweeps every connection: polling-mode deploys now cover all connected sites, one API call per site per tick, in sequence (a single-site install behaves exactly as before)
Render any site's bundle
A small addition to @readsmith/serve for hosts that serve more than one
site: renderPageFromBundle(bundle, slug) renders a page from any loaded
bundle (pure, no ambient site), and getBundle() exposes the default
site's bundle. Single-site serving is unchanged and delegates to the same
code path.
The serving core is a package
Everything the web app does at request time (site resolution, bundle
loading, the AI and git services, boot, and every text route from
llms.txt to the MCP endpoint) now lives in one server-only package,
@readsmith/serve. The Next app is a thin composition over it.
- Same site, byte for byte: every route's output is verified identical to 0.4.0; nothing changes for readers or operators
- Compose your own host: a custom server (or a future multi-tenant one) imports the same handlers and services the bundled app uses, instead of forking route files
- One shared instance of the database pool and site caches across the whole server, where the bundler previously duplicated them per route graph
Analytics, your way
Your analytics tool on your docs with one config block, plus identity-free reader signals recorded for you. See Analytics.
- Bring your own analytics: declare GA4, PostHog, Plausible, or Fathom in
docs.yamland the tags are compiled in with the Content-Security-Policy extended for exactly those hosts; loaders are async and never block a page - Search-gap logging: every search is recorded with a zero-result flag, so "what readers looked for and did not find" is one SQL query away
- Page feedback, persisted: the "was this page helpful" control now records its answer (path and verdict only)
- Nothing about the reader: no identity, no headers, no cookies in any of it, with 90-day retention defaults
S3-compatible storage
The compiled-site store now speaks S3: keep the zero-config local filesystem, or point the same port at Cloudflare R2, MinIO, or any S3-compatible bucket.
STORAGE_DRIVER=s3: five environment variables move the bundle store (deployments, render cache and all) into object storage; the local driver remains the default and needs nothing- Bundled MinIO, opt-in:
docker compose --profile s3 upadds MinIO with a console and creates the bucket on first start; the default two-service deployment is unchanged - Zero new dependencies: request signing is implemented against AWS's published test vectors and verified against real MinIO
- Instant deploys across instances: publishes and rollbacks now signal every running instance over Postgres, so multi-instance installs converge in milliseconds instead of waiting out a cache window
- Groundwork for serving many sites from one install (a host-to-site resolution seam and per-site bundle caching), invisible to single-site deployments
Deploy on push
Connect a GitHub repository and Readsmith becomes a deployment pipeline. See Deploy on push for the five-minute setup.
- Git-connected deployments: a push to the connected branch fetches that exact commit, builds it, and publishes atomically; readers only ever see the old site or the whole new one
- Two ways in: a GitHub App created for you by a one-click setup page, or a fine-grained personal access token with two environment variables
- Instant rollback: every deployment is an immutable snapshot; repointing is one command, and history prunes itself
- Races resolved correctly: when pushes overlap, the newer commit wins even if its build finishes first
- Incremental rebuilds: a persisted render cache means a one-page edit re-renders one page, and a shared-snippet edit exactly its dependents
- Polling fallback for instances GitHub cannot reach, and a manual
site:buildtrigger - Hardened fetching: repositories arrive as size-capped tarballs, never a git checkout; no symlinks, no submodules, nothing outside the build scratch
- Strict builds opt-in: fail the deploy instead of publishing a page error
- Search and Ask AI reindex automatically after every publish and rollback
- Monorepo-friendly:
docs.yamlat the repository root withcontent.rootpointing at your docs directory (this site now ships that shape)
First public release, in development
The version everything on this site describes. The headline surface:
- Precompiled MDX pipeline with deterministic, byte-identical builds
- The reading shell: Spectral and IBM Plex typography, first-class light and dark themes, zero JavaScript on prose pages
- Component library: callouts, accordions, tabs, steps, cards, code groups, frames, badges, and more
- Generated API reference from OpenAPI: single page or one page per operation, hybrid authored-plus-generated pages, data-model pages, inline operation embeds
- Search (Postgres full-text plus vectors) and Ask AI with cited answers, on your own model keys
- Agent outputs from every build: llms.txt, llms-full.txt, per-page Markdown, an MCP server, and Agent Skills with a review-then-commit generator
- Self-host with one Docker Compose file;
docs.jsonconfig accepted for migration