# Leumas Docs — @leumas/docs

The public Leumas knowledge bank -- generated reference, downloadable agent skills and a flat-file read API for coding agents, served at docs.leumas.tech.


**Documentation as a product — generated, not hand-written.**
Served three ways: to humans as a site, to agents over MCP, to machines over HTTP.

`docs.leumas.tech`, **hosted through Imperium on the Leumas-run Studio**.
Architecture: [APPLIANCES.md](../../APPLIANCES.md) §8 · [PLATFORM.md](../../PLATFORM.md)

---

## Core functionality

1. **Generated reference** — crawls the workspace for every `README.md`, `package.json`, adapter and
   MCP `server.json`, nav manifest, route manifest, and Imperium mode schema. One source of truth that
   updates as the ecosystem grows.
2. **The human site** — searchable docs on `@leumas/ui` + `@leumas/theme`, served as an Imperium
   config like every other Leumas site.
3. **The `leumas-docs` MCP server** — so Claude, Cursor and any coding agent can read Leumas docs
   directly. Uses the **existing** MCP loader; no new mechanism.
4. **The read API** — `GET /api/docs/*` (search · page · symbol) so other apps and agents can consume
   it over plain HTTP.
5. **Leumaepedia** — the wiki, absorbed from Studio's `knowledge` domain.
6. **Build-knowledge for agents** — the half of the Knowledge Bank that tells AI agents *how to build
   with Leumas*, not just what Leumas is.

## What it must never do

| Never | Because |
|---|---|
| Hand-maintain a page that could be generated | it will go stale. The whole point is derivation |
| Be its own hosting stack | it's an Imperium config like every other Leumas site |
| Duplicate the Knowledge Bank | it *renders* `shared/services/knowledge`, it doesn't fork it |
| Invent an MCP mechanism | `shared/engines/mcp/src/loader.js` already walks a dir and loads `server.json` + `tools/*` |

## Sources it derives from

| Source | Gives |
|---|---|
| `products/*/README.md` | the six products — core functionality, file trees, roadmaps |
| `shared/{packages,engines,services}/*/README.md` + `package.json` | every library, module and backend |
| `shared/engines/adapters/**` | domain packs and knowledge banks |
| `shared/engines/mcp/mcp-servers/*/server.json` | every MCP server and tool, with `price` |
| `shared/packages/config-registry/src/{modes,dataSchemas}.js` | the 30 Imperium modes and their fields |
| `products/leumas-studio/src/admin/nav.manifest.js` | every Studio surface |
| `shared/services/knowledge/` | domain knowledge + build-knowledge |
| `CONTROL-PLANE.md` · `PLATFORM.md` · `APPLIANCES.md` · `CLAUDE.md` | the architecture of record |
| `/index/*` | the live registry — apps, tools, capabilities, chatbots |

## Composes

```
@leumas/ui  @leumas/theme        the st- kit + tokens
@leumas/api-client               reads /index/* and /api/docs/*
@leumas/config-registry          rendered as an Imperium config
@leumas/index-service            the createIndexRouter({sources}) pattern the read API copies
@leumas/mcp                      the loader that picks up the docs server automatically
```

## File tree

```
products/leumas-docs/
├── package.json [todo] DOES NOT EXIST YET
├── vite.config.js [todo]
├── index.html [todo]
├── README.md [done] this file — currently the only file
├── scripts/
│ └── generate.mjs [todo] crawl the workspace → docs/*.json
├── docs/ [todo] generated. gitignored
└── src/
 ├── main.jsx [todo]
 ├── App.jsx [todo] search · sidebar · page · symbol
 └── pages/ [todo] Package · Engine · Service · Product · Mode · MCP · Wiki

shared/engines/mcp/mcp-servers/leumas-docs/ [todo] the MCP server
├── server.json                                    name · description · tools[] (+ price)
└── tools/
    ├── searchDocs.js                              q → ranked pages
    ├── getPage.js                                 slug → content
    ├── listPackages.js                            every @leumas/* + what it does
    ├── getSymbol.js                               an export → where it lives + its signature
    └── howDoI.js                                  a task → the build-knowledge recipe

shared/services/index/src/docsRouter.js [done] GET /api/docs/{search,packages,symbol,page}
shared/services/index/src/docsSite.js [done] the docs.leumas.tech Imperium row, ensured at boot
```

