---
title: "The complete AI readiness setup for Ghost in 2026"
slug: ai-readiness-setup-ghost
published: 2026-08-31T08:18:29.691087+00:00
updated: 2026-08-31T08:18:29.691087+00:00
author: "Asif Rahman"
author_url: https://masifrahman.com
category: "AI Readiness"
tags: platform:ghost, check:D1, check:D2, check:B2, check:C1, check:C2, check:C3, check:E3, check:E5, Ghost, AI readiness, robots.txt, llms.txt, AI crawlers
description: "Ghost ships a sitemap, RSS and server-rendered HTML for free, then blocks every other root file. The two doors that work, and the three that never will."
url: https://aiscan.site/blog/ai-readiness-setup-ghost
---

**Verified 31 August 2026 against Ghost's own source and three live Ghost 6.61 publications.**

Ghost hands you more agent readiness for free than any platform in this series, then stops at a wall you cannot climb from the admin panel. Server-rendered HTML, a sitemap, an RSS feed and `Article` schema all ship switched on. But Ghost has no static file root and no file manager, so every remaining discovery file arrives through one of two doors. This guide covers both, and the files that fit through neither.

## Quick summary

| What an agent looks for | Check | Ghost's default | What you do |
|---|---|---|---|
| robots.txt exists | D1 | Present, generated by Ghost | Nothing |
| AI crawlers named | B2 | **No AI bot is named** | Ship a `robots.txt` in your theme |
| sitemap.xml | D2 | Generated, and linked from robots.txt | Nothing |
| RSS feed plus autodiscovery | E5 | `/rss/` with `rel="alternate"` in head | Nothing |
| Server-rendered body copy | C3, E3 | Handlebars renders on the server | Nothing |
| llms.txt | C2 | Route exists, currently redirects | Theme file, or a routes.yaml route |
| Markdown at `.md` | C1 | Returns HTML, a false pass | Nothing fixable in admin |
| `.well-known` JSON files | P1 to P4 | Blocked by the theme file filter | Not reachable on Ghost |

## What Ghost gives you before you touch anything

Ghost renders Handlebars on the server and sends finished HTML. Fetched with plain curl on 31 August 2026, a 404 Media article returned **1,866 words of readable prose, one `<h1>`, and one `application/ld+json` block** typed `Article` with `headline`, `datePublished`, `dateModified`, `author` and `image`. C3 and E3 pass by construction, the opposite of where a client-rendered React site starts.

Ghost's default robots.txt lives in its source tree at `ghost/core/core/frontend/public/robots.txt` and is 203 bytes:

```
User-agent: *
Sitemap: {{blog-url}}/sitemap.xml
Disallow: /ghost/
Disallow: /email/
Disallow: /members/api/comments/counts/
Disallow: /r/
Disallow: /webmentions/receive/
Disallow: /.ghost/analytics/api/
```

That was fetched from the Ghost repository and matches byte for byte what platformer.news, 404media.co and thebrowser.com serve today. D1 passes, and D2 gets its declaration free from the `Sitemap:` line. `/rss/` returns `application/rss+xml` and the homepage carries the matching `<link rel="alternate" type="application/rss+xml">` tag, so E5 needs no work.

What it does not contain is a single AI crawler. Not GPTBot, not ClaudeBot, not PerplexityBot. Every Ghost site ships that silence, which is why **B2** fails first on a Ghost scan.

## The rule that decides everything: Ghost's fall-through list

Ghost serves root-path files from your **active theme folder**, through a middleware called `static-theme`. It applies two filters, both readable in `ghost/core/core/frontend/web/middleware/static-theme.js`, verified on 31 August 2026 against package version 6.61.1.

| Filter | Contents | Effect |
|---|---|---|
| Denied extensions | `.hbs`, `.md`, `.json`, `.lock`, `.log` | Never served, except `manifest.json`, `assetlinks.json`, and anything under `/assets/` |
| Fall-through paths | `/robots.txt`, `/sitemap.xml`, `/sitemap.xsl`, `/llms.txt`, `/llms-full.txt`, `/.well-known/llms.txt`, `/.well-known/llms-full.txt` | Theme file wins if present, Ghost's generated one if not |
| Anything else with an extension | any name | Served from the theme folder if it exists |

