Beta . Ortha CMS is in public beta. Every plan is free until it ends.
Get started
Menu
Public beta · free while it lasts · MIT

Content, composed from plugins.

A headless CMS you run yourself — with an AI assistant that asks before it acts.

npx create-orthacms-app
features, all in the MIT core
23
packages on npm
71
protocols: REST, GraphQL and MCP
3
permission keys, checked in the API
37

01 — Features

Built in, not bolted on. 23 features in the MIT core. None of them is paid-only.

See all 23 features

02 — Ortha CMS AI

An assistant that asks first.

It holds your permissions and nothing more. It never publishes — a person presses Publish.

ArticlesThe quiet return of night trains Published · up to date
The quiet return of night trains
Published EN · English Published Sep 20, 2026
Title *
The quiet return of night trains
Summary Changed
Sleeper routes that closed a decade ago are, it turns out, running again in quite a few places across Europe this year.
SEO description Changed
Empty
Cover image
cover-night-trains.jpg · Image · 2.4 MB
Body
From Vienna to Brussels, operators are betting that travellers will trade speed for a bed and a quiet morning arrival. We rode four of the new routes to find out what changed.
Ortha CMS AI
Ask about the content in this workspace. Ortha CMS AI can only see and change what your own role allows. Every change it makes is recorded and can be undone.
Tighten the summary and write the missing SEO description.
Thinking…
Read an entry · The quiet return of night trains 41ms
Read content types · article 18ms

The summary can lose half its words, and the entry has no SEO description yet. I have drafts for both — saving them needs your go-ahead.

Ortha CMS AI wants to change your content
content_propose_update
{
  "id": "e41f0a2b-…",
  "values": {
    "summary": "Sleeper routes that closed a decade ago are running again across Europe.",
    "seoDescription": "Night trains are back: which sleeper routes reopened, and why travellers are choosing them."
  }
}

Nothing has happened yet — it is waiting for you.

Updated an entry · 2 fields 63ms

Understood. Nothing was changed.

Tighten the summary and add an SEO description content.entry.update Saved
Summary WAS Sleeper routes that closed a decade ago are, it turns out, running again in quite a few places across Europe this year. NOW Sleeper routes that closed a decade ago are running again across Europe. SEO description WAS (empty) NOW Night trains are back: which sleeper routes reopened, and why travellers are choosing them.
This change was saved to your content.
Answer complete
Ask about your content…
Skills claude-sonnet-5

Enter to send, Shift+Enter for a new line

03 — Architecture

Plugins, not a monolith.

Every capability is a package on the same public contract your own code uses.

Host apps/server/src/plugins.ts 10 / 10 plugins

04 — Delivery

Three protocols, one API.

The same article, the same token, the same permissions — three ways in.

200 OK · 38 ms

Request

GET /api/v1/content/article/group/9b2d7c1e?locale=deAuthorization: Bearer orthacms_0TYI4Q…X-Workspace-Id: 3c1e5a…

Response

{  "id": "e41f0a2b-…",  "status": "published",  "locale": "de",  "localeGroupId": "9b2d7c1e-…",  "publishedAt": "2026-09-20T14:03:11.000Z",  "values": {    "title": "Die stille Rückkehr der Nachtzüge",    "slug": "nachtzuege"  }}

Request

POST /api/v1/graphql query {  article(localeGroupId: "9b2d7c1e-…", locale: "de") {    title    status    author { name }  }}

Response

{  "data": {    "article": {      "title": "Die stille Rückkehr der Nachtzüge",      "status": "PUBLISHED",      "author": { "name": "Mara Lind" }    }  }}

Request

POST /api/v1/mcp {  "jsonrpc": "2.0",  "method": "tools/call",  "params": {    "name": "content_get",    "arguments": {      "typeName": "article",      "localeGroupId": "9b2d7c1e-…",      "locale": "de"    }  }}

Response

{  "jsonrpc": "2.0",  "result": {    "structuredContent": {      "id": "e41f0a2b-…",      "status": "published",      "values": {        "title": "Die stille Rückkehr der Nachtzüge"      }    }  }}

05 — Questions

Asked before adopting it.

Is it really free?

Yes, in production too. Every feature is in the MIT core, with no time limit and no cap on people, records, API calls or bandwidth. A paid plan buys support, not features.

How many people can we add?

As many as you like on Community. After 1.0, the Team plan includes 10 members, then $3 each; Enterprise is unlimited.

Where does our content live?

In your own PostgreSQL database and your own storage. Query it, back it up or move it any time.

Can non-technical people use it?

Yes. Writers, editors and translators do everything in the admin, without touching code.

Can we work in more than one language?

Yes. Translation is built in, and fields that read the same in every language are written once.

Can we require somebody else to approve before publishing?

Yes, per content type: entries need a set number of approvals from someone other than the author before they go live. An edit asks for approval again.

What can the AI assistant see?

Only what the person using it can see. It holds exactly that person’s permissions, and it asks for approval in the conversation before it changes anything.

What do we need to run it?

PostgreSQL 16 and Node.js 22. No search cluster, message broker or cache.

06 — Install

One command. Five choices.

A keyboard wizard picks your adapters. Change any of them later in config.

npx create-orthacms-app
$ npx create-orthacms-app my-cms
Ortha CMS · Creating an app in ~/projects/my-cms
◆ Project
✔ App name my-cms
✔ Database URL postgresql://orthacms:orthacms@localhost:5432/my_cms
✔ Admin email admin@example.com
◆ Features
✔ Storage S3-compatible
✔ Copilot Claude (Anthropic), OpenAI-compatible endpoint
✔ Sign-in OpenID Connect single sign-on
✔ Protocols GraphQL content API, MCP server
✔ Mail SMTP relay
✔Files written
✔Git repository initialised
✔Dependencies installed
› cd my-cms
› docker compose up -d
› npm run migrate
› npm run dev → http://localhost:4200