How this site is built for AI search and agents
This site is built to be read correctly by search engines, AI answer engines, and browsing agents, not only by people. Every surface below is live and generated from the same source data as the human pages, so the machine versions cannot drift from what visitors see.
Crawler access and discovery
- robots.txt with Content-Signal
- Allows search and answer-engine crawlers (OAI-SearchBot, ChatGPT-User, GPTBot, PerplexityBot, ClaudeBot, Google-Extended, and others) and user-triggered agents; keeps private paths out; blocks CCBot.
- Why: Retrieval bots have to be allowed before a page can be cited. Content-Signal (search=yes, ai-input=yes, ai-train=no) separates being cited from being used for training.
- sitemap.xml
- Every public page and post with a lastmod taken from the content itself.
- Why: Accurate lastmod tells crawlers what changed so fresh content is recrawled first.
- IndexNow key
- Key file for IndexNow, plus a script that pings changed URLs after a deploy.
- Why: Bing and other IndexNow engines feed several AI answer products; pinging shortens the time to index.
- Canonical URLs
- Every HTML page declares its own canonical URL.
- Why: One URL per piece of content keeps ranking and citation signals from splitting across duplicates.
Content for language models
- llms.txt
- The resume in llms.txt format: H1, a quotable summary, the resume sections, and links to every machine endpoint.
- Why: A short, curated entry point a model can read in one pass to answer who Michael is and what he does.
- llms-full.txt
- The whole site as one Markdown file: resume, every page, the portfolio, and every published post.
- Why: Lets an agent load all of the context at once instead of crawling page by page.
- Markdown for every page
- Append .md to any path (/blog.md, /portfolio.md, /blog/<slug>.md), or request any page with Accept: text/markdown. Pages advertise it with a Link header and <link rel="alternate" type="text/markdown">, and the footer links to it.
- Why: Markdown uses far fewer tokens than rendered HTML and has no layout noise, so agents quote the content, not the chrome.
- Answer-first home page
- A "Who is Michael C. Hurley?" section near the top with a self-contained summary and stable heading ids.
- Why: Answer engines lift short, self-contained passages. Stable ids make the passage linkable.
Structured data
- JSON-LD
- Person (sameAs, knowsAbout, hasOccupation, alumniOf), WebSite, and Organization site-wide; ProfilePage on the home page; BlogPosting and BreadcrumbList on posts; CollectionPage with CreativeWork and SoftwareSourceCode items on the portfolio; FAQPage on this page.
- Why: Entity markup states the facts (who, where, what, which profiles are the same person) so engines do not have to infer them.
- resume.json
- The resume in the JSON Resume schema.
- Why: A standard, typed format that resume tools and agents already parse.
- portfolio.json and blog.json
- Portfolio pieces and blog posts as JSON, each post with a link to its Markdown.
- Why: Lists an agent can filter without scraping. See also /portfolio.json.
- RSS and JSON Feed
- The blog as RSS 2.0 (/feed.xml) and JSON Feed 1.1 (/feed.json).
- Why: Feeds are still how aggregators and many agents notice new posts.
- OpenAPI
- OpenAPI 3.1 description of the JSON endpoints, the Markdown routes, the booking API, and the MCP endpoint.
- Why: Agents and tool builders can generate a client instead of guessing request shapes.
FAQ
How can an AI agent read this site?
Start with https://www.michaelchurley.com/agents.md. For content, append .md to any page URL or send Accept: text/markdown. For everything at once, use https://www.michaelchurley.com/llms-full.txt.
Can an agent book a call with Michael?
Yes. Use the MCP server at /mcp or the WebMCP tools: get_booking_options, then get_availability, then book_meeting with a slot_start, name, and email. The visitor gets a confirmation email with a calendar invite.
Is the content allowed in AI answers?
Yes for search and answers (Content-Signal: search=yes, ai-input=yes). Training use is opted out (ai-train=no), and CCBot is blocked.
Why does the site publish the same content in several formats?
Each format fits a different reader: HTML for people, Markdown for language models, JSON and JSON-LD for software, and MCP or WebMCP tools for agents. All of them are generated from the same source data.