Put those together and the whole surface resolves into one sentence. **A discovery file works on Ghost if its extension is not `.md` or `.json`, and it is easy if the path is on the fall-through list.** `robots.txt` and `llms.txt` are. `agents.md` and `/.well-known/mcp/server-card.json` are on the wrong side of the denial list, and no setting changes that.

## Path 1: ship the files in your theme

Ghost's theme structure page says, in its own words, "Themes can include a robots.txt which overrides the default robots.txt provided by Ghost."

1. Download your active theme as a zip from Ghost admin, or clone it if you build locally.
2. Unzip it and find the folder holding `index.hbs`, `post.hbs` and `package.json`.
3. Create `robots.txt` there, beside `package.json`, not in `/assets/`.
4. Write the whole file, not a patch. A theme robots.txt replaces Ghost's default rather than merging, so copy the seven lines above, add your AI groups underneath, and swap `{{blog-url}}` for your domain. Drop the `Sitemap:` line and you lose D2 while fixing B2.
5. Add one group per crawler. Google's robots.txt specification is explicit that only the most specific matching group applies, so a bot with its own group never reads your `*` group. Repeat `Disallow:` and `Sitemap:` inside each.
6. Create `llms.txt` beside it: an H1 with the publication name, a one-line blockquote summary, then H2 link lists to your best pages.
7. Re-zip and upload in Ghost admin. Ghost runs GScan on upload and rejects fatal errors, so a broken theme cannot take the site down.
8. Re-fetch both files and read the content type, not just the status code.

```
User-agent: GPTBot
Disallow: /members/
Allow: /
Sitemap: https://example.com/sitemap.xml
```

