Agent-discovery metadata: Link headers, API catalog, content signals, llms.txt - #1039
Merged
Conversation
Make x402scan discoverable to AI agents via three standards-based mechanisms, directly addressing the isitagentready.com checks for link headers, API catalog, and content signals. - RFC 8288 Link header (next.config.ts): every page advertises the API catalog (rel="api-catalog") and the OpenAPI spec (rel="service-desc") so agents can bootstrap from any URL. - RFC 9727 API catalog at /.well-known/api-catalog (application/linkset+json, RFC 9264 link set): describes the /api/x402 API with service-desc (/openapi.json), service-doc (repo), and status (/api/health). Emits both the canonical relation-keyed members and a flat `links` mirror for scanner compatibility. - /api/health: dependency-free liveness endpoint used as the catalog's `status` target. - Content Signals in robots.txt: declares search=yes, ai-train=no, ai-input=yes. Converted from the robots.ts metadata convention to a route handler since that convention can't emit Content-Signal directives. tsconfig `include` gains an explicit entry for src/app/.well-known/** because TypeScript's `**/*.ts` glob skips leading-dot directories (keeps tsc + eslint covering the new route). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Curated Markdown index at /llms.txt following the llmstxt.org format: H1 name, summary blockquote, then H2 link sections (Explore, For agents and developers, Documentation, Optional). Links point at clean Markdown / machine-readable representations where they exist — the .md docs, the OpenAPI spec, and the RFC 9727 API catalog. Served via a route handler with env-driven absolute URLs so it resolves correctly on production and preview deploys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes x402scan discoverable to AI agents via standards-based mechanisms, directly addressing the isitagentready.com checks for link headers, API catalog, and content signals, plus a curated
/llms.txt. All are pure code changes scoped toapps/scan.1. RFC 8288
Linkresponse header (all pages)next.config.tsnow emits a site-wideLinkheader advertising discovery resources, so an agent landing on any URL can bootstrap:Next.js merges this with its own preload
Linkheaders as separate header lines (correct RFC 8288 multi-header behavior).2. RFC 9727 API catalog —
/.well-known/api-catalogNew route handler returning
application/linkset+json(an RFC 9264 link set) describing the existing/api/x402API:service-desc→/openapi.json(machine-readable OpenAPI)service-doc→ the GitHub repo (human docs)status→/api/healthEmits both the canonical relation-keyed members (RFC 9264 §4.2) and a flat
linksmirror for broad scanner compatibility.3.
/api/healthDependency-free liveness endpoint (no DB/network) used as the catalog's
statustarget.4. Content Signals in
robots.txtDeclares content-usage preferences for automated agents:
ai-input=yesbecause x402scan is an agent-facing explorer;ai-train=yesallows AI model training. These values are a site-owner policy decision — easy to change insrc/app/robots.txt/route.tsif you want a different stance.Converted from the
robots.tsmetadata convention to a route handler because that convention can't emitContent-Signaldirectives (existing sitemap reference preserved).5.
/llms.txtCurated Markdown map of the site following the llmstxt.org format: H1 name, summary blockquote, then H2 link sections (Explore / For agents and developers / Documentation / Optional). Links point at clean-Markdown or machine-readable representations where they exist — the
.mddocs, the OpenAPI spec, and the API catalog. Every referenced path was status-checked (no 404s).Notes
tsconfig.jsonincludegains an explicitsrc/app/.well-known/**/*.tsentry, because TypeScript's**/*.tsglob skips leading-dot directories (without it,eslint .fails to parse the api-catalog route). tsc + eslint now cover the file.NEXT_PUBLIC_APP_URL(→https://x402scan.comin prod, correct on preview deploys too).Deliberately not included (and why)
.mcpb); there's no HTTP MCP endpoint to advertise.SKILL.mdfiles to list.Accept: text/markdown) — genuinely useful but a larger, separate feature (needs per-route Markdown builders sourced from data, since the data pages render client-side)./llms.txtis the lightweight first step; the full version can follow.Verification
Ran locally against
next dev:GET /→ carries the discoveryLinkheaderGET /.well-known/api-catalog→200,Content-Type: application/linkset+json, valid linksetGET /robots.txt→200,Content-SignalpresentGET /api/health→200,{"status":"ok",...}GET /llms.txt→200,text/plain; all referenced URLs status-checked (no 404s)Prettier ✓, ESLint ✓ on all changed files. (The pre-existing Prisma schema-drift
tscerrors and homepage/openapi 500s in local dev are unrelated — they needdb:generate, which CI runs.)🤖 Generated with Claude Code