Docus is a Nuxt documentation theme whose generated sites each publish an MCP server at /mcp
Write beautiful documentations with Nuxt and Markdown.
At a glance
- What is it?
- nuxt-content/docus is a MIT TypeScript workspace holding a documentation theme, a scaffolding CLI, and the docs site that documents both, built on Nuxt 4 with Nuxt UI 4 and Tailwind CSS 4. Every site it generates also serves a machine-readable surface: an MCP endpoint, a skills directory, and two llms.txt files.
- Who is it for?
- Docus is a good fit for a Nuxt shop that wants its documentation readable by its own users and by coding agents at the same time, and the machine-readable surface is the part that is more finished than the marketing suggests. Two things deserve a decision before you commit.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Vercel button clones a subdirectory of the docs repository, not the published package
There are two ways to start a Docus site and they do not go through the same code.
The local path runs a CLI from npm:
npx create-docus my-docs
npx create-docus my-docs -t i18n
cd my-docs
npm run devThe online path is a Vercel clone button, and the repository it points at is `nuxt-content/docus/tree/main/.starters/default`. That is a subdirectory of the documentation repository, not the `docus` package on npm and not the CLI. So one path executes `create-docus`, and the other copies a starter directory out of the docs repository.
The starters are treated as a separate artifact in their own right. The workspace has a `test:starter` script that runs `./scripts/test-starter.sh` as a shell script rather than a Vitest project, which is a different harness from the unit and smoke suites, and the `.starters/` directory sits in the repository root next to `cli/`, `layer/`, and `docs/`.
The result is that a project started online and a project started with the CLI are not demonstrably the same tree, and the README gives no way to tell from the outside which one you got.
Every generated site serves an MCP server, a skills directory, and two llms.txt files
The feature list carries three machine-readable outputs, and they are the reason this template is worth a second look.
A Model Context Protocol server is built in and mounted at `/mcp` on every site, so a documentation instance is queryable from an editor directly. The README's own documentation site links to its own endpoint in two forms, one plain and one carrying an `ide=vscode` parameter. Alongside it, a `skills/` directory is served at `/.well-known/skills/`, following the Cloudflare Agent Skills Discovery RFC, and the install command is a single line:
npx skills add https://your-docs-domain.comThird is the LLM-ready layer: `llms.txt` and `llms-full.txt`, generated automatically through the Nuxt LLMs module.
The loop is worth noting. The documentation that explains these features is itself a Docus site, so it already exposes its own MCP endpoint and skills directory. The README also asks you to install the Docus skill from GitHub with `npx skills add nuxt-content/docus`, which is a second distribution channel for the same template that bypasses npm entirely.
None of this comes with an access note. The feature list describes the endpoints as built in and says nothing about who can reach them.
Three release configs publish three artifacts from one workspace version
The repository root is a private pnpm workspace named `docus-workspace`, version 5.13.0, and it carries three separate release-it configurations: `.release-it.layer.json`, `.release-it.cli.json`, and `.release-it.json`.
The scripts show what each one is for, and the shape of the layer release is a single npm command chain:
"layer:release": "release-it --config .release-it.layer.json && cd layer && npm publish",
"cli:release": "release-it --config .release-it.cli.json && cd cli && npm publish",`layer:release` runs release-it with the layer config and then publishes from `layer/`; `cli:release` does the same for `cli/`; and the top-level `release` script chains both in sequence before running the root release-it.
The current state is consistent. Version 5.13.0 in the workspace matches the newest tag, v5.13.0, published on 2026-08-28. The master branch was last pushed on 2026-10-02, so roughly five weeks of commits exist above the tag. Since the CLI and the layer publish separately, a partial release is possible if the chain stops between the two, and the README does not say how to recover from that.
verify runs the unit project and leaves the smoke and starter suites out
The workspace has three test entry points and they are not equivalent.
`test` is `vitest run --project unit`, `test:smoke` is `vitest run --project smoke`, and `test:starter` is `./scripts/test-starter.sh`, a shell script. Vitest is configured through `vitest.config.mts`, so the unit and smoke runs share one config with two named projects, while the starter check bypasses Vitest entirely.
Now look at what the aggregate command covers:
"verify": "pnpm run dev:prepare && pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run docs:build",`verify` prepares the Nuxt types, lints, typechecks, runs the unit project, and builds the docs site. It does not run `test:smoke` and it does not run `test:starter`, so a green `verify` says nothing about the smoke project or about whether the starter still scaffolds correctly.
The rest of the tooling is at least explicit. `lint` is `eslint .` through a flat config at `eslint.config.mjs`, `typecheck` is `nuxt typecheck layer`, and `check:vercel-output` runs a separate script that inspects the Vercel output directory.
The docs site extends the local layer, so the documentation never runs the published package
Contributing to the CLI follows a different path from using the template, and the difference is more than the package manager.
git clone https://github.com/nuxt-content/docus
pnpm install
pnpm run dev`pnpm run dev` is not the docs dev server directly. It calls `docs:dev`, which is `cd docs && TMPDIR=/tmp nuxt dev --extends ../layer`, so the documentation site extends the layer directory in the working copy rather than resolving `docus` from npm. The same pattern runs through `dev:prepare`, which prepares three targets in turn, the layer, the docs, and a `playground/` directory, each with `--extends ../layer`.
Two consequences. The published layer and the documented one are never the same object in this workflow, so a change to `layer/` that breaks the published package can still build the docs site cleanly. And the contributor path uses pnpm throughout while the user path in the quick start uses `npm run dev`, so the lockfile you validate against is not the one a new project gets.
There is also a `playground/` directory that the README's package structure section does not mention, alongside `test/`, `scripts/`, `eslint.config.mjs`, `vitest.config.mts`, `pnpm-workspace.yaml`, and `.nuxtrc`.
Two meanings of internationalization in one feature list
The Internationalization bullet promises native i18n support with 20 or more locales, and qualifies it: the locales are for the assistant UI. That is the chat widget's interface language, not the range of languages your documentation can be written in.
Document language is a separate concern, handled by the starter template rather than a switch. `npx create-docus my-docs -t i18n` chooses a starter whose `content/` directory is organised per language, with `en/` and `fr/` subdirectories each holding `index.md` and a `guide/` folder. Without that flag the same content directory holds `index.md`, `getting-started.md`, and a flat `guide/` directory instead.
So changing the number of supported content languages is a project structure decision made at scaffold time, not a runtime configuration. The `nuxt.config.ts` file is listed among the optional additions, and the Nuxt i18n module is among the pre-configured dependencies, which means the module is present in the generated project even when the flat structure is used.
The distinction between the two is easy to miss from the feature list alone, and it decides whether translating your docs is a config edit or a directory restructure.
The Customizable bullet ends after a comma, with no third item
One entry in the fourteen-item feature list is incomplete. The Customizable line reads:
- **Customizable** - Theme variants, custom icons,and stops at the trailing comma. Whatever customization mechanism was going to be named third is not in the file. The two items that survive, theme variants and custom icons, do have visible support elsewhere: the workspace pins three Iconify icon sets as development dependencies, `@iconify-json/lucide`, `@iconify-json/simple-icons`, and `@iconify-json/vscode-icons`, which is how a Nuxt UI project gets its icon catalogue, and the theme variants are the Docus layer's own concern.
The dark mode entry is complete and unusually specific about behaviour: it names a `d` keyboard shortcut for toggling between the two modes. The search entry is equally concrete about its two tiers, client-side search by default with an optional FTS5 full-text backend. Those two are the model the truncated line does not meet.
Nothing else in the README fills the gap. The answer to how a custom icon or a new theme variant is registered is only in the documentation site at docus.dev, not in this file.
Search is client-side by default, and the FTS5 backend has no documented switch
The search feature has two layers and the README names both without separating them. Client-side search is the default. The optional tier is an FTS5 full-text search backend.
FTS5 is a module rather than a plain query interface, so the optional tier implies a different data path from the default one, not just an index that got bigger. Which module or endpoint serves it, what has to be installed for it to work, and whether it survives a static build are all unstated here. The README's answer to any of those is the documentation site.
This matters most for the static deployment path. The quick start's online option is a Vercel clone button, and the workspace carries a `check:vercel-output` script for inspecting the build output, which suggests output format is treated carefully enough to be checked automatically. A full-text backend that needs a server is the kind of feature that decides whether a site can be deployed as static files at all, and the README leaves that question open.
The i18n locale count has a similar shape. Twenty or more locales are promised for the assistant UI, and nothing states how many of them ship by default.
Editorial conclusion
Docus is a good fit for a Nuxt shop that wants its documentation readable by its own users and by coding agents at the same time, and the machine-readable surface is the part that is more finished than the marketing suggests. Two things deserve a decision before you commit. The MCP endpoint at /mcp and the skills directory are served by every generated site with no access control described anywhere, so treat them as part of your public surface and gate them yourself if the content is not meant to be public. And pin your dependency by version rather than tracking main: three artifacts publish from one workspace version through three separate release configs, and the verify script only covers the unit test project.
Frequently asked questions
What is Docus and what does create-docus generate?
Docus is a MIT licensed documentation theme and scaffolding CLI for Nuxt, written in TypeScript. Running npx create-docus my-docs produces a project with a content directory for markdown, a public directory for static assets, and a package.json. Adding -t i18n switches the content layout to per-language subdirectories.
Does a Docus site expose an MCP server?
Yes. Every site exposes a Model Context Protocol server at /mcp, built in through the MCP Toolkit, and a skills directory dropped into skills/ is served at /.well-known/skills/. The README does not describe any access control on either endpoint.
Which Nuxt stack does Docus build on?
The generated project is pre-configured with Nuxt 4, Nuxt Content, Nuxt UI 4, Nuxt Image, Tailwind CSS 4, Nuxt i18n, Nuxt LLMs, Nuxt OG Image, MCP Toolkit, and the Vercel AI SDK, which is the only entry marked optional. The Docus theme itself ships as the docus package on npm.
How do I contribute to the Docus CLI?
Clone the repository, run pnpm install, then pnpm run dev. That dev script calls docs:dev, which starts the documentation site with nuxt dev --extends ../layer, so the docs run against the layer directory in your working copy. Three release-it configs at the root publish the layer, the CLI, and the workspace separately.
What tests does the Docus workspace run?
Three entry points exist: vitest run --project unit, vitest run --project smoke, and ./scripts/test-starter.sh. The aggregate verify script runs dev:prepare, lint, typecheck, the unit project, and a docs build, and it does not include the smoke or starter checks.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nuxt-content-docus)