404 Media has done this in the other direction: its robots.txt carries the seven defaults plus a `User-agent: GPTBot` group with `Disallow: /`. Either way the file now has an opinion. Current tokens are in our [AI crawler user agent list](https://aiscan.site/blog/ai-crawler-user-agent-list-2026).

## Path 2: routes.yaml, when the theme is not yours to edit

On a purchased theme you would rather not fork, Ghost's routing layer serves a text file from a template.

1. In Ghost admin, go to **Settings » Labs** and download `routes.yaml`.
2. Add a route under `routes:` pointing at a template, and set its mime type. The routing docs say, in their own words, "Generally, routes render HTML, but you can override that by specifying a `content_type` property with a custom mime-type."
3. Use a trailing slash on the route key. That same page says Ghost "automatically forces trailing slashes", so `/llms.txt/` behaves predictably.
4. Create the matching `.hbs` template in your theme and fill it with a `{{#get}}` query over your posts.
5. Upload the edited file back through Settings » Labs. Uploading applies routes immediately; editing on disk needs a Ghost restart.

```yaml
routes:
  /llms.txt/:
    template: llms
    content_type: text/plain
```

Two limits. `{{#get}}` reads posts, tags, authors, tiers and newsletters, but not pages, so a generated index misses your About and Pricing pages. And the trailing slash Ghost forces is the inverse of the Astro trap, where extension endpoints only answer without one. If you would rather not template it, our [llms.txt generator](https://aiscan.site/llms-txt-generator) writes the file for you.

## The 302 that reads as a pass

Ghost 6.61 registers four llms.txt routes and, when the feature is off, redirects them instead of returning a 404. The handler at `ghost/core/core/frontend/services/llms/handler.js` mounts `/llms.txt`, `/llms-full.txt`, `/.well-known/llms.txt` and `/.well-known/llms-full.txt`, and its disabled branch calls `res.redirect(302, '/')`. Verified on 31 August 2026, all three test publications returned **302 to `/` on exactly those four paths, while `/humans.txt` and `/.well-known/foo.txt` returned a real 404 on the same hosts.**

That creates a checking trap. A follow-redirects status test reports **200** for a Ghost site with no llms.txt at all, because it lands on the homepage and the homepage is fine. Read the final URL and content type:

```bash
curl -sL -o /dev/null -w '%{http_code} %{content_type} %{url_effective}\n' https://example.com/llms.txt
# no file:   200 text/html; charset=utf-8 https://example.com/
# real file: 200 text/plain; charset=utf-8 https://example.com/llms.txt
```

The file's structure and template are covered in [publishing llms.txt on Ghost](https://aiscan.site/blog/llms-txt-ghost).

## What Ghost genuinely cannot serve

| File | Check | Why it is blocked |
|---|---|---|
| `agents.md`, `AGENTS.md` | none yet | `.md` is on the denial list |
| `/.well-known/mcp/server-card.json` | P2 | `.json` denied outside `/assets/` |
| `/.well-known/api-catalog` | P1, E2 | Same filter |
| `/.well-known/agent-skills/index.json` | P3 | Same filter |
| OAuth metadata | P4 | Same filter |

According to the same middleware, none of these can be served from a theme. Verified on all three publications: `/agents.md` returns a hard 404, and `/AGENTS.md` 301s to lowercase before the same 404. Shopify serves `agents.md` natively and [Webflow gates `.well-known` behind an Enterprise API](https://aiscan.site/blog/ai-readiness-setup-webflow), so Ghost is the more restrictive of the three.

One more honest note. Appending `.md` to a Ghost post URL returns the post's HTML with a 200, so Ghost soft-serves unknown extensions. Any scanner deciding **C1** on the status code alone passes a Ghost site that has no Markdown at all. Ours currently does, and we published that bug ourselves rather than banking the pass.

## Check it with one command

Run the scan first. It reads every file above in one pass and names the row that moved.

```bash
npx aiscan-cli yourpublication.com
```

Or paste the URL at [aiscan.site](https://aiscan.site/), free, no account. It answers **D1** robots.txt, **D2** sitemap, **B2** AI bot rules, **C2** llms.txt, **C3** and **E3** server-rendered HTML, and **E5** feed autodiscovery, this guide's whole list. The rubric sits on the dimension pages: [bot access](https://aiscan.site/docs/checks/bot-access) for B2, [discoverability](https://aiscan.site/docs/checks/discoverability) for D1 and D2, [content](https://aiscan.site/docs/checks/content) for C2, C3 and E3.

If you would rather check by hand, this is the complete set and you do not need us for it:

```bash
SITE=https://yourpublication.com
curl -s "$SITE/robots.txt" | grep -iE 'gptbot|claudebot|perplexitybot|oai-searchbot'
curl -s -o /dev/null -w '%{http_code} %{content_type}\n' "$SITE/sitemap.xml"
curl -s -o /dev/null -w '%{http_code} %{content_type}\n' "$SITE/rss/"
curl -sL -o /dev/null -w '%{http_code} %{content_type} %{url_effective}\n' "$SITE/llms.txt"
curl -s "$SITE/" | grep -o 'rel="alternate" type="application/rss+xml"'
```

A pass reads: one AI user agent in the grep, `text/xml` on the sitemap, `application/rss+xml` on the feed, `text/plain` and an unchanged URL on llms.txt, one hit on the last grep.

What no scanner sees is whether your llms.txt names the right pages, whether member-only posts should be readable by a retrieval crawler, and whether your AI groups match the editorial policy you hold. Those are decisions, not checks.

## When Ghost is not the whole property

Plenty of Ghost publications are one property among several, and the files failing your scan often live elsewhere. If a WordPress site sits alongside the newsletter, [ThinkRank](https://thinkrank.ai) is the one to reach for there. It handles robots.txt, robots meta, schema, sitemaps and llms.txt from a single plugin, which answers the usual WordPress problem of three SEO plugins writing to the same robots.txt and overwriting each other. It migrates settings from Rank Math, Yoast, All in One SEO and SEOPress, so switching costs nothing in re-entered configuration. Rank Math and Yoast have deeper traditional-SEO reporting and bigger template libraries; if your team lives in that daily, keep it. Our [WordPress guide](https://aiscan.site/blog/ai-readiness-setup-wordpress) covers that stack.

If a Shopify store carries the merch, [StoreSEO](https://storeseo.com/) is the equivalent. It generates llms.txt from live products, collections, pages and articles rather than a file you keep by hand, and it ships an agents.md editor, which matters because Shopify serves that file natively where Ghost cannot. Other Shopify SEO apps do bulk alt text and broken-link auditing better.


## Start with the scan, not the theme

Two files in a theme folder take a Ghost publication the rest of the way, and Ghost already did the harder half. Run [the scan](https://aiscan.site/), read the B2 and C2 rows first, then work down. The rest of the series is in [our guides](https://aiscan.site/guides).

