Install
$ agentstack add mcp-dibbayajyotiroy-ahtml ✓ 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 Used
- ✓ 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
AHTML
> The contract layer of the agent web. One config in, every agent-readable > protocol out — MCP, OpenAPI 3.1, JSON-LD, llms.txt, RSL, Markdown, and a > token-optimal snapshot — plus signed provenance, verified-agent auth, and > priced actions.
[](https://www.npmjs.com/package/@ahtmljs/next) [](https://www.npmjs.com/package/@ahtmljs/schema) [](https://www.npmjs.com/package/@ahtmljs/cli) [](LICENSE) [](https://modelcontextprotocol.io) [](https://spec.openapis.org/oas/v3.1.0) [](https://json-schema.org/draft/2020-12) [](https://docs.npmjs.com/generating-provenance-statements) [](TESTING.md)
npm install @ahtmljs/next @ahtmljs/schema
// app/ahtml/[[...path]]/route.ts
import { createAHTMLRoute } from '@ahtmljs/next/handler';
import { snapshot } from '@ahtmljs/schema';
export const { GET, HEAD } = createAHTMLRoute(async (segments, req) => {
if (segments[0] !== 'products') return null;
const p = await db.product.findUnique({ where: { slug: segments[1] } });
return snapshot(req.url, 'product_detail')
.ttl(60)
.add({ id: `product:${p.slug}`, type: 'product', name: p.name,
price: { amount: p.price, currency: 'USD' },
stock: { status: p.qty > 0 ? 'in_stock' : 'out_of_stock' } })
.action({ id: 'purchase', target: `product:${p.slug}`, category: 'transact',
execute_url: '/api/checkout', auth: 'required',
cost: { amount: p.price, currency: 'USD', category: 'purchase',
rails: ['x402'] }, // priced action (v0.9.5)
reversible: { reversible: true, window: 'P30D' },
side_effects: ['charge_card', 'decrement_stock'],
confirmation: 'required' })
.build();
});
Your Next.js app now serves MCP tools at /ahtml/mcp.json, OpenAPI at /ahtml/openapi.json, JSON-LD inline in HTML, a discovery manifest at /.well-known/ahtml.json, an llms.txt shim, RSL at /rsl.txt, a Markdown view over content negotiation, and a token-optimal agent snapshot at /ahtml/ — all from the same source.
What is AHTML
The web that browsers see and the web that agents see are diverging. Browsers render pixels. Agents pay for tokens. A modern product page can ship 300 KB of nav, footer, tracking, and ad chrome — and an autonomous shopping agent pays for every byte. AHTML lets your site publish a typed semantic snapshot alongside its HTML: entities with stable IDs, actions with explicit cost / reversibility / auth / side-effects, freshness metadata, site-wide policy, cryptographic provenance via detached JWS (v0.8), and — as of v0.9.5 — verified-agent authentication (RFC 9421 signed requests) and priced actions (x402 machine payments + RSL 1.0 licensing).
The plugin auto-generates MCP tool manifests, OpenAPI 3.1 documents, JSON-LD fragments, the llms.txt discovery convention, an RSL 1.0 license file, and a Markdown view — all from the same source. Browsers see the same HTML. AHTML is additive — there is no migration.
And the whole toolchain works on any URL today, not just adopters: the @ahtmljs/cli and @ahtmljs/agent extract typed objects from ordinary HTML (schema.org + OpenGraph + microdata + data-attrs) when a site hasn't adopted AHTML yet.
The nine packages
Nine npm packages under the @ahtmljs scope, all published at the same version and released together. Grouped by what you're building:
Contract layer
| Package | What it is | Install when | |---|---|---| | [@ahtmljs/schema](packages/schema) | Snapshot types, validator, dual-format serializers (canonical JSON + token-optimal compact), Markdown + RSL emitters, diff, builder, JSON Schema, HTTP Message Signatures, x402 helpers, policy presets. Pure ESM + CJS, edge-runtime safe. Houses the emitters for well-known, MCP, OpenAPI, and llms.txt (re-exported by adapters). | You want the contract without a framework adapter — Express, Bun, Deno, Workers, or hand-rolled routes. |
Make your site agent-readable (site adapters)
| Package | What it is | Install when | |---|---|---| | [@ahtmljs/next](packages/next) | Next.js 14+/15 App Router plugin. createAHTMLRoute, createWellKnownRoute, createLlmsTxtRoute, MCP + OpenAPI emitters, JSON-LD injector, policy block, verifyAgents config, withPaymentGuard. | You ship a Next.js app and want it to be an MCP server. | | [@ahtmljs/vite](packages/vite) | Vite plugin. Wires the same handler into SvelteKit, SolidStart, Astro, and vanilla Vite. Byte-identical output to the Next adapter. | You ship a Vite-based app and want the same emitters. | | [@ahtmljs/hono](packages/hono) | Hono adapter — one mountAHTML(app, config) call. Runs on Node, Bun, Deno, Cloudflare Workers, and AWS Lambda. Edge-first, no node:* in the hot path. | You ship a Hono app or want the same surface on the edge / Workers. |
Read the agent web (agent-side)
| Package | What it is | Install when | |---|---|---| | [@ahtmljs/agent](packages/agent) | Client SDK: typed-error fetcher, ETag-conditional GET, diff replay, request coalescing, retry with jittered backoff, timeout, dry-run, real gpt-tokenizer + @anthropic-ai/tokenizer cost estimation, streaming reader, fetchPage() universal read with HTML fallback, agent request signing. | You are building an AI agent that reads other people's sites. | | [@ahtmljs/langchain](packages/langchain) | LangChain.js document loader. Fetches any AHTML-emitting site and yields Documents with chunk boundaries, citation anchors, and metadata preserved. | You are building a RAG pipeline and want to cite a web page in a RAG answer without re-scraping HTML. |
Tooling & infrastructure
| Package | What it is | Install when | |---|---|---| | [@ahtmljs/cli](packages/cli) | The AHTML CLI — analyze, score, doctor, extract, benchmark, mcp (stdio MCP proxy), llms (site→llms.txt crawler). Works on any URL, adopter or not. | You want to audit, score, or turn any site into MCP tools from your terminal or agent. | | [@ahtmljs/kv](packages/kv) | Pluggable KV / cache / rate-limit backends: in-memory, Upstash Redis, Cloudflare KV. Backend-agnostic token-bucket RateLimiter. | You need caching or per-agent rate limiting at the edge. | | [@ahtmljs/webmcp](packages/webmcp) | Registers AHTML page actions as native WebMCP browser tools (Chrome 149+ origin trial), with AHTML's richer cost/reversibility/confirmation metadata as annotations. Plus a zero-install bookmarklet inspector. | You want browser-embedded AI assistants to call your page's actions safely. |
Common install combos:
# site owner — make your site agent-readable (Next.js)
npm install @ahtmljs/next @ahtmljs/schema
# same, on the edge / Cloudflare Workers
npm install @ahtmljs/hono @ahtmljs/schema hono
# agent author — read the agent web (with HTML fallback for non-adopters)
npm install @ahtmljs/agent @ahtmljs/schema
# audit / score / proxy any URL — no install
npx @ahtmljs/cli analyze https://example.com
Works on any URL today — the CLI
You don't need a site to adopt AHTML to get value. @ahtmljs/cli extracts typed objects from ordinary HTML and turns any site into MCP tools:
npx @ahtmljs/cli analyze https://example.com # bytes → tokens → savings %, entity counts, agent-readiness probe
npx @ahtmljs/cli score https://example.com # Lighthouse-for-agents: 0–100 score, A–F grade, copy-paste fix
npx @ahtmljs/cli doctor https://example.com # audit the AHTML discovery chain + verify signatures
npx @ahtmljs/cli extract https://example.com # schema.org + OpenGraph + microdata + data-attrs → snapshot
npx @ahtmljs/cli benchmark https://example.com # HTML vs JSON-LD vs AHTML compact vs AHTML JSON table
npx @ahtmljs/cli mcp https://example.com # stdio MCP proxy — any URL becomes typed MCP tools in Claude/Cursor
npx @ahtmljs/cli llms https://example.com # crawl a site → spec-compliant llms.txt
ahtml mcp is claude mcp add-compatible: it probes /.well-known/ahtml.json and proxies to the real endpoint for adopters, and auto-extracts from plain HTML for everyone else. Four universal MCP tools — fetch_page, list_pages, search, and invoke_action (adopters).
One config, every protocol
A single buildSnapshot function feeds every output below. No parallel implementations.
| Output | Endpoint | Format | Consumer | |---|---|---|---| | Compact snapshot | /ahtml/ | application/ahtml+text | LLM agents (Claude, GPT, Gemini) — default | | Canonical JSON | /ahtml/?fmt=json | application/ahtml+json | Programmatic clients, signing | | Markdown view | /ahtml/ + Accept: text/markdown | text/markdown | curl / LLM clients (v0.9.4) | | Streaming snapshot | /ahtml/?stream=1 | application/ahtml+json-seq (NDJSON) | Long pages, progressive ingestion | | Incremental diff | /ahtml/?since= | application/ahtml-diff+json | Crawlers, cache layers | | MCP manifest | /ahtml/mcp.json | MCP 2025-11-25 | Cursor, ChatGPT, Claude Desktop, Copilot | | OpenAPI spec | /ahtml/openapi.json | OpenAPI 3.1 + x-ahtml-* | REST clients, codegen, agent runtimes | | Discovery manifest | /.well-known/ahtml.json | JSON | Any AHTML-aware agent | | llms.txt shim | /llms.txt | Markdown (+ Content Signals front-matter) | IDE agents (Cursor, Continue, Cline) | | RSL license | /rsl.txt (via toRsl) | RSL 1.0 | AI-licensing crawlers (v0.9.5) | | JSON-LD | inline in HTML | application/ld+json | Search engines + schema.org consumers | | Signed snapshot (v0.8) | header AHTML-Signature | Detached JWS over canonical JSON | Trust-sensitive agents | | Payment required (v0.9.5) | action execute_url | 402 + x-payment-required (x402/0.2) | Paying agents |
Every wire format is content-negotiated. All of them come from the same TypeScript object.
Why this exists — concrete numbers, not adjectives
| Concern | Today | With AHTML | |---|---|---| | Token cost on a typical product page | 4,269 tokens of HTML | 581 tokens compact (7.3× fewer) | | Production-bloat Shopify page | 200–500 KB of HTML | ~2 KB snapshot (50–100×) | | Answer accuracy on 20 fact-extraction questions (real LLM calls) | 91% on HTML | 100% on AHTML JSON | | MCP server | Separate process, parallel auth, parallel deploy | Your existing site emits MCP at /ahtml/mcp.json | | schema.org JSON-LD | Describes what something is | Plus typed cost, reversible, side_effects, confirmation | | llms.txt | Unstructured markdown — agents still guess | Auto-emitted as shim, plus typed action surface | | Crawler bandwidth | Full re-fetch every poll | ETag-conditional GET + ?since= diff endpoint | | Trust | "I scraped this 12 hours ago, was it tampered with?" | Detached JWS over canonical JSON (v0.8) | | Agent identity | Any bot can claim to be anyone | RFC 9421 signed requests → X-AHTML-Agent-Verified (v0.9.5) | | Priced actions | Agent can't tell what an action costs or how to pay | Typed cost.rails: ['x402'] + standards-compliant 402 flow (v0.9.5) | | Content licensing | Scrapers ignore terms | RSL 1.0 file + Content Signals declarations (v0.9.5) |
The token-only benchmark was measured with the same tokenizers OpenAI and Anthropic use internally (gpt-tokenizer, @anthropic-ai/tokenizer) — no text.length / 4 guessing. The accuracy benchmark issues real API calls across gpt-4o-mini, claude-haiku-4.5, gemini-2.5-flash, and llama-3.3-70b. See [benchmark-results-llm.md](benchmark-results-llm.md) and [examples/llm-benchmark/](examples/llm-benchmark/) to reproduce (~$0.10–0.50 in API spend), or run npx @ahtmljs/cli benchmark for a one-command table on any live page.
For the head-to-head "why AHTML wins" story — token savings plus capability proofs executed live (MCP tools emitted, a snapshot signed and verified, an x402 402 built, an RFC 9421 agent request verified) — see [WHY-AHTML.md](WHY-AHTML.md), regenerated by [examples/why-ahtml/](examples/why-ahtml/) (npm run benchmark:why).
Comparison
vs Firecrawl / ScrapingBee / Jina Reader / r.jina.ai / Spider / Browserbase / Diffbot / Cloudflare auto-markdown
These convert somebody else's HTML into LLM-friendly markdown by scraping it (Cloudflare now does it at the CDN with Accept: text/markdown). They are good tools. AHTML solves the inverse problem: let the site publish the agent-readable view itself, with typed actions, ETag, a signature, and a price. If you are the site owner, you should not need a third party to scrape your own pages — and AHTML also serves text/markdown when a client asks for it, so it's a superset, not a competitor.
vs Anthropic MCP SDK / OpenAI MCP SDK / FastMCP / mcp-framework / Smithery
These help you build an MCP server from scratch, as a separate process, with its own auth and deploy story. AHTML makes your existing Next.js, Vite, or Hono app emit MCP — same database, same auth, one deploy. The MCP tool manifest is generated from the same snapshot that already powers your agent-facing endpoint. And ahtml mcp turns any site — adopter or not — into MCP tools for your Claude/Cursor session today.
vs schema.org JSON-LD / llms.txt
| Capability | HTML | llms.txt | schema.org | AHTML | |---|:---:|:---:|:---:|:---:| | Typed entities | implicit | text only | yes | yes | | Typed actions | implicit | text only | no | yes | | Cost / reversibility | no | no | no | yes | | Side-effect declarations | no | no | no | yes | | Confirmation requirements | no | no | no | yes | | Freshness / TTL | no | no | no | yes | | Conditional fetch (ETag) | partial | no | no | yes | | Streaming | no | no | no | yes | | MCP-emittable | no | no | no | yes | | OpenAPI-emittable | no | no | no | yes | | Cryptographically signed | no | no | no | yes (v0.8) | | Verified-agent auth | no | no | no | yes (v0.9.5) | | Priced actions (x402) | no | no | no | yes (v0.9.5) |
AHTML ingests schema.org for a free Level-0 snapshot on most Shopify/WordPress sites, emits llms.txt as a compatibility shim, and adds the typed action surface that both lack.
vs LangChain CheerioWebBaseLoader / Mozilla Readability / trafilatura / Unstructured.io
Those are HTML cleaners — they strip chrome and return text. AHTML returns a structured object with stable IDs, typed actions, and freshness — so the LLM does not have to guess what the page is about. The [@ahtmljs/langchain](packages/langchain) loader is a drop-in replacement for CheerioWebBaseLoader when the upstream site emits AHTML.
A longer comparison — including WebMCP, NLWeb, RSL, x402, and Content Signals — is in [docs/compare.md](docs/compare.md).
Install in 3 minutes (Next.js App Router)
1. Install.
npm install @ahtmljs/next @ahtmljs/schema
2. Declare snapshots.
// lib/ahtml.ts
import { snapshot } from '@ahtmljs/schema';
export async function buildSnapshot(segments: string[], req: Request) {
if (segments[0] === 'products' && segments[1]) {
const p = await db.product.findUnique({ where: { slug: segments[1] } });
if (!p) return null;
return snapshot(req.url, 'product_detail')
.ttl(60)
.add({
id: `product:${p.slug}`,
type: 'product',
name: p.name,
price: { amount: p.price, currency: p.currency },
stock: { status: p.qty > 0 ? 'in_stock' : 'out_of_stock', quantity: p.qty },
})
.action({
id: 'purchase',
target: `product:${p.slug}`,
category: 'transact',
execute_url: '/api/checkout',
auth: 'required',
cost: { amount: p.price, currency: p.currency, category: 'purchase' },
reversible: { reversible: true, window: 'P30D', policy: 'full_refund' },
side_effects: ['charge_card', 'email_buyer', 'decrement_stock'],
confirmation: 'required',
})
.build();
}
ret
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [DibbayajyotiRoy](https://github.com/DibbayajyotiRoy)
- **Source:** [DibbayajyotiRoy/AHTML](https://github.com/DibbayajyotiRoy/AHTML)
- **License:** MIT
- **Homepage:** https://ahtmljs.vercel.app
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.