npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@obaronai/astro-ai-readiness

v0.0.6

Published

AI Readiness toolkit for Astro — six JSON-LD components + dist/llms.txt, dist/agents.md, dist/.well-known/mcp.json. dist/llms-full.txt and dist/robots.txt on the roadmap.

Downloads

699

Readme

@obaronai/astro-ai-readiness

AI Readiness toolkit for Astro — six JSON-LD helper components plus dist/llms.txt, dist/agents.md, and dist/.well-known/mcp.json today; llms-full.txt and robots.txt on the v0.1 roadmap.

Status: v0.0.6 — sixth slice shipped. Component sub-line complete (6 of 6); three of five file outputs live. Multi-output orchestration on the astro:build:done hook is established — subsequent file-output slices wire in without hook changes.

What ships in v0.0.6

Six JSON-LD components (component sub-line complete):

  • <OrganizationSchema /> — Organization block. Config-driven; place in your BaseLayout so it ships site-wide and the #organization @id reference resolves on every page.
  • <WebSiteSchema /> — WebSite block. Config-driven; alongside <OrganizationSchema /> in BaseLayout.
  • <CollectionSchema name url description? /> — CollectionPage block. Props-driven; place on collection-index pages (/articles/, /tags/[tag]/, etc.).
  • <BreadcrumbSchema items={[{ name, url }, ...]} /> — BreadcrumbList. Items-array prop; place on multi-level pages where the navigation hierarchy isn't already declared inline. Empty items skips emission.
  • <FAQPageSchema items={[{ question, answer }, ...]} /> — FAQPage. Items-array prop; place on pages with FAQ data. Long-form answers escape </script> and U+2028 / U+2029 automatically. Empty items skips emission.
  • <TechArticleSchema headline description datePublished {...optional} /> — TechArticle block. Heavy-props; place on article-detail pages. author defaults to a Person synthesized from config.organization.founder; pass an explicit author prop to override.

Three file outputs (three of five file-output sub-line entries live):

  • dist/llms.txtllmstxt.org format from the llmsTxt config block. H1 / blockquote summary / optional body / H2 sections with bulleted links / optional canonical-reference footer. Opt-in.
  • dist/agents.md — Markdown discovery file for AI-agent crawlers from the agentsMd config block. H1 / blockquote description / optional ## Audience, ## Contact, ## Links sections. Opt-in.
  • dist/.well-known/mcp.jsonModel Context Protocol discovery file from the mcp config block. Pretty-printed JSON with $schema reference to the toolkit-published v1 shape (per D-22). Supports status: 'active' (requires url + tools[]) and status: 'planned' (requires planned_tools[]; url forbidden by schema). Opt-in.

@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; the sitemap reference itself ships in robots.txt (v0.0.8).

All six components emit canonical Schema.org JSON-LD with cross-component @id references (#organization, #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.

On the roadmap (toward v0.1.0)

  • v0.0.7 — dist/llms-full.txt (content-collection introspection — first time the toolkit reads consumer content)
  • v0.0.8 — dist/robots.txt composition (compose-with-existing pattern; sitemap reference lands here)
  • v0.1.0 — polish, tests, docs; FF-3.7 full install (obaron.ai)

Track progress: https://github.com/obaronai/astro-ai-readiness/milestones

Install

npm install @obaronai/astro-ai-readiness

Quick start

Configure (v0.0.6 accepts site, organization, optional webSite, optional llmsTxt, optional agentsMd, and optional mcp blocks — 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 '@obaronai/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/',
        },
      },
      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: '[email protected]',
        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.' },
            ],
          },
        ],
      },
    }),
  ],
})

Note on raw markdown. llmsTxt.* and agentsMd.* string fields are emitted as raw markdown. If you're templating user-generated content into llmsTxt.summary, llmsTxt.body, llmsTxt.sections[].*.title, agentsMd.description, agentsMd.audience, agentsMd.contact, or agentsMd.links[].*.title / agentsMd.links[].*.description, 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 '@obaronai/astro-ai-readiness/components'
---
<head>
  <OrganizationSchema />
  <WebSiteSchema />
</head>

<OrganizationSchema /> declares @id: '<site>#organization'; <WebSiteSchema /> references it. Order matters in the head — Organization first.

---
// src/pages/articles/index.astro — collection index pages
import { CollectionSchema } from '@obaronai/astro-ai-readiness/components'
---
<CollectionSchema
  name="All Articles"
  url={new URL('articles/', Astro.site).toString()}
  description="Production-tested articles, version-pinned environments."
/>
---
// any multi-level page — site-context navigation
import { BreadcrumbSchema } from '@obaronai/astro-ai-readiness/components'
import type { BreadcrumbItem } from '@obaronai/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() },
]
---
<BreadcrumbSchema items={crumbs} />
---
// pages with FAQ data — items-array of question/answer pairs
import { FAQPageSchema } from '@obaronai/astro-ai-readiness/components'
import type { FAQItem } from '@obaronai/astro-ai-readiness/components'

const faqs: FAQItem[] = [
  { question: 'What is X?', answer: 'X is...' },
  { question: 'Why does Y matter?', answer: 'Because...' },
]
---
<FAQPageSchema items={faqs} />
---
// article-detail pages — required props only
import { TechArticleSchema } from '@obaronai/astro-ai-readiness/components'
---
<TechArticleSchema
  headline="How agents handle errors"
  description="A pattern for agent error handling that doesn't lose context."
  datePublished="2026-04-01T12:00:00Z"
/>

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

<TechArticleSchema
  headline={article.title}
  description={article.description}
  datePublished={article.pubDate.toISOString()}
  dateModified={(article.updatedDate ?? article.pubDate).toISOString()}
  author={{ name: 'Guest Author', url: 'https://example.com' }}
  image={{ url: 'https://your-site.com/og.png', width: 1200, height: 630 }}
  articleSection="Tutorials"
  keywords={['ai', 'agents', 'error-handling']}
  proficiencyLevel="intermediate"
  dependencies={['Node 22', 'Astro 5.5']}
/>

Build your site (npm run build); inspect any dist/*.html — you'll see inline <script type="application/ld+json"> blocks with cross-referenced @ids tying the entity graph together.

Design principles

  • Zero client JS. Every component emits inline <script type="application/ld+json"> at build time. Hydrating JSON-LD would erode the very Schema.org category it's meant to lift.
  • Compose, don't clobber. Future file outputs (robots.txt etc.) will merge with existing user files rather than overwrite. User intent wins.
  • Composes with @astrojs/sitemap. Doesn't replace it. Will warn when needed once sitemap-touching outputs land.

What's beyond v0.1

The v0.1 line is content → artifacts: components and files. Build-time AI-readiness self-scoring (against Obaron's published rubric), 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

Contributing

PRs welcome. See CONTRIBUTING.md and our Code of Conduct.

License

MIT — Copyright (c) 2026 Adam Kinney, LLC (DBA Obaron).