Pablo Albaladejo

GEO · · 6 min read

GEO: how AI agents find you, a same-day case study

Generative engine optimization (GEO) is how AI answer engines like ChatGPT and Perplexity cite you. A same-day case study of the five mechanisms I shipped on kaiord.com, from llms.txt to registries.

Generative engine optimization (GEO) is how you get found by the tools that now sit between people and the web. Think of ChatGPT, Perplexity, Claude and Google’s AI Overviews. Classic SEO optimizes for a ranked list of links that a human clicks. GEO optimizes for a model that reads a few sources, combines them, and cites the ones it trusted. The two overlap, because clean HTML and a sitemap help both. But a model would rather read text than render your app. So GEO leans on five concrete mechanisms. They are an llms.txt map, robots rules that let AI crawlers in, structured data, Markdown mirrors, and registries where agents and tools get indexed.

I ran that whole playbook against kaiord.com, my open-source, local-first training platform, in a single day. AI agents did the work, and I approved each pull request. This is a Day-1 report. I can show you what shipped and why, mechanism by mechanism, with a link to every artifact. I cannot yet show you what it earned. More on that at the end.

The five mechanisms, and the case for each

1. An llms.txt map (PR #955)

llms.txt is a small Markdown file at your site root that gives an LLM a curated map of your best pages and docs. Kaiord’s documentation already generated an excellent per-section llms.txt, but nothing at the root pointed agents to it. PR #955 added a root /llms.txt in the llmstxt.org format: product pages in both languages, the editor, the key docs as Markdown, the full corpus, GitHub, npm. It is the cheapest high-leverage file on the whole site.

2. Robots rules that let AI crawlers in (PR #955)

This is the embarrassing one. The robots.txt had carried Disallow: /editor/ since the original landing scaffold. So the application itself, the thing I most want cited, was invisible to every crawler and every answer engine. You can spend months on content and still forbid the machines from reading the best of it. The fix is one deleted line. Today kaiord.com/robots.txt reads:

User-agent: *
Allow: /

Sitemap: https://kaiord.com/sitemap.xml

# AI agents: a curated map of this site lives at https://kaiord.com/llms.txt
# Full docs corpus in markdown: https://kaiord.com/docs/llms-full.txt

The lesson to learn before anything else: audit what you already block before you optimize what you do not.

3. Structured data (PR #955, extended in #962)

A single-page app is a hard read for a crawler: an empty <div id="root"> and nothing else. So the editor shell got a descriptive title and an accurate meta description. More important, it got noscript content and a WebApplication JSON-LD block with a real featureList, so a crawler without JS sees real text instead of a blank frame. The landing gained a WebSite JSON-LD node that declares both languages, and a visible FAQ backed by FAQPage JSON-LD. A later PR kept that FAQ in sync with the on-screen copy. Structured data is how you hand a machine entities (“this is an application, these are its features”) instead of asking it to guess from your markup.

4. Markdown mirrors (PR #955 and #965)

Models read Markdown easily and render web apps only with effort. Kaiord’s docs already emit per-page .md mirrors and a single /docs/llms-full.txt that joins the whole corpus as plain text. A model can read the whole product in one fetch. PR #955 also turned the root sitemap into a proper index, so /, /es/, and /editor/ are listed at last. Then PR #965 added a set of long-tail converter pages (“convert FIT to ZWO”, “export Zwift workout to Garmin”) built on a repeatable GEO template. Each page has a direct-answer paragraph at the top and three concrete ways to do the task. Then a grounded “what survives the conversion” table and a couple of specific FAQs. That is content shaped like the questions people ask an assistant.

5. Registries (PR #956 and #962)

The last mechanism is to appear where agents and tools get catalogued. There were two moves. First, PR #956 fixed npm metadata. Every package’s homepage had linked back to its own npm page, so it pointed nobody at the docs. Now each points at its real docs page. The keyword sets were widened too, to the honest, high-signal terms people search (fit-parser, fit-to-tcx, zwift-workout, mcp-server). Second, PR #962 made visible that @kaiord/mcp is now published to the official MCP registry as io.github.pablo-albaladejo/kaiord and listed on Glama. It then put that where people evaluate the project: the landing’s developer section, its FAQ, and the README badges. If AI agents are a distribution channel, their registries are where you need to be listed.

The honest part: a gatekeeper said no

Same day, same program, one distribution move failed. I opened awesome-local-first PR #51 to add Kaiord to a curated list. That is the oldest and most human form of GEO: a citation on a page that LLMs already read. The maintainer closed it. I quote the reply exactly, because it is the most useful thing that happened all day:

Thanks — this is clearly a real, actively developed project. Passing for now though: at ~7 stars it’s below the traction bar for example apps, and the README doesn’t really substantiate the local-first architecture (offline behavior, on-device storage as the source of truth). Happy to revisit once either of those improves.

That is a fair no, and it teaches the thing the five mechanisms cannot. A technically correct PR (clean diff, accurate description, passing checks) is necessary but not sufficient. Human gatekeepers weigh substance and traction. Does the README prove the claim? Has the project earned enough signal to be worth a slot? You cannot automate your way past that. The reply even gives you the roadmap: prove the local-first architecture in the README, let the traction grow, and “revisit once either of those improves.” I would rather publish that no than pretend the day was perfect.

Too early to measure

This is where I stop short of the usual case-study move. It is Day 1. Everything above is verifiable: the PRs are merged, the files are live, the registry entry resolves. But I have no traffic, no citation counts and no ranking changes to report, because none exist yet. Anyone who shows you GEO “results” hours after shipping is selling something. The artifacts are the evidence. The outcomes are a measurement I will take later. Treat the checklist below as a set of mechanisms with proof, not as a promise of numbers.

A checklist you can repeat

If you want to run the same pass on your own project:

FAQ

What is GEO (generative engine optimization)?
GEO is the practice of making a site readable and citable for AI answer engines such as ChatGPT, Perplexity, Claude and Google AI Overviews. Ranked search results are no longer the only target. In practice it means machine-readable maps (llms.txt), permissive crawler rules, structured data and Markdown mirrors of your pages. It also means a listing in the registries that agents browse.
What is an llms.txt file and do I need one?
An llms.txt is a small Markdown file at your site root (see llmstxt.org). It gives an LLM a curated map of your most useful pages and documentation, plus links to full-text mirrors it can read without running JavaScript. It does not replace a sitemap; it adds to one. If you want AI assistants to summarize or cite your project accurately, it is the cheapest high-leverage file you can ship.
How do I get my site cited by ChatGPT or other AI assistants?
Make the content easy for a crawler to read and hard to misquote. Publish an llms.txt map. Stop blocking the pages you want cited in robots.txt. Add JSON-LD structured data and noscript text, so JS-heavy apps still expose real content. Mirror your docs as Markdown, and get listed in the relevant registries. There is no submit button: you make yourself the easiest correct answer to find.
Is GEO different from SEO?
They overlap but optimize for different readers. SEO targets a ranked list of links that a human clicks. GEO targets a model that reads, combines and cites a few sources inside an answer. Clean HTML and sitemaps help both. GEO leans harder on explicit maps, structured data and plain-text mirrors, because a model would rather read text than render your app.

SOURCES & PROOF