Install
$ agentstack add mcp-adkinn-astro-ai-readiness ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
@adkinn/astro-ai-readiness
> AI Readiness toolkit for Astro — eight JSON-LD helper components plus dist/llms.txt, dist/llms-full.txt, dist/agents.md, dist/robots.txt, and dist/.well-known/mcp.json.
Status: v0.0.11 — app / product / game support. ` (screenshots, feature list, offers, and a type for VideoGame / MobileApplication / WebApplication + gamePlatform), Organization description + sameAs + contactPoint, founder.url, WebSite inLanguage, and custom ## sections for agents.md` — proven on three real sites (a person, an app, a game).
What ships in v0.0.11
Eight JSON-LD components:
- `
— Organization block. Config-driven fromorganization(optional; now supportsdescription,contactPoint, andfounder.url); place in yourBaseLayoutso it ships site-wide and the#organization@idreference resolves on every page. Renders nothing iforganization` is unset. - `
— Person block. Config-driven fromperson(optional); for sites whose primary identity is an individual. Place in yourBaseLayout; declares#person, and becomes the WebSite publisher when set. Renders nothing ifperson` is unset. - `
— SoftwareApplication block. Config-driven fromsoftwareApplication(optional); for app/product sites. Emits#appwithoperatingSystem,applicationCategory,screenshot[],featureList[],offers[], and linkspublisher/author` to the site's Organization (or Person). Renders nothing if unset. - `
— WebSite block. Config-driven (now supportsinLanguage); alongsideorinBaseLayout`. - `
— CollectionPage block. Props-driven; place on collection-index pages (/articles/,/tags/[tag]/`, etc.). - `
— BreadcrumbList. Items-array prop; place on multi-level pages where the navigation hierarchy isn't already declared inline. Emptyitems` skips emission. - `
— FAQPage. Items-array prop; place on pages with FAQ data. Long-form answers escapeand U+2028 / U+2029 automatically. Emptyitems` skips emission. - `
— TechArticle block. Heavy-props; place on article-detail pages.authordefaults to a Person synthesized fromconfig.organization.founder; pass an explicitauthor` prop to override.
Five file outputs:
dist/llms.txt— llmstxt.org format from thellmsTxtconfig block. H1 / blockquote summary / optional body / H2 sections with bulleted links / optional canonical-reference footer. Opt-in.dist/llms-full.txt— manual full-context markdown from thellmsFullconfig block. This is config-driven in v0.0.7; content-collection introspection is a later layer.dist/agents.md— Markdown discovery file for AI-agent crawlers from theagentsMdconfig block. H1 / blockquote description / optional## Audience, arbitrary## sections(title + markdown content),## Contact, and## Links. Opt-in.dist/.well-known/mcp.json— Model Context Protocol discovery file from themcpconfig block. Pretty-printed JSON with$schemareference to the toolkit-published v1 shape (per D-22). Supportsstatus: 'active'(requiresurl+tools[]) andstatus: 'planned'(requiresplanned_tools[];urlforbidden by schema). Opt-in.dist/robots.txt— robots policy composition from therobotsTxtconfig block. Presets:search-visible,training-opt-out(default), andprivate; supports explicit bot rules,Sitemap, and optionalContent-Signaldirectives.
@astrojs/sitemap detection per D-8. When you call aiReadiness({...}) and @astrojs/sitemap isn't in your integrations list, the toolkit logs a build-time warning. Sitemap is an AI-Readiness baseline; when robotsTxt is enabled, the generated robots.txt includes a Sitemap line by default.
All eight components emit canonical Schema.org JSON-LD with cross-component @id references (#organization, #person, #app, #website) so search and AI consumers can resolve the entity graph without redeclaring shared fields.
URL config fields (site, organization.url, organization.logo, founder.sameAs, llmsTxt.*.url) require https:// (or http://localhost for dev).
Config validation errors are formatted with one issue per line — path: message per Zod issue — instead of the default ZodError JSON blob.
Install
npm install @adkinn/astro-ai-readiness
Quick start
Configure (v0.0.9 accepts site, optional person, optional organization, optional softwareApplication, optional webSite, optional llmsTxt, optional llmsFull, optional agentsMd, optional mcp, and optional robotsTxt blocks — provide at least one of person/organization as the site identity. The Zod schema rejects unknown keys, and URL fields must use https:// or http://localhost):
// astro.config.mjs
import { defineConfig } from 'astro/config'
import sitemap from '@astrojs/sitemap'
import aiReadiness from '@adkinn/astro-ai-readiness'
export default defineConfig({
site: 'https://your-site.com',
integrations: [
sitemap(), // recommended — AI Readiness baseline (D-8)
aiReadiness({
site: 'https://your-site.com',
organization: {
name: 'Your Brand',
url: 'https://your-site.com',
logo: 'https://your-site.com/logo.png',
founder: {
name: 'Your Name',
jobTitle: 'Founder',
sameAs: ['https://your-site.com', 'https://x.com/handle'],
},
},
webSite: {
// Optional. `name` defaults to organization.name when absent.
description: 'What your site does, in one sentence.',
},
llmsTxt: {
// Optional. When set, the toolkit ships dist/llms.txt at build time.
// Note: `summary` must be single-line — multi-paragraph summaries break
// the llms.txt blockquote shape. Use `body` (free-form markdown) for
// additional prose. Multi-line summary throws at config-validation time.
summary: 'What your site does, in one sentence — for AI agents discovering your content.',
body: 'A free-form markdown paragraph or two between summary and sections. Plain prose; no top-level H2 here (those are reserved for link sections below).',
sections: [
{
title: 'Articles',
links: [
{ title: 'All Articles', url: 'https://your-site.com/articles/' },
{ title: 'RSS Feed', url: 'https://your-site.com/rss.xml' },
],
},
],
deferTo: {
// Single canonical-reference link, rendered as a footer.
title: 'Articles Index',
url: 'https://your-site.com/articles/',
},
},
llmsFull: {
// Optional. When set, the toolkit ships dist/llms-full.txt at build time.
// v0.0.7 is manual/config-driven; later slices can derive sections from
// content collections.
sections: [
{
title: 'Site Context',
content: 'Long-form context agents should read before summarizing this site.',
},
{
title: 'Canonical Resources',
content: '- https://your-site.com/articles/\n- https://your-site.com/rss.xml',
},
],
},
agentsMd: {
// Optional. When set, the toolkit ships dist/agents.md at build time.
description: 'What your site does and who it serves — for AI-agent crawlers.',
audience: 'Developers and AI agents acting on their behalf.',
contact: 'hello@your-site.com',
links: [
{ title: 'Articles', url: 'https://your-site.com/articles/', description: 'All articles' },
{ title: 'RSS Feed', url: 'https://your-site.com/rss.xml', description: 'Machine-readable article stream' },
],
},
mcp: {
// Optional. When set, the toolkit ships dist/.well-known/mcp.json at build time.
// Each server must have status: 'active' or status: 'planned'.
// Active: requires url + tools[]. Planned: requires planned_tools[]; url is forbidden.
servers: [
{
// A live MCP server — must have url + tools.
status: 'active',
name: 'your-knowledge',
url: 'https://mcp.your-site.com',
description: 'MCP server exposing your site knowledge for AI agents.',
tools: [
{ name: 'search_articles', description: 'Search articles by keyword or tag.' },
{ name: 'fetch_article', description: 'Fetch a specific article by slug.' },
],
},
{
// A planned server — declares intent without a live URL.
status: 'planned',
name: 'your-future-server',
description: 'Planned MCP server for future capability.',
planned_tools: [
{ name: 'lookup', description: 'Lookup by ID once the server ships.' },
],
},
],
},
robotsTxt: {
// Optional. When set, the toolkit ships dist/robots.txt at build time.
// Default policy is "training-opt-out": ordinary search stays open while
// common model-training bot tokens are disallowed. Some vendors bundle
// training and grounding under one token, so override rules when needed.
policy: 'training-opt-out',
// Defaults to https://your-site.com/sitemap-index.xml. Set false to omit.
sitemap: 'https://your-site.com/sitemap-index.xml',
contentSignals: {
search: 'yes',
aiTrain: 'no',
aiInput: 'yes',
},
// Add or replace rules when your site has a specific bot policy.
additionalLines: [
'# Custom lines are appended before Sitemap.',
],
},
}),
],
})
> Note on raw markdown. llmsTxt.*, llmsFull.*, and agentsMd.* string fields are emitted as raw markdown. If you're templating user-generated content into those fields, escape ], ), and leading > to avoid breaking the rendered Markdown shape. Author-controlled strings (typical case) need no escaping. mcp.json is JSON-serialized and has no markdown-injection surface.
Use the components:
---
// src/layouts/BaseLayout.astro — site-wide
import { OrganizationSchema, WebSiteSchema } from '@adkinn/astro-ai-readiness/components'
---
` declares @id: '#organization'; ` references it. Order matters in the head — identity component first.
Personal-brand sites lead with a Person instead. Configure a person block (and omit organization if you don't need it), then:
---
// src/layouts/BaseLayout.astro — site-wide
import { PersonSchema, WebSiteSchema } from '@adkinn/astro-ai-readiness/components'
---
` declares @id: '#person'; when person is set, publisher and the llms.txt` heading follow it.
---
// src/pages/articles/index.astro — collection index pages
import { CollectionSchema } from '@adkinn/astro-ai-readiness/components'
---
---
// any multi-level page — site-context navigation
import { BreadcrumbSchema } from '@adkinn/astro-ai-readiness/components'
import type { BreadcrumbItem } from '@adkinn/astro-ai-readiness/components'
const crumbs: BreadcrumbItem[] = [
{ name: 'Home', url: new URL('/', Astro.site).toString() },
{ name: 'Articles', url: new URL('/articles/', Astro.site).toString() },
{ name: 'How agents handle errors', url: Astro.url.toString() },
]
---
---
// pages with FAQ data — items-array of question/answer pairs
import { FAQPageSchema } from '@adkinn/astro-ai-readiness/components'
import type { FAQItem } from '@adkinn/astro-ai-readiness/components'
const faqs: FAQItem[] = [
{ question: 'What is X?', answer: 'X is...' },
{ question: 'Why does Y matter?', answer: 'Because...' },
]
---
---
// article-detail pages — required props only
import { TechArticleSchema } from '@adkinn/astro-ai-readiness/components'
---
` defaults author to a Person synthesized from config.organization.founder (name from founder.name, url from founder.sameAs[0]). Pass an explicit author={{ name, url? }} to override on multi-author sites. The component throws at build time if author is omitted and founder is unset — actionable error pointing at the aiReadiness({...})` config.
Advanced — full prop surface:
Build your site (npm run build); inspect any dist/*.html — you'll see inline ` blocks with cross-referenced @id`s tying the entity graph together.
Design principles
- Zero client JS. Every component emits inline `` at build time. Hydrating JSON-LD would erode the very Schema.org category it's meant to lift.
- Compose, don't clobber.
robotsTxtexposes explicit rules and appended lines so user intent can override presets. If you already maintain a hand-writtenpublic/robots.txt, compare the generated file before adopting it. - Composes with
@astrojs/sitemap. Doesn't replace it. The integration warns when sitemap is missing androbotsTxtdefaults itsSitemapline to/sitemap-index.xml.
What's beyond v0.1
The v0.1 line is content → artifacts: components and files. Build-time AI-readiness self-scoring, spec validation against llmstxt.org, and content lints are on the v0.2 horizon — but not committed scope yet. v0.1 ships first.
Shipped on
- adamkinney.com — the personal-brand reference implementation. Person-first: runs
PersonSchema+WebSiteSchemasite-wide and emitsdist/llms.txtat anddist/agents.mdat . - comicscry.com — the app/product reference implementation (Astro 6 SSR,
@astrojs/cloudflare). RunsOrganizationSchema+WebSiteSchemasite-wide andSoftwareApplicationSchema+FAQPageSchemaon the homepage, and emitsdist/llms.txt,dist/agents.md, anddist/robots.txt. Drove the app/product features in v0.0.9–v0.0.10. - gurn.app — the game reference implementation (Astro 6 SSR,
@astrojs/cloudflare). RunsOrganizationSchema+WebSiteSchemasite-wide andSoftwareApplicationSchema(as aVideoGame) +FAQPageSchemaon the homepage, and emitsdist/llms.txt+dist/robots.txt. DroveVideoGame/gamePlatformsupport in v0.0.11.
Contributing
PRs welcome. See [CONTRIBUTING.md](./.github/CONTRIBUTING.md) and our [Code of Conduct](./CODEOFCONDUCT.md).
License
MIT — Copyright (c) 2026 Adam Kinney, LLC (DBA Obaron).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: adkinn
- Source: adkinn/astro-ai-readiness
- License: MIT
- Homepage: https://adamkinney.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.