AI readiness setup for Ghost: two open doorways and one sealed doorway in a deep green abstract scene, with AIScan check IDs D1, D2, B2, C2, C3, E3 and E5 listed below.
AI readiness setup for Ghost: two open doorways and one sealed doorway in a deep green abstract scene, with AIScan check IDs D1, D2, B2, C2, C3, E3 and E5 listed below.
AI Readiness

The complete AI readiness setup for Ghost in 2026

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.

AAsif Rahman August 31, 2026 9 min read
#Ghost#AI readiness#robots.txt#llms.txt#AI crawlers

This guide covers D1 · Discoverability, D2 · Discoverability, B2 · Bot Access, C1 · Content, C2 · Content, C3 · Content, E3 · Content, E5 · Content.

Table of contents

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 forCheckGhost's defaultWhat you do
robots.txt existsD1Present, generated by GhostNothing
AI crawlers namedB2No AI bot is namedShip a robots.txt in your theme
sitemap.xmlD2Generated, and linked from robots.txtNothing
RSS feed plus autodiscoveryE5/rss/ with rel="alternate" in headNothing
Server-rendered body copyC3, E3Handlebars renders on the serverNothing
llms.txtC2Route exists, currently redirectsTheme file, or a routes.yaml route
Markdown at .mdC1Returns HTML, a false passNothing fixable in admin
.well-known JSON filesP1 to P4Blocked by the theme file filterNot 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.

FilterContentsEffect
Denied extensions.hbs, .md, .json, .lock, .logNever 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.txtTheme file wins if present, Ghost's generated one if not
Anything else with an extensionany nameServed 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.

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.
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 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:

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.

What Ghost genuinely cannot serve

FileCheckWhy it is blocked
agents.md, AGENTS.mdnone yet.md is on the denial list
/.well-known/mcp/server-card.jsonP2.json denied outside /assets/
/.well-known/api-catalogP1, E2Same filter
/.well-known/agent-skills/index.jsonP3Same filter
OAuth metadataP4Same 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, 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.

npx aiscan-cli yourpublication.com

Or paste the URL at 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 for B2, discoverability for D1 and D2, 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:

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 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 covers that stack.

If a Shopify store carries the merch, StoreSEO 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, read the B2 and C2 rows first, then work down. The rest of the series is in our guides.

Frequently asked questions

My Ghost site's /llms.txt returns 200 but I never created one. Why?

Ghost registers /llms.txt, /llms-full.txt, /.well-known/llms.txt and /.well-known/llms-full.txt as real routes, and when the feature is disabled it answers them with a 302 to your homepage rather than a 404. A checker that follows redirects lands on the homepage and records 200. Re-run the check reading the final URL and content type: curl -sL -o /dev/null -w '%{http_code} %{content_type} %{url_effective}' https://yoursite.com/llms.txt. A real file returns text/plain at the unchanged URL.

I put robots.txt in my theme but Ghost still serves its default. What went wrong?

Three usual causes. The file is inside /assets/ rather than the theme root beside package.json, so it is served at /assets/robots.txt instead. The edited theme is not the active one, since Ghost only serves files from the active theme. Or the upload failed GScan, which Ghost runs automatically on theme upload and which rejects fatal errors. Re-download the active theme from admin and confirm your robots.txt is inside the zip at the top level.

I added agents.md to my theme and it returns 404. How do I fix it?

You cannot. Ghost's static-theme middleware denies the extensions .hbs, .md, .json, .lock and .log outright, with only manifest.json and assetlinks.json exempted. A .md file in a theme is never served, which is why /agents.md returns a hard 404 on every Ghost site tested on 31 August 2026. If agents.md matters to you, it has to be served from a different host.

Where is the robots.txt setting in Ghost admin?

There isn't one. Ghost generates robots.txt from a file in its own source tree and there is no admin field to edit it. The supported override is a robots.txt inside your active theme, which Ghost's theme structure documentation describes as replacing the default. That means editing robots.txt on Ghost is a theme change, not a settings change.

Does Ghost give me a sitemap and an RSS feed automatically?

Yes, and neither needs configuration. /sitemap.xml returns a sitemap index pointing at sitemap-pages.xml, sitemap-posts.xml, sitemap-tags.xml and sitemap-authors.xml, and the default robots.txt already carries the matching Sitemap: line, so D1 and D2 pass on a fresh install. /rss/ returns application/rss+xml and Ghost themes emit the rel="alternate" autodiscovery tag in head, which is what E5 looks for.

My scan says C3 or E3 failed on a Ghost site. Is that possible?

It is unusual and worth investigating rather than fixing blind. Ghost renders Handlebars on the server, and a plain curl of a live Ghost article on 31 August 2026 returned 1,866 words of prose and one h1 with no JavaScript executed. If C3 or E3 fails, look at what sits in front of Ghost: a proxy or bot-protection layer returning a challenge page to non-browser clients, or a theme that injects the article body from JavaScript through code injection rather than rendering it in the template.

Can I publish an MCP server card or an API catalog on Ghost?

Not from Ghost itself. Both live under /.well-known/ as .json documents, and .json is on the theme denial list outside /assets/, so P1 through P4 are unreachable on a Ghost-hosted domain. Shopify serves agents.md natively and Webflow allows .well-known uploads on Enterprise, so Ghost is the most restrictive of the three on capability files. Host them on a domain you control the web server for.

Is llms.txt worth publishing on Ghost at all?

It depends what you want from it. Google states that llms.txt files will "neither harm nor help" visibility in Google Search because Search ignores them, and Ahrefs found in June 2026 that 97% of the valid llms.txt files across roughly 137,000 domains received zero requests in May. The case for publishing one is directed tooling, where a person hands an agent your URL, plus the low cost of a single file in a folder you are already editing for robots.txt.

Related guides