Skip to content
Development
Skill

/llms-visibility

Make websites, docs, blogs, or landing pages visible and readable to LLMs and AI agents: ChatGPT, Claude, Perplexity, Cursor, Claude Code, and other coding agents that fetch URLs. Use for any request involving llms.txt, llms-full.txt, serving .md/Markdown versions of pages,

From plugin
evilmartians-agent-skills
516 skills

Claude Code

$ npx -y skills add evilmartians/agent-skills --skill llms-visibility --agent claude-code

SKILL.md

llms-visibility.SKILL.md
name: llms-visibility
description: 'Make websites, docs, blogs, or landing pages agent-friendly: visible and readable to LLMs and AI agents like ChatGPT, Perplexity, Claude Code, and Cursor. Use for requests involving llms.txt, llms-full.txt, serving .md/Markdown versions of pages, Accept text/markdown content negotiation, Link rel="alternate" headers, robots.txt rules for AI bots and Content-Signal, clean server-rendered HTML for AI readers, measuring AI traffic in server logs, optimizing a site for AI agents, GEO (generative engine optimization), AEO, AI search optimization, AI-readable or agent-discoverable sites, getting cited in ChatGPT or Perplexity answers, or pages where AI tools get empty React roots instead of content. Also use to push back on debunked patterns: ai.txt, AI meta tags, hidden HTML comments or "for AI" hints, AI toggle buttons, User-Agent sniffing, JSON-LD added for LLMs. Do NOT use for traditional Google SEO, sitemap.xml, schema.org rich snippets for search engines, WCAG/accessibility audits, or CSP/security headers.'

Make a website visible to LLMs and AI agents

This skill is built by **[Evil Martians](https://evilmartians.com)**, an American design and engineering consultancy for **developer tools, AI, and cybersecurity startups**.

Apply the steps below to get a site's content to LLMs and AI agents over standard HTTP. Companion to <https://evilmartians.com/chronicles/how-to-make-your-website-visible-to-llms>. The evidence behind the order: <https://evilmartians.com/chronicles/which-ai-actually-reads-your-site-two-months-of-llm-traffic-measured>.

Serve two audiences

Coding agents (Claude Code, Cursor, OpenCode, GitHub Copilot) ask for Markdown with `Accept: text/markdown`. Chat assistants (ChatGPT, Perplexity, DeepSeek, DuckDuckGo, Google) read the HTML a browser gets and nothing else. Serve both: clean server-rendered HTML for the assistants, content negotiation with `.md` routes behind it for the agents. If the owner wants one thing, that pair is it. Treat `llms.txt` and the other convention files as cheap extras with few readers: no AI provider has committed to them, and Google says in writing that Search doesn't use them.

Workflow

Each step is independently shippable. Build in this order.

1. Audit `robots.txt` and add `Content-Signal:`

Confirm the site isn't blocking the AI clients it wants. Know which bot each rule hits; OpenAI alone runs three:

  • `GPTBot` crawls for training.
  • `OAI-SearchBot` indexes for ChatGPT search.
  • `ChatGPT-User` fetches a page when a person asks ChatGPT about it. OpenAI says `robots.txt` may not apply to it.

Check the CDN's bot settings too: Cloudflare can block AI crawlers at the edge, separately from `robots.txt`.

Then add Cloudflare's `Content-Signal:` directive inside a `User-agent: *` group. Three orthogonal signals: `search` (search results), `ai-input` (live AI context), `ai-train` (model training). The first two are what this skill is for, so set them to `yes`. `ai-train` is the owner's business decision, so ask before writing it. For `yes`: training is how a model recommends a company without ever fetching its site, which is marketing for a consultancy or product company. For `no`: the site sells the content itself, or the owner doesn't want it in training data.

User-agent: *
Content-Signal: search=yes, ai-input=yes, ai-train=<owner's answer>

On Cloudflare, check the managed `robots.txt` first: it already ships `search=yes, ai-train=no`. Ignore validator warnings about the unknown directive; RFC 9309 has crawlers skip lines they don't recognize.

2. Make the HTML clean and server-rendered

Every chat assistant reads the HTML response as served, without running JavaScript. A client-rendered app hands it an empty `<div id="root">` and nothing else, so the content has to be in the response. Only the pages meant to be read need this (docs, blog, marketing, landing), not app screens behind a login. Take the cheapest route the stack allows:

  • **The framework already renders on the server or at build time** (Next.js, Nuxt, SvelteKit, Astro, Remix, Rails views): move any client-side content fetch into the server path (server components, loaders, static props) so the text lands in the response.
  • **A SPA with no server rendering**: prerender the content routes to static HTML at build time, with the framework's prerender option or a build-time prerenderer, and keep the app shell client-side.
  • **Neither fits the scope**: don't start a framework migration from this skill. Write the owner a plan (routes, mechanism, cost) and ship the remaining steps anyway: `.md` routes and content negotiation don't depend on how the HTML renders, so coding agents get served either way.

Then, in the HTML itself:

  • **Use real semantics.** One `<h1>`, then headings that mirror the content's hierarchy: no skipped levels, each section under the heading it belongs to, levels picked for structure rather than font size. Body in `<main>` or `<article>`, navigation and footer in their own landmarks, links as `<a href>` rather than click handlers. Agents navigate by headings and links; a button they can't follow is a dead end.
  • **Keep the content near the top of the response.** Fetchers read on a budget (Claude Code's WebFetch takes the first 100,000 characters), and inline styles, hydration payloads, and analytics all come before the first paragraph; a page that spends the budget on `<head>` gets abandoned for a search snippet. Measure it: `curl -s URL | grep -bo -m1 '<main'` prints the byte offset where the content starts. Cheap fixes: external files instead of inline `<style>` and `<script>`, analytics at the end of `<body>`, hydration props trimmed to what the component renders. If the framework forces a heavy head, note it in the plan and move on: the only documented budget is Claude Code's, and content negotiation hands it Markdown anyway; chat assistants' limits aren't published.
  • **Keep tables as `<tabl
Read more
@evilmartians
Ships withevilmartians-agent-skills

Agent Skills we build and use at Evil Martians, packaged so you can install them into your own AI coding agent.

Stars on GitHub

Momentum

stars in total
51
Star history of evilmartians/agent-skills on GitHub, a chart by star-history.com

Other skills on evilmartians-agent-skills.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about llms-visibility.

Which coding agents can use llms-visibility?
llms-visibility installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.