Verified AgentReady.md certificate
Issued sig: 4a11b5ba8a9cb9b4 Verify →

Analyzed URL

https://stackharden.com

Analyze another URL

AI-Ready Score

76 / B

Good

out of 100

Token Savings

HTML tokens 5735
Markdown tokens 115
Savings 98%

Score Breakdown

Semantic HTML 93/100
Content Efficiency 70/100
AI Discoverability 47/100
Structured Data 92/100
Accessibility 93/100

Emerging protocols

0 of 3 detected

Well-known endpoints AI agents look for. Detected here means an agent can discover and connect to your service automatically.

  • OAuth Discovery RFC 8414
    /.well-known/oauth-authorization-server
  • MCP Server Card Anthropic
    /.well-known/mcp.json
  • A2A Agent Card Google
    /.well-known/agent.json

Your site doesn't have an llms.txt file. This is the emerging standard for helping AI agents understand your site structure.

How to implement

Create an /llms.txt file following the llmstxt.org specification. Include a site description and links to your key pages.

Your page has a low ratio of actual content to total HTML. Much of the page weight is markup, scripts, or styles rather than content.

How to implement

Move CSS to external stylesheets, remove inline styles, minimize JavaScript, and ensure the HTML focuses on content structure.

Your site doesn't support Markdown for Agents. This Cloudflare standard lets AI agents request content in markdown format, reducing token usage by ~80%.

How to implement

Implement one or more: (1) Respond to Accept: text/markdown with markdown content. (2) Serve .md URLs (e.g., /page.md). (3) Add <link rel="alternate" type="text/markdown"> tags. (4) Add Link HTTP headers for markdown discovery.

{\n res.setHeader('Vary', 'Accept');\n res.setHeader('Link', '; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n res.type('text/markdown; charset=utf-8');\n return res.send(renderMarkdown('page'));\n }\n res.render('page');\n});"},{"id":"fastify","label":"Fastify","language":"javascript","filename":"server.js","code":"// Mechanisms 1 + 4: content negotiation + Link header\nfastify.get('/page', async (req, reply) => {\n reply.header('Vary', 'Accept');\n reply.header('Link', '; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n return reply.type('text/markdown; charset=utf-8').send(renderMarkdown('page'));\n }\n return reply.view('/page.ejs');\n});"},{"id":"nextjs","label":"Next.js","language":"typescript","filename":"app/page/route.ts","code":"// Next.js App Router — Route Handler returning Markdown\nimport { NextRequest } from 'next/server';\nimport { renderMarkdown } from '@/lib/md';\nexport async function GET(req: NextRequest) {\n const accept = req.headers.get('accept') || '';\n if (accept.includes('text/markdown')) {\n return new Response(await renderMarkdown('page'), {\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Vary': 'Accept',\n },\n });\n }\n // Fall through to the page component\n return new Response(null, { status: 404 });\n}"},{"id":"wordpress","label":"WordPress","language":"php","filename":"functions.php","code":"post_content));\n exit;\n});"},{"id":"static","label":"Hugo / Jekyll / Astro","language":"txt","filename":"static/page.md","code":"# Mechanism 2: serve .md alongside .html\n# Hugo: place page.md in /static/ — built unchanged\n# Jekyll: drop page.md in /assets/ — copied as-is\n# Astro: src/pages/page.md.ts that exports a GET returning markdown\n\n# Then advertise with mechanism 3 in :\n# "}] }'>

Your heading structure has issues (skipped levels or multiple h1 tags). A clean hierarchy helps AI agents understand content organization.

How to implement

Ensure you have exactly one <h1> per page, and headings follow sequential order: h1 > h2 > h3. Don't skip levels (e.g., h1 directly to h3).

Missing or incomplete Open Graph tags. OG tags help AI agents (and social platforms) understand your page title, description, and image.

How to implement

Add og:title, og:description, and og:image meta tags to your page's <head>.

post_content), 30);\n $image = get_the_post_thumbnail_url($post, 'large') ?: 'https://yoursite.com/og-image.jpg';\n $url = get_permalink($post);\n printf('' . \"\\n\", esc_attr($title));\n printf('' . \"\\n\", esc_attr($desc));\n printf('' . \"\\n\", esc_url($image));\n printf('' . \"\\n\", esc_url($url));\n echo '' . \"\\n\";\n}, 5);"},{"id":"nextjs","label":"Next.js","language":"typescript","filename":"app/page.tsx","code":"// Next.js App Router — Metadata API\nimport type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: \"StackHarden\",\n description: \"Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\",\n openGraph: {\n title: \"StackHarden\",\n description: \"Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\",\n url: \"https://stackharden.com\",\n images: [\"https://yoursite.com/og-image.jpg\"],\n type: 'website',\n },\n};"}] }'>
Markdown tokens: 115
Practical infrastructure hardening for people who run real systems: SaaS builds, self-hosted apps, WordPress stacks, email servers, and VPS baselines. Every guide explains the security rationale and, where relevant, the NIS2 / ISO 27001 control it maps to — not just copy-paste commands.

