Public Blog

A blog people read and AI models quote

A post is a wiki page with metadata. You write plain markdown, and the server builds a page with ready-made blocks, a markdown version for AI models, structured data and feeds. A lint checks the post before publication.

Key features

A post is a wiki page with metadata

The content lives in the wiki, and a separate metadata row holds the slug, description, author, tags, language, translation link, cover and the verification date. A wiki page without that metadata is not a post. A published post is available without signing in at /blog/{slug}.

Post blocks

Plain markdown is enough for callouts, a TL;DR, a quote with an author, a captioned image, code with a copy button, an FAQ, steps, a comparison table, charts from a table, Mermaid diagrams and a terminal window. The server generates the block HTML and sanitizes the author's text, so custom scripts, classes and identifiers never reach the page.

A markdown twin for AI models

Every post has a markdown version at /blog/{slug}.md, and the blog list is at /blog/index.md. A client that sends Accept: text/markdown gets the same document. Every graphic has a text source, so a model sees the chart data and the diagram description, not just a picture.

JSON-LD structured data

A post page carries BlogPosting and BreadcrumbList as JSON-LD. From the FAQ, steps and video blocks the server adds FAQPage, HowTo and VideoObject, and the language versions of a post are linked in the sitemap.

Atom, RSS and JSON feeds

The blog has /blog/feed.xml (Atom), /blog/rss.xml (RSS) and /blog/feed.json (JSON Feed) with the full text of the 20 newest posts, and readers find them in the page header. The /llms.txt file lists the newest posts live, with markdown addresses.

A post lint for AI readers

The lint checks the description, the TL;DR block, image alt text, heading order, descriptive link text, the verification date and the translation. The result is a list of problems with a line number and a level (error, warning, info) and a score from 0 to 100. The lint_blog_post MCP tool, the REST API and the monolynx blog lint command return the same result.

Publication behind a lint gate

Publishing is a separate operation: the lint runs first, then the post becomes public. A post with lint errors stays private, and the refusal names the rules to fix; the force parameter publishes anyway. Unpublishing takes the post and its markdown version off the web, while the slug and the date stay, so publishing again returns to the same address.

Blog permission

Only an account with the blog permission can publish a post, unpublish it or change its metadata. The permission belongs to the account, not to a role in a project, is off by default, and only a superuser grants or revokes it on the account edit page; a project owner or admin cannot. The same rule holds in the dashboard, MCP, the REST API and the CLI, also when a wiki page is marked public. An account without it gets a refusal (403 in the REST API), nothing is saved, and the blog write tools do not appear on its MCP tool list. Reading posts and the lint need only wiki read permission.

Draft preview

The "Post preview" button on a wiki page opens the draft in the look of the public blog before you tick "public page". Only a signed-in user with wiki read permission sees the preview, and its address carries a noindex header and stays out of the sitemap and the feeds.

The blog-post skill and a guide for any model

The /monolynx:blog-post skill leads a post from the brief through the draft and the lint to the preview, and publishes only after your explicit consent. The public guide /blog-authoring.md describes the block syntax, the lint rules and the connector operations, so a model without the plugin can write a post in this format too.

Access from the terminal

The monolynx blog command group (list, get, meta, lint, publish, unpublish) runs the same operations as the MCP tools, so you can handle posts from a script and from CI.

How it works

1

Write a draft in the wiki

Create a private wiki page with markdown content and post blocks. The draft preview shows it in the look of the blog.

2

Set the metadata

Give a description, a language, tags and a verification date. The first metadata save turns the wiki page into a post.

3

Run the lint

Fix the errors on the list until no problem of the level error is left. Warnings do not block publication.

4

Publish

The post goes live at /blog/{slug} together with its markdown version, structured data and feeds.

5

AI writes and publishes via MCP

Your AI agent goes through the same steps with the connectors and publishes only after you agree. The account the agent runs under needs the blog permission.

AI & MCP

The blog is built so that an AI agent can both write and read it. The agent sets post metadata, lints a post, publishes it and unpublishes it - 6 MCP tools.

Available MCP tools

list_blog_posts List blog posts with metadata, drafts included; published or draft filter
get_blog_post A blog post: metadata, public URLs and markdown content
set_blog_post_meta Post metadata: slug, description, author, tags, language, translation, cover, verified date; needs the blog permission
lint_blog_post Lint a post for AI: a list of problems with line and level, plus a score from 0 to 100
publish_blog_post Publish a post after the lint: refused on errors unless force; returns URLs and the lint score; needs the blog permission
unpublish_blog_post Unpublish a post: its address and its .md answer 404, the date and the slug stay; needs the blog permission

Technical details

Storage
The post content is the markdown of a wiki page in MinIO, the metadata (slug, description, tags, language, publication date) is in PostgreSQL.
Rendering
Markdown, then nh3 sanitization without class and id attributes. The server draws charts as SVG, and animated diagrams come from a closed list of components.
Public addresses
/blog/, /blog/{slug}, /blog/{slug}.md, /blog/index.md and /blog/feed.xml, /blog/rss.xml and /blog/feed.json. No session, no sign-in.
Stable addresses
Renaming a post does not change its address, and the previous address redirects (301). The list sorts posts by publication date.

Other modules

Try Monolynx

Free, open source, self-hosted. Deploy on your infrastructure in minutes.