## Roadmap

### [todo] D1 · The generator

- Status: todo — `scripts/generate.mjs` — crawl every source in the table above into `docs/*.json`
- Status: todo — Run it in CI so it can never drift from the code
- Status: todo — Guard: a package with no README, or a README missing its core-functionality block, fails the build
- Status: todo — Provenance: every generated page links back to the file it came from

### [todo] D2 · The MCP server

*Do this second, before the site — it's the highest-leverage output and it reuses everything.*

- Status: todo — `shared/engines/mcp/mcp-servers/leumas-docs/{server.json,tools/*}` — the existing loader picks it
      up with **zero new mechanism**
- Status: todo — `searchDocs` · `getPage` · `listPackages` · `getSymbol` · `howDoI`
- Status: todo — Note: the loader is env-gated — without `MCP_SERVERS_DIR` set, **zero servers load**
- Status: todo — Verify from Claude Code: "what does `@leumas/entitlements` do?" answers from the graph, not guesses

### [done] D3 · The read API

- Status: done — `GET /api/docs/{search,packages,symbol,page}` — `@leumas/index-service/docs-router`, mounted in
      `leumas-api/src/app.js` with its own `docs:read` limiter (120/min)
- Status: done — Public read; no auth (documentation is not secret) — the gate is at BUILD time, in
      `docs.manifest.mjs`, which is the only place it can be verified
- Status: done — Publicly cacheable: success responses set `public, max-age=300`; a 503 or 404 does not

### [todo] D4 · The site

- Status: todo — Vite app on `@leumas/ui` + `@leumas/theme`
- Status: done — Publish as an Imperium config on `docs.leumas.tech` — the product-site pattern
      ([PLATFORM.md](../../PLATFORM.md) §5). Provisioned at boot by `ensureDocsSite`
      (`@leumas/index-service/docs-site`), `LEUMAS_ROLE=platform` only. Two things about that row are
      counter-intuitive enough to be worth stating here: it is on the **hosted** lane, not
      `firstParty`, because a first-party row has `hosting: null` and so structurally cannot carry a
      target; and its `ownerUserId` is deliberately **empty**, because a non-empty one arms a live
      entitlement re-check whose only possible effect on a platform site is an outage.
- Status: todo — SEO: canonical, JSON-LD `TechArticle`, per-page OG images, in the cluster sitemap index
- Status: todo — Server-rendered above-the-fold content — docs that need JS to show a heading don't rank

### [todo] D5 · Absorb Studio's `knowledge` domain (roadmap B7)

- Status: todo — Leumaepedia (`WikiSurface`) moves here
- Status: todo — The two `deferred: true` sub-items (Docs Feed, leumas-knowledge MCP) are **built here**, not there
- Status: todo — Delete the domain from Studio's nav

### [todo] D6 · Build-knowledge for agents

- Status: todo — Render the `shared/services/knowledge` build-knowledge as first-class pages — how to add a
      package, wire a router, write a plugin manifest, launch a site
- Status: todo — Every recipe cites the file it's derived from, so a stale recipe is detectable

## Status

Built and shipping: the generator (`scripts/generate.mjs`), the corpus under `dist/docs`, the
React site with SSR prerender, `llms.txt` / `llms-full.txt`, and the **`leumas-docs` MCP server**
(`shared/engines/mcp/mcp-servers/leumas-docs/`) with `searchDocs` · `getPage` · `getSymbol` ·
`listPackages` · `howDoI`.

`GET /api/docs/{search,packages,symbol,page}` is mounted in leumas-api
(`@leumas/index-service/docs-router`) and is a thin projection of those same tools over the same
scorer and the same corpus reader — `pnpm smoke:docs-api` asserts the two rank **identically**,
because a docs site and an agent that disagree cannot detect it from either side.

> [warning] **This section said "one file — this README. Everything above is unbuilt" long after it stopped
> being true**, and a reader believed it: a survey of the ecosystem reported the whole product as a
> stub while the corpus, the site and the MCP server were all shipping. A stale status line is worse
> than none, because it is the one part of a README people trust without checking. Unticked boxes
> below are the honest record of what is still open; this paragraph is not a substitute for reading
> them.


---
Source: products/leumas-docs/README.md
Canonical: https://docs.leumas.tech/p/products/docs