Start with the [guides](https://stackharden.com/guides/), grab a [script](https://stackharden.com/scripts/), or run an [infrastructure checklist](https://stackharden.com/checklist/).
StackHarden

Practical infrastructure hardening for people who run real systems: SaaS builds, self-hosted apps, WordPress stacks, email servers, and VPS baselines. Every guide explains the security rationale and, where relevant, the NIS2 / ISO 27001 control it maps to — not just copy-paste commands.

Start with the [guides](https://stackharden.com/guides/), grab a [script](https://stackharden.com/scripts/), or run an [infrastructure checklist](https://stackharden.com/checklist/).

## Browse by series[All series →](https://stackharden.com/series/)

[### Data-tier hardening

Databases, caches, backups, and the logs they produce — PostgreSQL and Redis posture, backup and recovery patterns, log minimisation. The data layer of a production service and the operational trail …

7 pieces · Open series →](https://stackharden.com/series/data-tier-hardening/)[### AI security

Strategic and architectural pieces on deploying agentic AI in security contexts — control posture, reference architecture, threat modelling, prompt-injection defences, audit-trail design, with a …

3 pieces · Open series →](https://stackharden.com/series/ai-security/)[### Edge hardening

Nginx at the public boundary — modern TLS configuration, rate-limiting and fail2ban patterns, and the operational defaults that keep the edge from becoming the weak link.

3 pieces · Open series →](https://stackharden.com/series/edge-hardening/)[### Host hardening

Ubuntu and RHEL / AlmaLinux baselines, the SSH hardening they both depend on, and the system-state controls that turn a fresh provider image into a defensible internet-facing host.

3 pieces · Open series →](https://stackharden.com/series/host-hardening/)[### Compliance

NIS2, ISO 27001, and GDPR translated into the configurations, controls, and evidence an auditor will actually look at — with a short closing position on what is governance work that does not appear on …

2 pieces · Open series →](https://stackharden.com/series/compliance/)[### Launch readiness

Pre-launch verification — the 'have we actually done it' layer for new systems about to take production traffic. Currently anchored by the pre-launch VPS security checklist.

2 pieces · Open series →](https://stackharden.com/series/launch-readiness/)[### AI readiness

Making sites and services consumable by AI agents — Link headers, content signals, schema.org markup, and the emerging conventions that determine whether AI assistants can identify, ingest, and …

1 piece · Open series →](https://stackharden.com/series/ai-readiness/)[### App deployment

Practical deployment recipes for application stacks on a hardened VPS — gunicorn or equivalent under systemd, Caddy or Nginx in front, and the real-world integration bumps that only show up the first …

1 piece · Open series →](https://stackharden.com/series/app-deployment/)

## Latest checklists[All checklists →](https://stackharden.com/checklist/)

[### NIS2 Technical Readiness Checklist

A technical readiness checklist for the NIS2 risk-management measures that have a real surface on the box — hardening, patching, …

Open checklist →](https://stackharden.com/checklist/nis2-readiness/)[### Agentic AI Deployment Readiness Checklist

A design-review checklist for deploying an agentic AI system in a security context — architecture, threat model coverage, prompt-injection …

Open checklist →](https://stackharden.com/checklist/agentic-ai-deployment/)[### WordPress Hosting Security Checklist

A pre-launch and ongoing security checklist for agencies hosting WordPress sites — server isolation, wp-config flags, admin posture, plugin …

Open checklist →](https://stackharden.com/checklist/wordpress-security/)

## Latest guides[All guides →](https://stackharden.com/guides/)

[### Making a Static Site Agent-Ready: What I Changed, What I Didn't, and Why

A practitioner's walk-through of the agent-readiness signals that matter for a static content site on Hugo + Cloudflare Pages — Link headers, Content-Signal, the …

Read guide →](https://stackharden.com/guides/agent-readiness-static-site/)[### Building Agentic AI for Security: Architecture, Threat Modelling, and the Audit Trail You Will Actually Need

Reference architecture for an agentic AI security pipeline — STRIDE threat modelling, practical prompt-injection defences, and the audit trail your auditor will actually ask for.

Read guide →](https://stackharden.com/guides/agentic-ai-pipeline-reference/)[### Agentic AI in Security: Why Control Posture Matters More Than Capability

How to govern agentic AI in a security environment — human-in-the-loop vs human-on-the-loop, least privilege for autonomous systems, the prompt-injection attack surface, and the …

Read guide →](https://stackharden.com/guides/agentic-ai-control-posture/)[### Deploying a Flask Tools Site on a Hardened VPS Behind Caddy

A faithful walkthrough of deploying a small Flask app to a single VPS — system user, gunicorn over a unix socket, systemd with the hardening directives this site recommends, Caddy …

Read guide →](https://stackharden.com/guides/deploying-flask-on-caddy/)[### Log Minimisation Recipes — Nginx, Apache, PostgreSQL, Applications

Practical log\_format and configuration recipes that capture what you need for debugging and security without retaining what you don't. The application-layer companion to the …

Read guide →](https://stackharden.com/guides/log-minimisation-recipes/)[### Nginx Rate Limiting — limit\_req, limit\_conn, and fail2ban

Nginx rate limiting that actually protects authentication endpoints, signup flows, and expensive APIs — without locking out legitimate traffic. With sensible defaults and the …

Read guide →](https://stackharden.com/guides/nginx-ratelimit/)[### WordPress Hardening for Agencies

A WordPress hardening baseline aimed at agency hosting — server posture, wp-config flags, admin protection, plugin discipline, and the items that turn a CMS into a compliance …

Read guide →](https://stackharden.com/guides/wordpress-hardening/)[### Hardened RHEL / AlmaLinux VPS Baseline

A pragmatic RHEL 9 / AlmaLinux 9 hardening baseline — first-boot user setup, SSH, firewalld, automatic patching, SELinux verification, audit logging, and the order to apply them …

Read guide →](https://stackharden.com/guides/rhel-baseline/)[### Hardened Ubuntu VPS Baseline

A pragmatic Ubuntu 24.04 LTS hardening baseline — first-boot user setup, SSH, firewall, automatic security updates, audit logging, and time-sync — applied in the right order.

Read guide →](https://stackharden.com/guides/ubuntu-baseline/)[### Encrypted Backups with restic

An opinionated restic backup baseline — repository design, passphrase survival, retention, off-site targets, verification, and restoration drills. The compliance-friendly default …

Read guide →](https://stackharden.com/guides/encrypted-backups-restic/)

Emails when a new guide, script, or tool ships — roughly weekly, sometimes every few days. Double opt-in, no tracking.

[Subscribe →](https://stackharden.com/subscribe/)

[](https://stackharden.com/#top "Go to Top (Alt + G)")

[Subscribe](https://stackharden.com/subscribe/)  ·  [Write for us](https://stackharden.com/contribute/)  ·  [Privacy](https://stackharden.com/privacy/)  ·  [Cookies](https://stackharden.com/cookies/)  ·  [Disclaimer](https://stackharden.com/disclaimer/)

Operated by Data Vision IT Consulting Limited, Kilbride, Wicklow, Ireland.

Upload this file as /index.md on your server so AI agents can access a clean version of your page. You can also configure Accept: text/markdown content negotiation to serve it automatically.

Generated llms.txt for this single page

Download llms.txt
# StackHarden

> Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.

## Main
- [StackHarden](https://stackharden.com): Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context ba…
- [About](https://stackharden.com/about/)
- [StackHarden](https://stackharden.com/)
- [Guides](https://stackharden.com/guides/)
- [Scripts](https://stackharden.com/scripts/)
- [Checklists](https://stackharden.com/checklist/)
- [Learner](https://stackharden.com/learner/)
- [Series](https://stackharden.com/series/)
- [Next  »](https://stackharden.com/page/2/)

Full llms.txt requires domain-wide analysis (coming soon)

Upload this file to https://stackharden.com/llms.txt at the root of your domain. AI agents like ChatGPT, Claude, and Perplexity check this file to understand your site structure.

Semantic HTML

Uses article or main element (100/100)

Has <main>

Proper heading hierarchy (70/100)

no <h1>

Uses semantic HTML elements (100/100)

10 semantic elements, 11 divs (ratio: 48%)

Meaningful image alt texts (100/100)

No images found

Low div nesting depth (100/100)

Avg div depth: 0.1, max: 1

Content Efficiency

Good token reduction ratio (100/100)

98% token reduction (HTML→Markdown)

Good content-to-noise ratio (0/100)

Content ratio: 1.6% (364 content chars / 22163 HTML bytes)

Minimal inline styles (100/100)

0/216 elements with inline styles (0.0%)

Reasonable page weight (100/100)

HTML size: 22KB

AI Discoverability

Has llms.txt file (0/100)

No llms.txt found

Has robots.txt file (100/100)

robots.txt exists

Robots.txt allows AI bots (100/100)

All major AI bots allowed

Has sitemap.xml (100/100)

Sitemap found

Markdown for Agents support (0/100)
&#10007; Accept: text/markdown &#10007; .md URL &#10007; <link> tag &#10007; Link header
Has Content-Signal (robots.txt or HTTP headers) (60/100)
&#10003; robots.txt &#10007; HTTP header &#10007; Policy

Structured Data

Has Schema.org / JSON-LD (100/100)

JSON-LD found: Organization

Has Open Graph tags (67/100)

2/3 OG tags present

Has meta description (100/100)

Meta description: 126 chars

Has canonical URL (100/100)

Canonical URL present

Has lang attribute (100/100)

lang="en"

Accessibility

Content available without JavaScript (100/100)

Content available without JavaScript

Reasonable page size (100/100)

Page size: 22KB

Content appears early in HTML (75/100)

Main content starts at 30% of HTML

{
  "url": "https://stackharden.com",
  "timestamp": 1779829477776,
  "fetch": {
    "mode": "simple",
    "timeMs": 112,
    "htmlSizeBytes": 22163,
    "supportsMarkdown": false,
    "markdownAgents": {
      "contentNegotiation": false,
      "mdUrl": {
        "found": false,
        "url": null
      },
      "linkTag": {
        "found": false,
        "url": null
      },
      "linkHeader": {
        "found": false,
        "url": null
      },
      "responseHeaders": {
        "contentSignal": null,
        "xMarkdownTokens": null,
        "vary": null
      },
      "frontmatter": {
        "present": false,
        "fields": [],
        "level": "none"
      },
      "level": "none"
    },
    "statusCode": 200
  },
  "extraction": {
    "title": "StackHarden",
    "excerpt": "Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.",
    "byline": null,
    "siteName": "StackHarden",
    "lang": "en",
    "contentLength": 364,
    "metadata": {
      "description": "Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.",
      "ogTitle": "StackHarden",
      "ogDescription": "Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.",
      "ogImage": null,
      "ogType": "website",
      "canonical": "https://stackharden.com/",
      "lang": "en",
      "schemas": [
        {
          "@context": "https://schema.org",
          "@type": "Organization",
          "name": "StackHarden",
          "url": "https://stackharden.com/",
          "description": "Hardened infrastructure guides, scripts and tools for sysadmins and agencies",
          "logo": "https://stackharden.com/favicon.ico",
          "sameAs": []
        }
      ],
      "robotsMeta": "index, follow",
      "author": null,
      "generator": "Hugo 0.147.0",
      "markdownAlternateHref": null
    }
  },
  "markdown": "Practical infrastructure hardening for people who run real systems: SaaS builds, self-hosted apps, WordPress stacks, email servers, and VPS baselines. Every guide explains the security rationale and, where relevant, the NIS2 / ISO 27001 control it maps to — not just copy-paste commands.\n\nStart with the [guides](https://stackharden.com/guides/), grab a [script](https://stackharden.com/scripts/), or run an [infrastructure checklist](https://stackharden.com/checklist/).\n",
  "fullPageMarkdown": "StackHarden\n\nPractical infrastructure hardening for people who run real systems: SaaS builds, self-hosted apps, WordPress stacks, email servers, and VPS baselines. Every guide explains the security rationale and, where relevant, the NIS2 / ISO 27001 control it maps to — not just copy-paste commands.\n\nStart with the [guides](https://stackharden.com/guides/), grab a [script](https://stackharden.com/scripts/), or run an [infrastructure checklist](https://stackharden.com/checklist/).\n\n## Browse by series[All series →](https://stackharden.com/series/)\n\n[### Data-tier hardening\n\nDatabases, caches, backups, and the logs they produce — PostgreSQL and Redis posture, backup and recovery patterns, log minimisation. The data layer of a production service and the operational trail …\n\n7 pieces · Open series →](https://stackharden.com/series/data-tier-hardening/)[### AI security\n\nStrategic and architectural pieces on deploying agentic AI in security contexts — control posture, reference architecture, threat modelling, prompt-injection defences, audit-trail design, with a …\n\n3 pieces · Open series →](https://stackharden.com/series/ai-security/)[### Edge hardening\n\nNginx at the public boundary — modern TLS configuration, rate-limiting and fail2ban patterns, and the operational defaults that keep the edge from becoming the weak link.\n\n3 pieces · Open series →](https://stackharden.com/series/edge-hardening/)[### Host hardening\n\nUbuntu and RHEL / AlmaLinux baselines, the SSH hardening they both depend on, and the system-state controls that turn a fresh provider image into a defensible internet-facing host.\n\n3 pieces · Open series →](https://stackharden.com/series/host-hardening/)[### Compliance\n\nNIS2, ISO 27001, and GDPR translated into the configurations, controls, and evidence an auditor will actually look at — with a short closing position on what is governance work that does not appear on …\n\n2 pieces · Open series →](https://stackharden.com/series/compliance/)[### Launch readiness\n\nPre-launch verification — the 'have we actually done it' layer for new systems about to take production traffic. Currently anchored by the pre-launch VPS security checklist.\n\n2 pieces · Open series →](https://stackharden.com/series/launch-readiness/)[### AI readiness\n\nMaking sites and services consumable by AI agents — Link headers, content signals, schema.org markup, and the emerging conventions that determine whether AI assistants can identify, ingest, and …\n\n1 piece · Open series →](https://stackharden.com/series/ai-readiness/)[### App deployment\n\nPractical deployment recipes for application stacks on a hardened VPS — gunicorn or equivalent under systemd, Caddy or Nginx in front, and the real-world integration bumps that only show up the first …\n\n1 piece · Open series →](https://stackharden.com/series/app-deployment/)\n\n## Latest checklists[All checklists →](https://stackharden.com/checklist/)\n\n[### NIS2 Technical Readiness Checklist\n\nA technical readiness checklist for the NIS2 risk-management measures that have a real surface on the box — hardening, patching, …\n\nOpen checklist →](https://stackharden.com/checklist/nis2-readiness/)[### Agentic AI Deployment Readiness Checklist\n\nA design-review checklist for deploying an agentic AI system in a security context — architecture, threat model coverage, prompt-injection …\n\nOpen checklist →](https://stackharden.com/checklist/agentic-ai-deployment/)[### WordPress Hosting Security Checklist\n\nA pre-launch and ongoing security checklist for agencies hosting WordPress sites — server isolation, wp-config flags, admin posture, plugin …\n\nOpen checklist →](https://stackharden.com/checklist/wordpress-security/)\n\n## Latest guides[All guides →](https://stackharden.com/guides/)\n\n[### Making a Static Site Agent-Ready: What I Changed, What I Didn't, and Why\n\nA practitioner's walk-through of the agent-readiness signals that matter for a static content site on Hugo + Cloudflare Pages — Link headers, Content-Signal, the …\n\nRead guide →](https://stackharden.com/guides/agent-readiness-static-site/)[### Building Agentic AI for Security: Architecture, Threat Modelling, and the Audit Trail You Will Actually Need\n\nReference architecture for an agentic AI security pipeline — STRIDE threat modelling, practical prompt-injection defences, and the audit trail your auditor will actually ask for.\n\nRead guide →](https://stackharden.com/guides/agentic-ai-pipeline-reference/)[### Agentic AI in Security: Why Control Posture Matters More Than Capability\n\nHow to govern agentic AI in a security environment — human-in-the-loop vs human-on-the-loop, least privilege for autonomous systems, the prompt-injection attack surface, and the …\n\nRead guide →](https://stackharden.com/guides/agentic-ai-control-posture/)[### Deploying a Flask Tools Site on a Hardened VPS Behind Caddy\n\nA faithful walkthrough of deploying a small Flask app to a single VPS — system user, gunicorn over a unix socket, systemd with the hardening directives this site recommends, Caddy …\n\nRead guide →](https://stackharden.com/guides/deploying-flask-on-caddy/)[### Log Minimisation Recipes — Nginx, Apache, PostgreSQL, Applications\n\nPractical log\\_format and configuration recipes that capture what you need for debugging and security without retaining what you don't. The application-layer companion to the …\n\nRead guide →](https://stackharden.com/guides/log-minimisation-recipes/)[### Nginx Rate Limiting — limit\\_req, limit\\_conn, and fail2ban\n\nNginx rate limiting that actually protects authentication endpoints, signup flows, and expensive APIs — without locking out legitimate traffic. With sensible defaults and the …\n\nRead guide →](https://stackharden.com/guides/nginx-ratelimit/)[### WordPress Hardening for Agencies\n\nA WordPress hardening baseline aimed at agency hosting — server posture, wp-config flags, admin protection, plugin discipline, and the items that turn a CMS into a compliance …\n\nRead guide →](https://stackharden.com/guides/wordpress-hardening/)[### Hardened RHEL / AlmaLinux VPS Baseline\n\nA pragmatic RHEL 9 / AlmaLinux 9 hardening baseline — first-boot user setup, SSH, firewalld, automatic patching, SELinux verification, audit logging, and the order to apply them …\n\nRead guide →](https://stackharden.com/guides/rhel-baseline/)[### Hardened Ubuntu VPS Baseline\n\nA pragmatic Ubuntu 24.04 LTS hardening baseline — first-boot user setup, SSH, firewall, automatic security updates, audit logging, and time-sync — applied in the right order.\n\nRead guide →](https://stackharden.com/guides/ubuntu-baseline/)[### Encrypted Backups with restic\n\nAn opinionated restic backup baseline — repository design, passphrase survival, retention, off-site targets, verification, and restoration drills. The compliance-friendly default …\n\nRead guide →](https://stackharden.com/guides/encrypted-backups-restic/)\n\nEmails when a new guide, script, or tool ships — roughly weekly, sometimes every few days. Double opt-in, no tracking.\n\n[Subscribe →](https://stackharden.com/subscribe/)\n\n[](https://stackharden.com/#top \"Go to Top (Alt + G)\")\n\n[Subscribe](https://stackharden.com/subscribe/)  ·  [Write for us](https://stackharden.com/contribute/)  ·  [Privacy](https://stackharden.com/privacy/)  ·  [Cookies](https://stackharden.com/cookies/)  ·  [Disclaimer](https://stackharden.com/disclaimer/)\n\nOperated by Data Vision IT Consulting Limited, Kilbride, Wicklow, Ireland.\n",
  "markdownStats": {
    "images": 0,
    "links": 3,
    "tables": 0,
    "codeBlocks": 0,
    "headings": 0
  },
  "tokens": {
    "htmlTokens": 5735,
    "markdownTokens": 115,
    "reduction": 5620,
    "reductionPercent": 98
  },
  "score": {
    "score": 76,
    "grade": "B",
    "dimensions": {
      "semanticHtml": {
        "score": 93,
        "weight": 20,
        "grade": "A",
        "checks": {
          "uses_article_or_main": {
            "score": 100,
            "weight": 20,
            "details": "Has <main>"
          },
          "proper_heading_hierarchy": {
            "score": 70,
            "weight": 25,
            "details": "no <h1>"
          },
          "semantic_elements": {
            "score": 100,
            "weight": 20,
            "details": "10 semantic elements, 11 divs (ratio: 48%)"
          },
          "meaningful_alt_texts": {
            "score": 100,
            "weight": 15,
            "details": "No images found"
          },
          "low_div_nesting": {
            "score": 100,
            "weight": 20,
            "details": "Avg div depth: 0.1, max: 1"
          }
        }
      },
      "contentEfficiency": {
        "score": 70,
        "weight": 25,
        "grade": "C",
        "checks": {
          "token_reduction_ratio": {
            "score": 100,
            "weight": 40,
            "details": "98% token reduction (HTML→Markdown)"
          },
          "content_to_noise_ratio": {
            "score": 0,
            "weight": 30,
            "details": "Content ratio: 1.6% (364 content chars / 22163 HTML bytes)"
          },
          "minimal_inline_styles": {
            "score": 100,
            "weight": 15,
            "details": "0/216 elements with inline styles (0.0%)"
          },
          "reasonable_page_weight": {
            "score": 100,
            "weight": 15,
            "details": "HTML size: 22KB"
          }
        }
      },
      "aiDiscoverability": {
        "score": 47,
        "weight": 25,
        "grade": "D",
        "checks": {
          "has_llms_txt": {
            "score": 0,
            "weight": 20,
            "details": "No llms.txt found"
          },
          "has_robots_txt": {
            "score": 100,
            "weight": 10,
            "details": "robots.txt exists"
          },
          "robots_allows_ai_bots": {
            "score": 100,
            "weight": 15,
            "details": "All major AI bots allowed"
          },
          "has_sitemap": {
            "score": 100,
            "weight": 10,
            "details": "Sitemap found"
          },
          "supports_markdown_negotiation": {
            "score": 0,
            "weight": 25,
            "details": "No Markdown for Agents support detected"
          },
          "has_content_signals": {
            "score": 60,
            "weight": 20,
            "details": "robots.txt: search=yes, ai-input=yes, ai-train=no"
          }
        }
      },
      "structuredData": {
        "score": 92,
        "weight": 15,
        "grade": "A",
        "checks": {
          "has_schema_org": {
            "score": 100,
            "weight": 30,
            "details": "JSON-LD found: Organization"
          },
          "has_open_graph": {
            "score": 67,
            "weight": 25,
            "details": "2/3 OG tags present"
          },
          "has_meta_description": {
            "score": 100,
            "weight": 20,
            "details": "Meta description: 126 chars"
          },
          "has_canonical_url": {
            "score": 100,
            "weight": 15,
            "details": "Canonical URL present"
          },
          "has_lang_attribute": {
            "score": 100,
            "weight": 10,
            "details": "lang=\"en\""
          }
        }
      },
      "accessibility": {
        "score": 93,
        "weight": 15,
        "grade": "A",
        "checks": {
          "content_without_js": {
            "score": 100,
            "weight": 40,
            "details": "Content available without JavaScript"
          },
          "reasonable_page_size": {
            "score": 100,
            "weight": 30,
            "details": "Page size: 22KB"
          },
          "fast_content_position": {
            "score": 75,
            "weight": 30,
            "details": "Main content starts at 30% of HTML"
          }
        }
      }
    }
  },
  "recommendations": [
    {
      "id": "add_llms_txt",
      "priority": "critical",
      "category": "aiDiscoverability",
      "titleKey": "rec.add_llms_txt.title",
      "descriptionKey": "rec.add_llms_txt.description",
      "howToKey": "rec.add_llms_txt.howto",
      "effort": "quick-win",
      "estimatedImpact": 10,
      "checkScore": 0,
      "checkDetails": "No llms.txt found"
    },
    {
      "id": "improve_content_ratio",
      "priority": "critical",
      "category": "contentEfficiency",
      "titleKey": "rec.improve_content_ratio.title",
      "descriptionKey": "rec.improve_content_ratio.description",
      "howToKey": "rec.improve_content_ratio.howto",
      "effort": "moderate",
      "estimatedImpact": 6,
      "checkScore": 0,
      "checkDetails": "Content ratio: 1.6% (364 content chars / 22163 HTML bytes)"
    },
    {
      "id": "add_markdown_negotiation",
      "priority": "critical",
      "category": "aiDiscoverability",
      "titleKey": "rec.add_markdown_negotiation.title",
      "descriptionKey": "rec.add_markdown_negotiation.description",
      "howToKey": "rec.add_markdown_negotiation.howto",
      "effort": "significant",
      "estimatedImpact": 6,
      "checkScore": 0,
      "checkDetails": "No Markdown for Agents support detected"
    },
    {
      "id": "fix_heading_hierarchy",
      "priority": "medium",
      "category": "semanticHtml",
      "titleKey": "rec.fix_heading_hierarchy.title",
      "descriptionKey": "rec.fix_heading_hierarchy.description",
      "howToKey": "rec.fix_heading_hierarchy.howto",
      "effort": "quick-win",
      "estimatedImpact": 6,
      "checkScore": 70,
      "checkDetails": "no <h1>"
    },
    {
      "id": "add_open_graph",
      "priority": "medium",
      "category": "structuredData",
      "titleKey": "rec.add_open_graph.title",
      "descriptionKey": "rec.add_open_graph.description",
      "howToKey": "rec.add_open_graph.howto",
      "effort": "quick-win",
      "estimatedImpact": 4,
      "checkScore": 67,
      "checkDetails": "2/3 OG tags present"
    }
  ],
  "llmsTxtPreview": "# StackHarden\n\n> Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\n\n## Main\n- [StackHarden](https://stackharden.com): Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context ba…\n- [About](https://stackharden.com/about/)\n- [StackHarden](https://stackharden.com/)\n- [Guides](https://stackharden.com/guides/)\n- [Scripts](https://stackharden.com/scripts/)\n- [Checklists](https://stackharden.com/checklist/)\n- [Learner](https://stackharden.com/learner/)\n- [Series](https://stackharden.com/series/)\n- [Next  »](https://stackharden.com/page/2/)\n\n",
  "llmsTxtExisting": null,
  "emergingProtocols": {
    "oauthDiscovery": {
      "exists": false,
      "url": "https://stackharden.com/.well-known/oauth-authorization-server"
    },
    "mcpServerCard": {
      "exists": false,
      "url": "https://stackharden.com/.well-known/mcp.json"
    },
    "a2aAgentCard": {
      "exists": false,
      "url": "https://stackharden.com/.well-known/agent.json"
    },
    "count": 0
  },
  "snippets": [
    {
      "id": "add_llms_txt",
      "title": "Create /llms.txt",
      "description": "Upload this file to your web root. It tells AI agents what your site is about and which pages matter.",
      "language": "markdown",
      "code": "# StackHarden\n\n> Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\n\n## Main\n- [StackHarden](https://stackharden.com): Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context ba…\n- [About](https://stackharden.com/about/)\n- [StackHarden](https://stackharden.com/)\n- [Guides](https://stackharden.com/guides/)\n- [Scripts](https://stackharden.com/scripts/)\n- [Checklists](https://stackharden.com/checklist/)\n- [Learner](https://stackharden.com/learner/)\n- [Series](https://stackharden.com/series/)\n- [Next  »](https://stackharden.com/page/2/)\n\n",
      "filename": "/llms.txt"
    },
    {
      "id": "fix_heading_hierarchy",
      "title": "Fix heading hierarchy",
      "description": "Your page has no <h1>. Every page needs exactly one <h1> as the main heading. Add it inside your <main> or <article>.",
      "language": "html",
      "code": "<h1>StackHarden</h1>",
      "filename": "<main> or <article>"
    },
    {
      "id": "add_open_graph",
      "title": "Add missing Open Graph tags",
      "description": "Open Graph tags control how your page looks when shared on social media and how AI platforms preview your URL in answers.",
      "language": "html",
      "code": "<meta property=\"og:image\" content=\"https://yoursite.com/og-image.jpg\">\n<meta property=\"og:url\" content=\"https://stackharden.com\">\n<meta property=\"og:type\" content=\"website\">",
      "filename": "<head>",
      "stacks": [
        {
          "id": "html",
          "label": "HTML <head>",
          "language": "html",
          "filename": "<head>",
          "code": "<meta property=\"og:image\" content=\"https://yoursite.com/og-image.jpg\">\n<meta property=\"og:url\" content=\"https://stackharden.com\">\n<meta property=\"og:type\" content=\"website\">"
        },
        {
          "id": "wordpress",
          "label": "WordPress",
          "language": "php",
          "filename": "functions.php",
          "code": "<?php\n// Quick Open Graph tags without a plugin (skip if Yoast / Rank Math is active)\nadd_action('wp_head', function () {\n    if (!is_singular()) return;\n    $post = get_queried_object();\n    $title = get_the_title($post);\n    $desc  = get_the_excerpt($post) ?: wp_trim_words(strip_tags($post->post_content), 30);\n    $image = get_the_post_thumbnail_url($post, 'large') ?: 'https://yoursite.com/og-image.jpg';\n    $url   = get_permalink($post);\n    printf('<meta property=\"og:title\" content=\"%s\">' . \"\\n\", esc_attr($title));\n    printf('<meta property=\"og:description\" content=\"%s\">' . \"\\n\", esc_attr($desc));\n    printf('<meta property=\"og:image\" content=\"%s\">' . \"\\n\", esc_url($image));\n    printf('<meta property=\"og:url\" content=\"%s\">' . \"\\n\", esc_url($url));\n    echo '<meta property=\"og:type\" content=\"article\">' . \"\\n\";\n}, 5);"
        },
        {
          "id": "nextjs",
          "label": "Next.js",
          "language": "typescript",
          "filename": "app/page.tsx",
          "code": "// Next.js App Router — Metadata API\nimport type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n  title: \"StackHarden\",\n  description: \"Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\",\n  openGraph: {\n    title: \"StackHarden\",\n    description: \"Hardened infrastructure guides, scripts and tools for sysadmins and small agencies — with NIS2 and ISO 27001 context baked in.\",\n    url: \"https://stackharden.com\",\n    images: [\"https://yoursite.com/og-image.jpg\"],\n    type: 'website',\n  },\n};"
        }
      ]
    },
    {
      "id": "add_markdown_negotiation",
      "title": "Support Markdown for Agents",
      "description": "Let AI agents request a clean Markdown version of any page via content negotiation, .md alternate URLs, link tags or Link headers.",
      "language": "html",
      "code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">",
      "filename": "<head>",
      "stacks": [
        {
          "id": "html",
          "label": "HTML <head>",
          "language": "html",
          "filename": "<head>",
          "code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
        },
        {
          "id": "express",
          "label": "Express",
          "language": "javascript",
          "filename": "server.js",
          "code": "// Mechanisms 1 + 4: content negotiation + Link header\napp.get('/page', (req, res) => {\n  res.setHeader('Vary', 'Accept');\n  res.setHeader('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n  if ((req.headers.accept || '').includes('text/markdown')) {\n    res.type('text/markdown; charset=utf-8');\n    return res.send(renderMarkdown('page'));\n  }\n  res.render('page');\n});"
        },
        {
          "id": "fastify",
          "label": "Fastify",
          "language": "javascript",
          "filename": "server.js",
          "code": "// Mechanisms 1 + 4: content negotiation + Link header\nfastify.get('/page', async (req, reply) => {\n  reply.header('Vary', 'Accept');\n  reply.header('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n  if ((req.headers.accept || '').includes('text/markdown')) {\n    return reply.type('text/markdown; charset=utf-8').send(renderMarkdown('page'));\n  }\n  return reply.view('/page.ejs');\n});"
        },
        {
          "id": "nextjs",
          "label": "Next.js",
          "language": "typescript",
          "filename": "app/page/route.ts",
          "code": "// Next.js App Router — Route Handler returning Markdown\nimport { NextRequest } from 'next/server';\nimport { renderMarkdown } from '@/lib/md';\nexport async function GET(req: NextRequest) {\n  const accept = req.headers.get('accept') || '';\n  if (accept.includes('text/markdown')) {\n    return new Response(await renderMarkdown('page'), {\n      headers: {\n        'Content-Type': 'text/markdown; charset=utf-8',\n        'Vary': 'Accept',\n      },\n    });\n  }\n  // Fall through to the page component\n  return new Response(null, { status: 404 });\n}"
        },
        {
          "id": "wordpress",
          "label": "WordPress",
          "language": "php",
          "filename": "functions.php",
          "code": "<?php\n// Mechanism 1: respond to Accept: text/markdown on the same URL\nadd_action('template_redirect', function () {\n    if (!is_singular()) return;\n    $accept = $_SERVER['HTTP_ACCEPT'] ?? '';\n    if (strpos($accept, 'text/markdown') === false) return;\n    header('Content-Type: text/markdown; charset=utf-8');\n    header('Vary: Accept');\n    $post = get_queried_object();\n    echo \"# \" . get_the_title($post) . \"\\n\\n\";\n    echo wp_strip_all_tags(apply_filters('the_content', $post->post_content));\n    exit;\n});"
        },
        {
          "id": "static",
          "label": "Hugo / Jekyll / Astro",
          "language": "txt",
          "filename": "static/page.md",
          "code": "# Mechanism 2: serve .md alongside .html\n# Hugo: place page.md in /static/ — built unchanged\n# Jekyll: drop page.md in /assets/ — copied as-is\n# Astro: src/pages/page.md.ts that exports a GET returning markdown\n\n# Then advertise with mechanism 3 in <head>:\n#   <link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
        }
      ]
    }
  ]
}

Use our API to get this programmatically (coming soon)

This JSON is for internal use — unlike the Markdown and llms.txt files, it's not meant to be uploaded to your site. Save it as a baseline to track your score over time, share it with your dev team, or integrate it into your CI/CD pipeline.

Share your results

Twitter LinkedIn

Embed your badge

Add this badge to your site. It updates automatically as your AI-readiness score changes.

AgentReady.md score for stackharden.com
Script Recommended
<script src="https://agentready.md/badge.js" data-id="ae0ab0c0-3510-4b0a-acb3-d0a80078b1bd" data-domain="stackharden.com"></script>
Markdown
[![AgentReady.md score for stackharden.com](https://agentready.md/badge/stackharden.com.svg)](https://agentready.md/r/ae0ab0c0-3510-4b0a-acb3-d0a80078b1bd)

Coming soon: Full Domain Analysis

Crawl your entire domain, generate llms.txt, and monitor your AI-readiness score over time. Join the waitlist to be notified.

You're on the list! We'll notify you when it launches.