{"domain":"celesto.ai","url":"https://celesto.ai","urlKind":"domain","finalUrl":"https://celesto.ai/","score":65,"maxScore":100,"grade":"C","ctaMessage":"You've started but agents are leaving you on the table.","ctaTier":"mid","layers":[{"id":"discovery","name":"Discovery","description":"Can agents find and recommend you?","checks":[{"id":"ard-catalog","name":"ARD discovery","description":"One catalog that tells agents everything you offer them: MCP servers, APIs, agents, and skills. Without it, every agent has to hunt for your capabilities page by page. We look where ARD v0.91 tells agents to look: an Agentic Resource Discovery catalog at /.well-known/ard.json, or one your homepage points to with a <link rel=\"ard\"> tag (an HTTP Link header with rel=\"ard\" also counts). The predecessor /.well-known/ai-catalog.json and rel=\"ai-catalog\" still count, with a nudge to move. Entries published only through a robots.txt Agentmap directive or as JSON-LD on your homepage are noted without the point, since agents resolving your domain are not required to read them. Weighted at 1 point while ecosystem adoption is early (2026-08 audit; was 3).","status":"fail","score":0,"maxScore":1,"details":"No /.well-known/ard.json (and no legacy /.well-known/ai-catalog.json)","recommendation":"Publish an Agentic Resource Discovery catalog at /.well-known/ard.json so AI clients can discover your agentic resources (MCP servers, agents, skills, APIs). See https://agenticresourcediscovery.org/","bonus":false,"specUrl":"https://agenticresourcediscovery.org/","maturity":"verified","tier":"required","estScoreGain":2.2},{"id":"ai-catalog-published","name":"AI Catalog discovery","description":"The AI Catalog Standard (ai-catalog.io, Agent-Card WG) specifies its own discovery path, /.well-known/ai-catalog.json, separately from ARD's ard.json. Serving a valid catalog there keeps you discoverable by consumers that follow that spec. Bonus: earns credit when present, never costs points.","status":"na","score":0,"maxScore":1,"details":"No /.well-known/ai-catalog.json - the AI Catalog Standard's discovery path. Bonus only; a catalog at /.well-known/ard.json is scored by the ARD discovery check.","recommendation":"Serve a valid catalog at /.well-known/ai-catalog.json - the AI Catalog Standard's own discovery path - so consumers following that spec (see https://ai-catalog.io/) also find you. The same document you serve at /.well-known/ard.json works unchanged.","bonus":true,"specUrl":"https://ai-catalog.io/","maturity":"verified","tier":"recommended"},{"id":"ard-entries-valid","name":"ARD entry validity","description":"Each entry in your catalog is complete enough for an agent to actually use it: an identifier, a display name, a media type, and a working target. Validated against the AI Catalog Standard's entry model on the catalog the ARD discovery check found (ard.json, a rel=\"ard\" source, else the legacy ai-catalog.json). Only applies when the catalog exists; partial adoption earns credit and never costs points.","status":"na","score":0,"maxScore":2,"details":"No catalog at /.well-known/ard.json or /.well-known/ai-catalog.json - entry validity applies only to published catalogs","recommendation":"Make every catalog entry fully valid: a domain-anchored urn:air identifier, a displayName, a media type, and exactly one of url or data. Applies to the catalog at /.well-known/ard.json or the legacy /.well-known/ai-catalog.json.","bonus":true,"specUrl":"https://ai-catalog.io/","maturity":"verified","tier":"recommended"},{"id":"ard-trust-manifest","name":"ARD trust manifest","description":"Trust signals inside your catalog (verified identity, compliance attestations, signatures) that let cautious agents pick you over an unverified alternative. The trust model comes from the AI Catalog Standard and is validated on whichever path serves your catalog. Only applies when the catalog exists; never costs points.","status":"na","score":0,"maxScore":2,"details":"No catalog at /.well-known/ard.json or /.well-known/ai-catalog.json - trust metadata applies only to published catalogs","recommendation":"Add a trustManifest (verifiable identity, compliance attestations, or signature) to your catalog entries (ard.json, or the legacy ai-catalog.json) so clients can verify your resources with progressive trust.","bonus":true,"specUrl":"https://ai-catalog.io/","maturity":"verified","tier":"recommended"},{"id":"agentic-search-usecase","name":"Category share of voice","description":"When someone asks an AI for a tool that does what you do, do you come up? This measures your share of voice for the problem you solve, not just your name.","status":"na","score":0,"maxScore":6,"details":"Category share of voice is in beta. It measures whether agents surface you for capability and use-case searches (not just your name). We are tuning it for accuracy before it counts toward your score - coming soon as a Pro check.","recommendation":"Build topical authority for your category. Publish comparison pages, 'best X for Y' content, tutorials, and integration guides that rank for generic use-case queries - not just your brand name - so agents surface you when users describe a need.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"agentic-search-specific","name":"Developer resource discoverability","description":"Can an agent that knows your name find your developer resources by searching: API docs, OpenAPI spec, MCP server, auth docs, developer portal, SDK documentation? Any one recognized resource type earns full marks. Missing resources refer to this search sample, not proof that pages are unindexed. Weighted at 3 points while search-result categorisation is noisy (2026-08 audit; was 6, requiring 2 types).","status":"warning","score":1,"maxScore":3,"details":"Name search surfaced no pages on celesto.ai, although developer resources exist on the site (API docs, developer portal, auth docs, MCP server, SDK documentation) - weak search indexing or transient search noise","recommendation":"Check whether your developer resources (API docs, OpenAPI spec, auth docs, developer portal, MCP server, SDK documentation) surface in name-based searches. If they do not, use predictable URLs, link them in llms.txt, and include your product name in page titles and headings. This result reflects one search sample.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":4.4},{"id":"brand-search-accuracy","name":"Brand name discoverability","description":"When people search for your brand together with your main product, your domain should be in the top results. If it is not, agents cannot reliably tell you apart from lookalikes and resellers.","status":"pass","score":3,"maxScore":3,"details":"celesto.ai ranks #1 for \"Celesto AI sandbox environment\"","recommendation":"Make sure your own domain ranks in the top results when people search your brand together with your main product (for example \"Acme payments API\"). If it does not, your brand may be too generic, conflict with a more established term, or not yet indexed. Strengthen it by describing your main product clearly in your homepage title and headings, earning press mentions that link to your domain, and avoiding redirect chains that mask your main domain in search results.","bonus":false,"maturity":"verified","tier":"required","data":{"mode":"site_term","rank":1,"term":"sandbox environment","query":"Celesto AI sandbox environment","matchCount":3,"termSource":"picked","bareBrandReason":null}},{"id":"wikipedia-presence","name":"Wikipedia / Wikidata entity presence","description":"A Wikipedia article and Wikidata entry that link to your domain. Wikipedia is the largest single source of citations in AI answers (~48% of ChatGPT citations), so presence there decides whether AIs can verify who you are.","status":"fail","score":0,"maxScore":4,"details":"No Wikipedia article or Wikidata entity found for \"celesto\" - creating a Wikipedia page and a Wikidata item with P856 = celesto.ai is the highest-impact step for AI search citation coverage","recommendation":"Establish a Wikipedia article and a Wikidata entity for your brand, with the domain set as the official website (Wikidata property P856) and a corresponding external link on Wikipedia. Wikipedia is the largest single source of citations in ChatGPT and a primary input to Knowledge Graphs across Google, Bing, and LLM training data. Earn third-party press coverage first to satisfy notability, then draft the article with cited references rather than self-promotion.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":1.9},{"id":"robots-ai-policy-quality","name":"robots.txt AI crawler policy","description":"Whether your robots.txt lets the AI search crawlers (OAI-SearchBot, Claude-SearchBot, PerplexityBot) read your public pages, so AI search can find you. Blocking AI training crawlers such as GPTBot and ClaudeBot is your choice and never lowers this score.","status":"pass","score":2,"maxScore":2,"details":"Training: 12/12. Search: 18/18 page/crawler pairs permitted. No applicable crawl or usage restriction found for 5 training and search crawlers (gptbot, claudebot, oai-searchbot, claude-searchbot, perplexitybot) on 6 public pages: https://celesto.ai/, https://celesto.ai/become-design-partner, https://celesto.ai/events/2026/unicorn-ai-summit, https://celesto.ai/openclaw, https://celesto.ai/toolhub/e2b, https://celesto.ai/toolhub/linkedin_scraper. Declared policy only; absence of a Content Signal expresses no usage preference. Paths outside this sample, live bot access, indexing, and model training are not verified","recommendation":"For broad training and search readiness, permit GPTBot and ClaudeBot to collect the affected public pages for training, and OAI-SearchBot, Claude-SearchBot, and PerplexityBot to crawl them for search. Review the reported URLs, rule lines, and applicable ai-train or search Content Signals. Keep private and account paths restricted. General permissions already count; named directives and Content Signals are optional. The paired search=yes, ai-train=no retains full credit when all evaluated crawling and search are permitted. Other training restrictions mean partial coverage under this benchmark. Usage permission never overrides Disallow. Use the existing agent-user policy and live access results to assess visits.","bonus":false,"maturity":"verified","tier":"required","data":{"access":[{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/become-design-partner","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/become-design-partner","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/become-design-partner","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/become-design-partner","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/become-design-partner","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/events/2026/unicorn-ai-summit","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/events/2026/unicorn-ai-summit","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/events/2026/unicorn-ai-summit","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/events/2026/unicorn-ai-summit","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/events/2026/unicorn-ai-summit","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/openclaw","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/openclaw","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/openclaw","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/openclaw","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/openclaw","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/e2b","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/e2b","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/e2b","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/e2b","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/e2b","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/linkedin_scraper","line":14,"rule":"Allow: /","agent":"gptbot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/linkedin_scraper","line":14,"rule":"Allow: /","agent":"claudebot","access":"allowed","source":"wildcard","purpose":"training","permission":"permitted","usageSignal":"ai-train","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/linkedin_scraper","line":14,"rule":"Allow: /","agent":"oai-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/linkedin_scraper","line":14,"rule":"Allow: /","agent":"claude-searchbot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false},{"url":"https://celesto.ai/toolhub/linkedin_scraper","line":14,"rule":"Allow: /","agent":"perplexitybot","access":"allowed","source":"wildcard","purpose":"search","permission":"permitted","usageSignal":"search","ruleTruncated":false}],"coverage":{"search":{"evaluated":18,"permitted":18},"training":{"evaluated":12,"permitted":12}},"robotsUrl":"https://celesto.ai/robots.txt","usageRules":[],"evaluatedUrls":["https://celesto.ai/","https://celesto.ai/become-design-partner","https://celesto.ai/events/2026/unicorn-ai-summit","https://celesto.ai/openclaw","https://celesto.ai/toolhub/e2b","https://celesto.ai/toolhub/linkedin_scraper"],"contentSignals":[],"robotsFinalUrl":"https://celesto.ai/robots.txt","usageGroupCount":0,"robotsHttpStatus":200,"evaluatedCrawlers":["gptbot","claudebot","oai-searchbot","claude-searchbot","perplexitybot"],"contentSignalCount":0}},{"id":"mcp-registry-listed","name":"Listed in MCP registries","description":"Agents find MCP servers through registries the way people find apps through app stores. We check the major ones (Smithery, mcp.so) for an entry verified against your domain.","status":"na","score":0,"maxScore":1,"details":"No MCP server detected","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"npm-sdk-package","name":"NPM/PyPI SDK package","description":"An official SDK or CLI on NPM or PyPI gives agents and the developers steering them a ready-made way in, instead of hand-rolling every API call.","status":"pass","score":1,"maxScore":1,"details":"NPM package found: @celestoai/sdk - \"Celesto SDK — managed agents, Gatekeeper, and Computers clients for Node.js\"","recommendation":"Publish a JavaScript/TypeScript SDK package on npm so developers can integrate your API programmatically. In package.json set `repository` to your source repo and `homepage` to your product domain - these links are how agents confirm the package is your official SDK rather than a third-party tool with a similar name.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"agent-rules-repo","name":"Agent platform configs","description":"Published rules or config files for AI coding tools (Claude, Cursor, Windsurf). They teach coding agents to use your product correctly from the first prompt.","status":"pass","score":1,"maxScore":1,"details":"Agent config found: github.com/celestoai/celesto/blob/main/AGENTS.md","recommendation":"Add an AGENTS.md or .cursorrules file to your public GitHub repo with instructions for how AI coding agents should interact with your codebase. Then make sure the repo is documented in the entry-point pages agents read - homepage, docs, and llms.txt - so it can be discovered without guessing.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"agent-plugins-repo","name":"Agent Plugins manifest","description":"An Agent Plugins manifest (plugin.json) in your public GitHub repos, bundling skills and MCP servers into one installable package. An emerging format, so it never costs points.","status":"fail","score":0,"maxScore":1,"details":"No Agent Plugins manifest (plugin.json) found in discovered repos","recommendation":"Bundle your agent skills and MCP servers as an Agent Plugin: add a plugin.json manifest with the agent-plugins.org $schema and a name. See https://agent-plugins.org/specification","bonus":true,"specUrl":"https://agent-plugins.org/specification","draft":true,"maturity":"emerging","tier":"emerging"},{"id":"registry-branding","name":"Registry branding","description":"Your MCP registry entry has a display name, icon, and description. Agents choosing between servers see this first; a bare entry looks abandoned.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","recommendation":"Give your MCP server-card (at /.well-known/mcp/server-card.json) a display name, an icon or logo, and a description - all three together are what reads as a complete, branded listing agents can present.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"chatgpt-app-listed","name":"ChatGPT app listed","description":"Listed in the ChatGPT app directory, where hundreds of millions of users can pull your product into a conversation by name. Upside-only: the directory is curated and gated, so absence never costs points.","status":"fail","score":0,"maxScore":2,"details":"Not found in ChatGPT app directory","recommendation":"Submit your app to the ChatGPT apps / connectors directory (the apps-in-ChatGPT surface) so ChatGPT users can discover and use your product.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":1.1}],"score":7,"maxScore":10},{"id":"accessibility","name":"Access","description":"Can agents access your data and understand you?","checks":[{"id":"sitemap","name":"Sitemap exists","description":"A map of every page you want found. Agents use your XML sitemap to discover content without crawling blind, so gaps here mean pages that never get read.","status":"pass","score":2,"maxScore":2,"details":"Valid sitemap found at https://celesto.ai/sitemap.xml with 27 entries","recommendation":"Add a valid XML sitemap at /sitemap.xml listing all indexable URLs. Include lastmod dates and keep it under 50MB.","bonus":false,"maturity":"verified","tier":"required"},{"id":"content-no-js","name":"Content without JavaScript","description":"Most AI crawlers never run JavaScript. If your pages need it to show content, agents see a blank site. We fetch your pages with JavaScript off and check the content is still there.","status":"warning","score":2,"maxScore":3,"details":"7564 chars with H1, but 4.5% content ratio is below the 5% target","recommendation":"Serve at least 500 characters of meaningful homepage content in raw HTML. Add a clear H1, keep deeper heading levels sequential, and remove excessive non-content markup.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":0.5},{"id":"bot-detection","name":"Not blocked by bot detection","description":"Your bot protection may be turning away the visitors you want. We check whether AI agents can reach your site without being blocked.","status":"pass","score":2,"maxScore":2,"details":"Site accessible to 6 AI agent user-agents","recommendation":"Allowlist known AI agent User-Agents (ChatGPT-User, ClaudeBot, Google-Extended, DeepSeekBot) in your WAF or bot-detection rules.","bonus":false,"maturity":"verified","tier":"required"},{"id":"agent-discovery-file","name":"Agent discovery file","description":"A dedicated endpoint that tells arriving agents what you are and where to start, like a front desk for automated visitors.","status":"fail","score":0,"maxScore":2,"details":"No agent discovery file found","recommendation":"Publish an Agent Skills index at /.well-known/agent-skills/index.json that lists your capabilities, with each skill carrying a name and a description so agents can find and parse what you offer.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":1.1},{"id":"agent-skills-index-v2","name":"Agent Skills index conformance (v0.2.0)","description":"Your published agent skills follow the current discovery spec, so tools can verify and install them safely. We check /.well-known/agent-skills/index.json for the v0.2.0 schema and typed entries, then verify one artifact digest (SKILL.md or archive).","status":"na","score":0,"maxScore":2,"details":"No /.well-known/agent-skills/index.json - skip v0.2.0 conformance","recommendation":"Upgrade /.well-known/agent-skills/index.json to the v0.2.0 schema: add \"$schema\": \"https://schemas.agentskills.io/discovery/0.2.0/schema.json\", and give every entry a type (skill-md or archive), url, and digest. Use \"digest\": \"sha256:<64 lowercase hex chars>\" (e.g. \"digest\": \"sha256:a3f1...\") - a bare \"sha256\": \"<hex>\" field is also accepted. Compute the value from the artifact's raw bytes. For archives, hash the ZIP or tar.gz download itself; a separate skill-md entry is not required.","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"a2a-agent-card","name":"A2A / agent-card","description":"A business card for agent-to-agent contact: who you are, what you can do, and how to reach you, published at /.well-known/agent-card.json (the A2A protocol).","status":"fail","score":0,"maxScore":2,"details":"No A2A agent card found at /.well-known/agent-card.json","recommendation":"Publish an Agent-to-Agent (A2A) agent card at /.well-known/agent-card.json describing your agent's capabilities, skills, and contact endpoint.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":0.3},{"id":"skills-sh-listed","name":"Listed on skills.sh","description":"Official skills published on skills.sh, the public directory where agents and developers browse for ready-made capabilities.","status":"fail","score":0,"maxScore":1,"details":"No official skills self-published on skills.sh (86 community skills with potential relation to this domain found, but only self-published official skills count)","recommendation":"Publish agent skills on skills.sh so AI agents can discover your product's capabilities. Create a SKILL.md in your GitHub repo and register it with 'npx skills add'. See skills.sh/docs.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"pricing-md","name":"pricing.md exists","description":"An agent comparing options needs your prices in a form it can read. We check for a machine-readable pricing file at /pricing.md.","status":"fail","score":0,"maxScore":2,"details":"No pricing.md found - agents need machine-readable pricing to compare products and make purchase recommendations","recommendation":"Create a /pricing.md file with your pricing tiers, features, and limits in plain markdown. This lets AI agents compare costs and recommend plans without scraping HTML pricing pages.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"nlweb-schema-feeds","name":"NLWeb Schema Feeds","description":"A schemamap directive in robots.txt pointing at structured data feeds (NLWeb). It hands agents your catalog as data instead of making them scrape pages.","status":"fail","score":0,"maxScore":1,"details":"No schemamap: directive in robots.txt","recommendation":"Add a schemamap: directive to robots.txt pointing to a Schema Map XML file listing your structured data feeds (JSONL/RSS). See the NLWeb Schema Feeds spec.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"mcp-well-known-discovery","name":"MCP well-known discovery","description":"Publishing an MCP server is not enough; agents have to find it. We look where MCP clients look (a server card on your own domain listed in /.well-known/ai-catalog.json, the same catalog ARD crawlers read at /.well-known/ard.json, or a card served at <server URL>/server-card) and where sites also announce a server: /.well-known/mcp/server-card.json, a /.well-known/mcp.json manifest, llms.txt, or a /.well-known/mcp redirect to a working server, conventions no MCP spec defines.","status":"pass","score":2,"maxScore":2,"details":"MCP server referenced in llms.txt","recommendation":"Serve your MCP server at /.well-known/mcp, publish a server-card.json at /.well-known/mcp/server-card.json, or reference it in llms.txt so agents can discover it automatically without manual URL input.","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"agent-mode-view","name":"Agent mode view","description":"A stripped-down, structured view of your site at ?mode=agent, built for machine readers: plain content and direct endpoint links.","status":"fail","score":0,"maxScore":2,"details":"?mode=agent returns same content as homepage (no dedicated agent view)","recommendation":"Add a ?mode=agent query parameter to your homepage that returns a structured, machine-readable view with API endpoints, authentication info, and key capabilities instead of marketing HTML.","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"link-headers-discovery","name":"HTTP Link headers (RFC 8288)","description":"HTTP Link headers that point agents at your sitemap and service docs before they parse a single page, making every automated visit faster.","status":"fail","score":0,"maxScore":1,"details":"No HTTP Link response headers (RFC 8288) found","recommendation":"Add HTTP Link: response headers (RFC 8288) advertising your sitemap, markdown alternates, API service descriptions, and API catalog. Example: Link: </sitemap.xml>; rel=\"sitemap\", </index.md>; rel=\"alternate\"; type=\"text/markdown\".","bonus":true,"maturity":"verified","tier":"required","estScoreGain":0.1},{"id":"markdown-url-fallback","name":"Markdown URL fallback","description":"Append .md to a page URL and get the markdown version: the cleanest possible read for an agent. Homepage /index.md is the baseline; .md twins on content pages earn full credit.","status":"fail","score":0,"maxScore":2,"details":"Homepage does not support the .md suffix. Probed https://celesto.ai/index.md and it did not return markdown (expected text/markdown content-type or a heading-led non-HTML body). Serve /index.md so agents can fetch one canonical markdown URL for the site root.","recommendation":"Let agents fetch markdown by appending .md to page URLs. Required for any credit: serve a markdown homepage at /index.md. For full credit (2/2): also serve a .md twin for each content page (e.g. /docs/auth -> /docs/auth.md). Content-Type should be text/markdown and the body should start with a top-level heading (not HTML).","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"modular-llms-txt","name":"Modular llms.txt per product area","description":"Per-section llms.txt files (like /docs/llms.txt) so an agent working in one area gets a focused index instead of your whole site.","status":"warning","score":0,"maxScore":1,"details":"Only 1 section-level llms.txt found (docs) - add at least one more (/docs/llms.txt, /api/llms.txt) to earn bonus credit","recommendation":"Add per-section llms.txt files (e.g. /docs/llms.txt, /api/llms.txt, /developers/llms.txt) so agents can fetch scoped context for specific product areas instead of the whole manual.","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"sitemap-lastmod","name":"Sitemap freshness (lastmod)","description":"Dates in your sitemap tell agents what changed and when, so they reread fresh pages instead of guessing. We check lastmod dates parse and the newest is recent.","status":"pass","score":1,"maxScore":1,"details":"100% of 27 sampled sitemap entries carry lastmod; newest is 5 day(s) old","recommendation":"Add <lastmod> dates (W3C datetime, e.g. 2026-08-01) to your sitemap entries and update them when content actually changes. Aim for lastmod on at least half your entries with the newest within the last year. Verify with `curl https://yourdomain.com/sitemap.xml | grep lastmod`.","bonus":true,"specUrl":"https://www.sitemaps.org/protocol.html","maturity":"verified","tier":"recommended"},{"id":"robots-agent-user-policy","name":"robots.txt agent-user policy","description":"Declared homepage permission for ChatGPT-User, Claude-User, and Perplexity-User. General rules and permission by default count. Actual fetch behavior depends on the vendor; unverifiable policies are N/A.","status":"pass","score":2,"maxScore":2,"details":"No applicable crawl or usage restriction found for 3 user-triggered agents (chatgpt-user, claude-user, perplexity-user) on 1 public page: https://celesto.ai/. Declared policy only; absence of a Content Signal expresses no usage preference. Paths outside this sample, live bot access, indexing, and model training are not verified","recommendation":"Review the matched homepage rules for ChatGPT-User, Claude-User, and Perplexity-User. If you intend to permit these requests, remove or narrow the reported restriction while keeping private paths protected. Review applicable ai-input=no declarations if answer-time use is intended. This check reports declared permission; a robots.txt change alone does not establish live access.","bonus":false,"maturity":"verified","tier":"required","data":{"access":[{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"chatgpt-user","access":"allowed","source":"wildcard","purpose":"user","permission":"permitted","usageSignal":"ai-input","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"claude-user","access":"allowed","source":"wildcard","purpose":"user","permission":"permitted","usageSignal":"ai-input","ruleTruncated":false},{"url":"https://celesto.ai/","line":14,"rule":"Allow: /","agent":"perplexity-user","access":"allowed","source":"wildcard","purpose":"user","permission":"permitted","usageSignal":"ai-input","ruleTruncated":false}],"coverage":{"user":{"evaluated":3,"permitted":3}},"robotsUrl":"https://celesto.ai/robots.txt","usageRules":[],"evaluatedUrls":["https://celesto.ai/"],"contentSignals":[],"robotsFinalUrl":"https://celesto.ai/robots.txt","usageGroupCount":0,"robotsHttpStatus":200,"evaluatedCrawlers":["chatgpt-user","claude-user","perplexity-user"],"contentSignalCount":0}},{"id":"llms-txt-exists","name":"llms.txt exists","description":"llms.txt is your site's guide for AI readers: what you do and where the important pages are. We check for /llms.txt or /.well-known/llms.txt.","status":"pass","score":1,"maxScore":1,"details":"Found the llms.txt at https://celesto.ai/llms.txt.","recommendation":"Create an llms.txt file at your domain root (/llms.txt) - the AI equivalent of robots.txt. Write at least 100 characters of real content: what your product is, what it does, and links to your key docs. Then verify it with `curl https://yourdomain.com/llms.txt` - you should see your text, not HTML. If your app returns its homepage for every URL (common with single-page apps), add a static file route so the raw text is served. A placeholder with just a heading earns no credit.","bonus":false,"maturity":"verified","tier":"required"},{"id":"llms-txt-formatting","name":"llms.txt formatting","description":"An llms.txt only helps if agents can parse it. We check the format: a heading up top, markdown links, and enough substance to navigate by.","status":"warning","score":1,"maxScore":2,"details":"The llms.txt is well-formatted with markdown links, but at 33,753 characters it exceeds the 30,000-character recommendation for a navigation index.","recommendation":"Format your llms.txt as a navigation index: start with a markdown heading, include markdown links to deeper resources, and keep it under 30,000 characters. If you have more to say, move long-form content into /llms-full.txt or per-section files (e.g. /docs/llms.txt, /api/llms.txt) and link to them from the main index.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":0.5},{"id":"json-ld","name":"JSON-LD structured data","description":"Structured data that states in machine terms what you are: a product, a company, a person. Without it, every AI describing you is guessing from prose. We grade the completeness of your homepage JSON-LD.","status":"pass","score":4,"maxScore":4,"details":"Rich JSON-LD identity: Organization with name, description, url, and sameAs/logo/address (1 block(s))","recommendation":"Add JSON-LD structured data to your homepage using the identity type that matches your site - SoftwareApplication for products, Organization or LocalBusiness for companies, Person for personal sites, Article for blogs - with name, description, url, and type-appropriate fields (offers, sameAs, author) so AI can parse your identity programmatically.","bonus":false,"maturity":"verified","tier":"required"},{"id":"pricing-info","name":"Pricing info accessible","description":"If an agent cannot find your prices, it cannot recommend you for a purchase. We check that pricing is discoverable and readable on your site.","status":"pass","score":3,"maxScore":3,"details":"Pricing page found at /pricing","recommendation":"Make pricing discoverable - add a /pricing page or include pricing as schema.org/Offer structured data, so agents can find it without scraping a marketing page.","bonus":false,"maturity":"verified","tier":"required"},{"id":"public-api-docs","name":"Public API/docs linked from homepage","description":"Your API docs, linked straight from your homepage. If an agent has to search for your documentation, most will not. Only docs you own count.","status":"pass","score":3,"maxScore":3,"details":"Documentation site found at https://celesto.ai","recommendation":"Publish API documentation at a discoverable URL (/docs, /api, /developers). Include authentication, endpoints, and example requests.","bonus":false,"maturity":"verified","tier":"required"},{"id":"agent-instruction","name":"Agent instruction / when-to-use","description":"Explicit guidance on when to use your product, written where agents will read it. An agent choosing between ten tools picks the one that says what it is for.","status":"fail","score":0,"maxScore":3,"details":"No agent instruction file with when-to-use guidance found","recommendation":"Tell agents when to reach for you: add a 'when to use this' section to your llms.txt (or a dedicated agent-instructions file) that names your best-fit use cases and how an agent should call you. Be specific about the jobs you are right for - generic marketing copy does not read as guidance.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":1.6},{"id":"skills-sh-quality","name":"Skills.sh skill quality","description":"Not just listed on skills.sh, but worth installing: multiple skills, descriptive names, and real adoption.","status":"fail","score":0,"maxScore":2,"details":"No official skills on skills.sh to evaluate","recommendation":"Expand your skills.sh presence with multiple skill repos covering different use cases. Add descriptive skill names, clear SKILL.md files, and organize by capability area.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"json-ld-entity-linking","name":"JSON-LD entity linking (sameAs)","description":"sameAs links from your structured data to your official profiles (GitHub, LinkedIn, app stores). They let AIs confirm that every mention of you is actually you.","status":"pass","score":2,"maxScore":2,"details":"Strong entity linking via sameAs: github.com, linkedin.com","recommendation":"Add sameAs links in your JSON-LD structured data pointing to your Wikipedia page, Wikidata entry, GitHub org, and social profiles. This helps AI disambiguate your brand from similarly named entities.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"metadata-completeness","name":"Metadata completeness","description":"The basics AIs use to identify a page: canonical URL, language, and Open Graph image and type. Missing pieces mean mangled citations and wrong previews.","status":"pass","score":2,"maxScore":2,"details":"All metadata signals present: canonical URL, lang=\"en\", og:image, og:type","recommendation":"Add all four signals to your homepage: <link rel=\"canonical\">, <html lang=\"...\">, <meta property=\"og:image\">, and <meta property=\"og:type\">. Agents use these for entity resolution and attribution.","bonus":false,"maturity":"verified","tier":"required"},{"id":"org-schema-completeness","name":"Organization schema completeness","description":"Company details (contact, address) in your structured data. AIs use them to verify you are a real business before recommending you.","status":"warning","score":1,"maxScore":2,"details":"Organization schema found but missing: contactPoint, address","recommendation":"Add Organization JSON-LD that includes both contactPoint (with email/phone and contactType) and address (PostalAddress). This lets AI verify your business legitimacy and answer contact queries.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":0.5},{"id":"schema-type-breadth","name":"Schema type breadth","description":"The more kinds of content you mark up with schema.org (FAQs, reviews, services, events, videos), the more kinds of questions an AI can answer about you with confidence.","status":"fail","score":0,"maxScore":2,"details":"No extended schema types found - AI can only answer basic questions about this entity","recommendation":"Expand your JSON-LD beyond Organization/WebSite. Add FAQPage for common questions, Service or Product for offerings, AggregateRating or Review for social proof, and BreadcrumbList for navigation context.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":1.1},{"id":"trust-anchors","name":"Trust anchor pages","description":"About, contact, and privacy pages with real content. Agents check these to verify you are legitimate before recommending you, the way a careful person would.","status":"pass","score":2,"maxScore":2,"details":"All trust anchor pages verified: About, Contact, Privacy","recommendation":"Publish real /about, /contact, and /privacy pages with at least 500 characters of content each. These are the pages AI agents check to verify your business is legitimate before recommending you.","bonus":false,"maturity":"verified","tier":"required"},{"id":"llms-txt-links-resolve","name":"llms.txt links resolve","description":"The markdown links an llms.txt declares actually resolve - broken links strand agents that follow the index","status":"pass","score":2,"maxScore":2,"details":"All 5 probed llms.txt links resolve to real content","recommendation":"Make every link your llms.txt declares resolve to real content. Verify each one with `curl -L <url>` - you should see the linked document, not your homepage. If your app returns the homepage shell for unknown paths (common with single-page apps), a 200 status is not proof: check the body. Fix or remove any dead link; agents that follow the index treat a broken link as a dead end.","bonus":false,"specUrl":"https://llmstxt.org","maturity":"verified","tier":"recommended"},{"id":"markdown-link-alternate","name":"Markdown alternate link","description":"Pages advertise their markdown twin via a rel=alternate link or HTTP Link header, and the advertised target really serves markdown.","status":"fail","score":0,"maxScore":1,"details":"No sampled page advertises a markdown alternate. Add <link rel=\"alternate\" type=\"text/markdown\" href=\"...\"> (or the equivalent Link response header) pointing at a markdown twin of the page.","recommendation":"Advertise a markdown twin of each page with <link rel=\"alternate\" type=\"text/markdown\" href=\"...\"> in the HTML head (or an equivalent Link response header), and make sure the advertised URL actually serves markdown - an advertisement pointing at HTML is worse than none. Verify the target with `curl -s <href>` and check the body starts with a heading, not <!doctype html>.","bonus":true,"specUrl":"https://www.rfc-editor.org/rfc/rfc8288","maturity":"emerging","tier":"emerging"},{"id":"markdown-frontmatter","name":"Markdown frontmatter metadata","description":"Served markdown docs open with a frontmatter block (title plus description / canonical / last-updated) so agents get document metadata without scraping","status":"na","score":0,"maxScore":1,"details":"No served markdown found (no root .md docs, no Accept: text/markdown negotiation) - nothing to carry frontmatter","recommendation":"Open your served markdown docs with a --- frontmatter block carrying title plus at least one of description, canonical, or last-updated. Agents read frontmatter as document metadata without scraping. A Link: rel=\"canonical\" response header also satisfies the canonical slot.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"redirect-hygiene","name":"Redirect hygiene","description":"Pages reach real content without meta-refresh stubs, JavaScript-only redirects, or cross-domain hops that strand non-JS agents","status":"pass","score":1,"maxScore":1,"details":"No meta-refresh stubs, JavaScript-redirect stubs, or cross-domain hops across 6 checked pages","recommendation":"Replace meta-refresh and JavaScript-only redirects with real HTTP 301/302 redirects. Non-JS agents never execute `location.href` or wait for a meta refresh - they see only the stub page. Verify with `curl -sI <url>` - you should see a Location header, not a 200 with a near-empty body.","bonus":false,"specUrl":"https://www.rfc-editor.org/rfc/rfc9110#name-redirection-3xx","maturity":"verified","tier":"recommended"},{"id":"page-token-budget","name":"Page token budget","description":"Individual pages keep extracted text within an agent-readable budget (~25K tokens) so they fit a context window without truncation","status":"pass","score":1,"maxScore":1,"details":"All 6 measured pages fit an agent context budget (largest ~2K tokens)","recommendation":"Keep each page's extracted text under ~100K characters (~25K tokens) so it fits an agent's context window without truncation. Split oversized reference pages into focused per-topic documents and link them from an index. Check a page with `curl -s <url> | wc -c` and remember agents read the extracted text, not the raw HTML.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"code-fence-validity","name":"Code fence validity","description":"Fenced code blocks in served markdown are balanced - an unclosed fence swallows the rest of the document when an agent parses it","status":"pass","score":1,"maxScore":1,"details":"Code fences balanced across 1 markdown document","recommendation":"Close every fenced code block (``` or ~~~) in your served markdown. CommonMark treats everything after an unclosed fence as code, so an agent parsing the document silently loses the rest of it. Count fence lines per file - the total must be even.","bonus":false,"specUrl":"https://spec.commonmark.org/0.31.2/#fenced-code-blocks","maturity":"emerging","tier":"emerging"},{"id":"docs-auth-gate","name":"Content behind auth","description":"Sampled content pages are publicly readable - pages behind a login wall are invisible to agents","status":"pass","score":2,"maxScore":2,"details":"All 5 sampled pages are publicly readable (4 with substantive content)","recommendation":"Serve your content pages without a login wall. Agents cannot complete auth flows while browsing - a 401/403 or a login-form page is invisible content. Keep public documentation public; if some content must stay gated, publish an ungated summary so agents can still represent it.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"openapi-spec","name":"OpenAPI spec published","description":"An OpenAPI spec is your API in a form machines can read. Agents use it to integrate without a human studying the docs, so it is one of the highest-leverage files you can publish.","status":"fail","score":0,"maxScore":7,"details":"No OpenAPI/Swagger specification found","recommendation":"Publish an OpenAPI (Swagger) specification at /openapi.json or /api/openapi.yaml. This is how agents understand your API surface automatically.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":3.8},{"id":"developer-portal","name":"Developer portal","description":"A place to sign up, get keys, and manage an integration without emailing anyone. Self-serve is the difference between integrating today and never.","status":"pass","score":6,"maxScore":6,"details":"Developer portal found at /docs","recommendation":"Create a developer portal at /developers with API keys, documentation, quickstart guides, and a sandbox environment.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"api-catalog-rfc9727","name":"API catalog (RFC 9727)","description":"A machine-readable list of all your APIs at /.well-known/api-catalog (RFC 9727), so agents see your full surface in one request.","status":"fail","score":0,"maxScore":2,"details":"No /.well-known/api-catalog found (RFC 9727)","recommendation":"Publish an API catalog at /.well-known/api-catalog per RFC 9727. Serve it with Content-Type: application/linkset+json;profile=\"https://www.rfc-editor.org/info/rfc9727\" and include a 'linkset' array with item entries pointing to your OpenAPI specs and service descriptions.","bonus":true,"maturity":"verified","tier":"required","estScoreGain":0.3},{"id":"markdown-negotiation","name":"Markdown agent docs","description":"Agents prefer markdown: the same content at a fraction of the noise. We check whether your docs are available as markdown, via content negotiation or .md routes.","status":"fail","score":0,"maxScore":1,"details":"Missing markdown content negotiation. Homepage returned text/html when probed with Accept: text/markdown (expected text/markdown), and none of the well-known root paths (/llms.md, /auth.md, /agents.md, /developers.md, /api.md, /index.md, /skill.md, /agent.md, /developer.md) returned markdown. Cold-arrival agents that land on the homepage from web search cannot get a markdown representation - serve text/markdown on the homepage via Accept negotiation, or publish a static /llms.md at the root.","recommendation":"Pick one: (a) return Content-Type: text/markdown on GET <homepage> when the request sends Accept: text/markdown, or (b) publish a static /llms.md, /auth.md, or /agents.md file at your root with real markdown content. Option (b) is usually a single static file. This is the cold-discovery path for agents that land at your homepage from web search without reading llms.txt first.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"markdown-negotiation-vary","name":"Markdown content negotiation (acceptmarkdown.com)","description":"The homepage serves Markdown when requested and HTML for browsers, with Vary: Accept on the Markdown response. Markdown support on a docs page alone does not satisfy this homepage check.","status":"fail","score":0,"maxScore":1,"details":"Homepage https://celesto.ai does not meet the Markdown negotiation requirements: Accept: text/markdown returned text/html; charset=utf-8; Vary header missing Accept (got \"none\")","recommendation":"Enable Markdown negotiation on the scanned homepage. Supporting it only on /docs or a separate .md URL does not satisfy this check. Requests with Accept: text/markdown must receive a nonempty Markdown body with Content-Type: text/markdown and Vary: Accept. Keep serving HTML for Accept: text/html. Adding Vary alone does not create a Markdown response. Verify both with `curl -sS -L -i -H 'Accept: text/markdown' https://yourdomain.com/` and `curl -sS -L -i -H 'Accept: text/html' https://yourdomain.com/`. Check the final response headers and body: Markdown with Vary: Accept for the first request, HTML for the second.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":0.1},{"id":"agent-ua-markdown","name":"Bot-UA markdown serving","description":"You recognize AI bots by their user-agent and serve them markdown even when they ask for HTML. Proactive courtesy for machine readers.","status":"fail","score":0,"maxScore":1,"details":"No probed bot User-Agent (GPTBot, ClaudeBot, ChatGPT-User, PerplexityBot, Google-Extended, Applebot-Extended, ora-agent, DeepSeekBot) receives markdown when requesting HTML. Optional: detect AI-bot UAs server-side and serve them a markdown representation directly.","recommendation":"Optionally detect AI-bot User-Agents (GPTBot, ClaudeBot, PerplexityBot) server-side and serve them a markdown representation of the page directly, even when they send Accept: text/html. Verify with `curl -A \"ClaudeBot/1.0\" https://yourdomain.com/` - a markdown body earns this bonus. Accept-header negotiation is scored separately.","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"agent-crawler-reachability","name":"Agent crawler reachability","description":"Whether the homepage is reachable to the agents that act for users and search (ChatGPT-User, OAI-SearchBot, Claude-User, PerplexityBot). A site that blocks these agents is invisible to them from step one.","status":"pass","score":2,"maxScore":2,"details":"Reachable to all major AI crawlers - ChatGPT-User: reachable, ClaudeBot: reachable, Google-Extended: reachable, ora-agent: reachable, DeepSeekBot: reachable","recommendation":"Allowlist the major AI crawler/agent User-Agents (ChatGPT-User, ClaudeBot, Google-Extended, ora-agent, DeepSeekBot) in your WAF, bot-detection rules, and robots.txt so agents can reach your homepage.","bonus":false,"maturity":"verified","tier":"recommended"}],"score":44,"maxScore":61},{"id":"usability","name":"Usability","description":"Can agents use you?","checks":[{"id":"mcp-tool-descriptions","name":"MCP tool descriptions","description":"An agent picks tools by reading their descriptions: vague ones get skipped, clear ones get called. We grade every tool on your MCP server, with different bars for product and docs servers.","status":"na","score":0,"maxScore":3,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-param-schemas","name":"MCP parameter schemas","description":"Typed parameter schemas on your MCP tools, so agents know what to send without trial and error. Product servers need required-field lists; docs servers need at least a query.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-server-identity","name":"MCP server identity","description":"Your MCP server introduces itself in the handshake: name, version, and usage instructions. An anonymous server makes every agent guess what it connected to.","status":"na","score":0,"maxScore":1,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-tool-listing","name":"MCP tool listing","description":"Your MCP server actually returns tools when asked. We call tools/list and grade the surface: product servers earn on breadth, docs servers on focus.","status":"na","score":0,"maxScore":3,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-tool-naming","name":"MCP tool naming","description":"Predictable tool names (create_invoice, search_docs) that agents parse at a glance. Inconsistent naming makes every call a small research project.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"public-api","name":"Public API with reachable endpoints","description":"The foundation of agent access: an API that agents can actually call. We check for documentation and at least one endpoint that responds.","status":"pass","score":7,"maxScore":7,"details":"REST API documentation found at https://celesto.ai/docs/index.md. Best-of-protocols score: 7/7.","recommendation":"Expose a public REST or GraphQL API. AI agents need programmatic access  - not just a web UI  - to integrate with your product.","bonus":false,"maturity":"verified","tier":"required"},{"id":"oauth-support","name":"OAuth 2.0 support","description":"Agents need a standard way to sign in. We check for OAuth 2.0, or an explicitly open API that needs no keys at all.","status":"fail","score":0,"maxScore":5,"details":"No OAuth 2.0 or OpenID Connect support detected","recommendation":"Implement OAuth 2.0 for API authentication. Publish your authorization server metadata at /.well-known/oauth-authorization-server.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":4},{"id":"scoped-permissions","name":"Scoped permissions","description":"Granular permissions so an agent gets only the access it needs, nothing more. Businesses connect faster when the blast radius of a mistake is small. We look for declared OAuth scopes (OpenAPI security schemes, RFC 9728 metadata), not prose mentions.","status":"warning","score":2,"maxScore":5,"details":"Scoped permissions described at https://celesto.ai/docs/llms.txt, but no machine-readable scope declaration found (OpenAPI oauth2 scopes or RFC 9728 scopes_supported)","recommendation":"Declare scoped API permissions where machines can read them: named OAuth scopes in your OpenAPI security schemes, or scopes_supported in RFC 9728 protected-resource metadata. Prose descriptions of roles help humans, but agents need the machine-readable declaration to request least-privilege access.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":2.4},{"id":"mcp-auth-mechanism","name":"MCP auth mechanism","description":"The right lock on the right door: docs servers should be public, product servers should require OAuth. We check your MCP auth matches what the server does.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-oauth-metadata","name":"MCP OAuth metadata","description":"Standard OAuth metadata (RFC 8414) that lets agents discover your sign-in flow automatically, instead of a developer wiring it by hand.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-pkce-s256","name":"MCP PKCE S256 support","description":"PKCE with S256, the OAuth hardening that stops intercepted codes from being replayed. Table stakes for agent auth done right.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"onboarding-friction","name":"Agent onboarding friction","description":"Can an agent go from discovering you to a first successful API call with no human in the loop? Every manual step is a place automated integrations quietly die.","status":"warning","score":1,"maxScore":2,"details":"Onboarding signals described but not verified live: free tier available, self-serve key generation, sandbox/test environment","recommendation":"Offer a free tier or trial, self-serve API key generation, and a sandbox environment. Agents can't fill out 'contact sales' forms.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":0.8},{"id":"web-bot-auth-directory","name":"Web Bot Auth directory","description":"A public key directory (RFC 9421) that lets agents cryptographically sign their requests, so you know exactly who is calling and can let the good ones through.","status":"fail","score":0,"maxScore":2,"details":"No /.well-known/http-message-signatures-directory found","recommendation":"Publish a Web Bot Auth directory at /.well-known/http-message-signatures-directory. Serve a JSON document with a 'keys' array of Ed25519 JWKs (kty=OKP, crv=Ed25519, kid, nbf, exp). This lets agents sign their requests per RFC 9421 so you can distinguish legitimate bots from spoofers.","bonus":true,"maturity":"emerging","tier":"emerging"},{"id":"oauth-protected-resource","name":"OAuth Protected Resource metadata (RFC 9728)","description":"Metadata at /.well-known/oauth-protected-resource (RFC 9728) that tells agents your auth requirements up front, instead of leaving them to trial and error.","status":"fail","score":0,"maxScore":2,"details":"No /.well-known/oauth-protected-resource found (RFC 9728)","recommendation":"Publish RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource. Include the resource field plus enough supporting metadata - your authorization servers, supported scopes, accepted bearer methods - that an agent can work out how to authenticate without first triggering a 401.","bonus":true,"maturity":"verified","tier":"required","estScoreGain":0.7},{"id":"auth-md-exists","name":"auth.md exists","description":"auth.md is a walkthrough that teaches an agent how to get its own credentials, served at /auth.md. An emerging standard from WorkOS.","status":"fail","score":0,"maxScore":2,"details":"No /auth.md found at site root","recommendation":"Publish /auth.md as a markdown prose walkthrough of how agents should obtain credentials. Serve it with Content-Type: text/markdown, lead with a top-level heading, and write at least ~200 chars of real content (not just a placeholder). See the WorkOS auth.md spec at https://github.com/workos/auth.md.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"required","estScoreGain":0.7},{"id":"auth-md-structure","name":"auth.md structure","description":"Your auth.md follows the standard walkthrough structure (discover, pick a method, register, claim, exchange, use, errors, revocation), so any agent can follow it step by step. We grade the content of each section, not just the headings.","status":"fail","score":0,"maxScore":2,"details":"No /auth.md found at site root","recommendation":"Structure /auth.md as the WorkOS spec prescribes: sections for Discover, Pick a method, Register, Claim, Exchange, Use the access_token, Errors, and Revocation, with spec anchor keywords (agent_auth, identity_endpoint, identity_assertion, service_auth, id-jag, WWW-Authenticate). Reference https://github.com/workos/auth.md.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"recommended","estScoreGain":0.7},{"id":"auth-md-walkthrough-simulation","name":"auth.md walkthrough simulation","description":"We do not take your auth.md's word for it: we simulate the walkthrough end to end (read-only) and verify an agent that only knows a user's email could actually get through it.","status":"na","score":0,"maxScore":2,"details":"/auth.md not found at site root","recommendation":"Make your published auth-discovery chain traversable end to end: an agent starting at /auth.md (or your protected-resource metadata) should be able to follow the links to your authorization-server metadata and registration endpoint without hitting a dead link. Test the whole path, not just each file in isolation.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"recommended"},{"id":"agent-auth-discovery-metadata","name":"Agent auth discovery metadata","description":"The machine-readable half of agent auth: discovery documents (RFC 9728 and 8414) with an agent_auth block that round-trips to your auth.md, so agents can look up the exact request shape for each supported identity type.","status":"fail","score":0,"maxScore":3,"details":"Neither /.well-known/oauth-protected-resource nor /.well-known/oauth-authorization-server found. Probed: celesto.ai, api.celesto.ai.","recommendation":"Publish RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource on your resource server (the host that actually serves the API, e.g. api.<apex>) with `resource` and `authorization_servers`. Publish RFC 8414 authorization-server metadata at /.well-known/oauth-authorization-server on the AS origin, and include the WorkOS auth.md `agent_auth` block with `identity_endpoint`, `identity_types_supported` drawn from the spec enum (`anonymous`, `identity_assertion`, `service_auth` - the assertion variant, the ID-JAG URN `urn:ietf:params:oauth:token-type:id-jag`, belongs inside `identity_assertion.assertion_types_supported`, not at the top level), and the `identity_assertion.assertion_types_supported` block when you advertise that type, so agents can check their assertion shape is accepted before minting. Cross-link by listing the AS origin in PRM `authorization_servers`, and point `agent_auth.skill` back at your published /auth.md. Spec: https://github.com/workos/auth.md.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"recommended","estScoreGain":1},{"id":"agent-auth-www-authenticate","name":"Agent auth WWW-Authenticate hint","description":"When an agent hits a 401 on your API, the response should point at the metadata explaining how to authenticate. One WWW-Authenticate header turns a dead end into a signpost.","status":"fail","score":0,"maxScore":1,"details":"No 401 with WWW-Authenticate: Bearer resource_metadata=... found. Probed [https://celesto.ai/api, https://celesto.ai/api/v1, https://celesto.ai/v1, https://celesto.ai/v2, https://celesto.ai/agent/identity, https://celesto.ai/agent/auth, https://api.celesto.ai/api, https://api.celesto.ai/api/v1, https://api.celesto.ai/v1, https://api.celesto.ai/v2, https://api.celesto.ai/agent/identity, https://api.celesto.ai/agent/auth].","recommendation":"Return a 401 carrying a spec-shaped `WWW-Authenticate: Bearer resource_metadata=\"<your protected-resource metadata URL>\"` header on your API's primary entry points, so an agent learns your auth requirements from one request instead of hunting for the well-known document. Point the metadata URL at /.well-known/oauth-protected-resource on the host that serves the API. Spec: https://github.com/workos/auth.md.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"recommended","estScoreGain":0.3},{"id":"agent-auth-endpoints-reachable","name":"agent_auth endpoints reachable","description":"The registration, claim, and revocation surfaces your auth docs advertise actually respond. Stale discovery data is worse than none: it sends agents to doors that no longer exist.","status":"fail","score":0,"maxScore":2,"details":"No agent_auth endpoint URIs found in AS metadata or /auth.md prose; nothing to probe","recommendation":"Make sure the URIs you advertise (in the AS metadata agent_auth block OR in your /auth.md prose) for identity_endpoint, claim_endpoint, and events_endpoint actually resolve. An OPTIONS preflight should return any HTTP status (2xx/3xx/4xx that isn't 404). DNS-level failure or a 404 means the discovery block / prose is stale - either remove the URI or stand up the endpoint.","bonus":true,"specUrl":"https://github.com/workos/auth.md/blob/main/AUTH.md","draft":true,"maturity":"verified","tier":"recommended","estScoreGain":0.7},{"id":"mcp-server","name":"MCP server / manifest","description":"MCP is how agents plug directly into your product, the way apps plug into an app store. We check for a Model Context Protocol server or manifest.","status":"warning","score":2,"maxScore":6,"details":"MCP mentioned on site but no standard manifest endpoint found","recommendation":"Build an MCP (Model Context Protocol) server exposing your API as tools. Use Streamable HTTP transport for full score. This lets Claude, ChatGPT, and other AI agents call your product natively.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":3.2},{"id":"mcp-error-handling","name":"MCP error handling","description":"When an agent sends your MCP server a bad request, the answer should be a structured error it can correct from, not a silent failure.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-transport-modern","name":"MCP modern transport","description":"Your MCP server speaks the current transport (Streamable HTTP), not just the legacy one. New agent clients increasingly expect it.","status":"na","score":0,"maxScore":1,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"webmcp","name":"WebMCP support","description":"WebMCP (a W3C draft) exposes tools to agents right on your web pages, no separate server needed. Chrome and the ChatGPT desktop browser now discover and call these tools, so agents browsing your site can act, not just read.","status":"warning","score":1,"maxScore":5,"details":"WebMCP mentioned in documentation at /docs but not implemented on homepage","recommendation":"Expose in-page tools through WebMCP, a proposed web standard for browser agents. Register tools with document.modelContext.registerTool() and use navigator.modelContext only as a trailing compatibility fallback. Declarative forms with toolname and tooldescription provide server-rendered evidence, but remain a preview and should not be your only tool surface. Chrome's origin trial covers versions 149-156, with shipping currently targeted for 157. ChatGPT can discover and call WebMCP site tools in the desktop app's built-in browser when the feature is available.","bonus":false,"maturity":"verified","tier":"required","estScoreGain":3.2},{"id":"rate-limit-headers","name":"Rate limit response headers","description":"Standard RateLimit headers tell agents how much room they have left, so they slow down gracefully instead of hitting errors and giving up on you.","status":"na","score":0,"maxScore":2,"details":"No REST or GraphQL surface detected - rate-limit headers check not applicable","recommendation":"Return standard rate-limit headers on your API responses (the RFC RateLimit headers, plus Retry-After on a 429) so agents can self-throttle in real time, and document the conventions alongside your API.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"idempotency-key-support","name":"Idempotency-Key support","description":"Networks fail mid-request. Idempotency keys let an agent retry a payment or an order safely, without doubling it. We check that write endpoints accept the header.","status":"na","score":0,"maxScore":3,"details":"No REST or GraphQL surface detected - idempotency check not applicable","recommendation":"Support an idempotency key on your write operations and declare it where agents can read it: an Idempotency-Key header parameter on your POST/PUT/PATCH operations in your OpenAPI spec for REST, or a client-supplied id argument on your GraphQL mutations. Agents retry on network failures, and without this a retry can double-charge or duplicate a record.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"json-error-responses","name":"JSON error responses","description":"When something breaks, agents need a structured JSON error, not an HTML error page. One is recoverable, the other is a dead end.","status":"pass","score":4,"maxScore":4,"details":"API returns JSON error responses (404 at https://api.celesto.ai)","recommendation":"Return structured JSON error responses with error codes, messages, and resolution hints. Agents can't parse HTML error pages.","bonus":false,"maturity":"verified","tier":"required"},{"id":"api-error-model","name":"REST typed error model","description":"A typed error schema in your OpenAPI spec, so agents know every failure shape in advance and can handle each one deliberately.","status":"na","score":0,"maxScore":3,"details":"No REST API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"api-versioning-policy","name":"REST versioning / deprecation policy","description":"Agents integrate once and then run unattended. A versioning and deprecation policy is your promise about when things will break and how much warning they get.","status":"na","score":0,"maxScore":3,"details":"No REST API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"pagination-shape","name":"REST pagination pattern","description":"A predictable way to page through lists, cursor-based preferred. Without one, agents read page one and quietly miss the rest of your data.","status":"na","score":0,"maxScore":2,"details":"No REST API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"async-job-pattern","name":"REST async-job pattern","description":"Long-running operations should return 202 Accepted with a way to poll for the result. Otherwise agents time out and retry work that was still running.","status":"na","score":0,"maxScore":2,"details":"No REST API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"cli-tool","name":"CLI tool available","description":"An official CLI. Coding agents live in the terminal, so a CLI makes your product directly operable by the fastest-growing class of agents.","status":"warning","score":2,"maxScore":3,"details":"CLI tool mentioned in llms.txt","recommendation":"Publish an official CLI tool on npm, PyPI, or Homebrew. A CLI lets agents and developers script interactions with your product without building API integrations from scratch.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":0.8},{"id":"rest-sdk-packages","name":"Multi-language SDK packages","description":"Official SDKs across ecosystems (npm, PyPI, Go). Each one is an integration an agent does not have to hand-roll, in the language it is already working in.","status":"warning","score":2,"maxScore":3,"details":"SDK packages found in npm, pypi","recommendation":"Publish official SDK packages across multiple language ecosystems (npm, PyPI, Go modules, RubyGems). Auto-generate them from your OpenAPI spec using tools like openapi-generator. For each package set the project URL or homepage to your product domain (package.json `repository`/`homepage`, PyPI `Home-Page` or `project_urls`, RubyGems `homepage_uri`) - this is how agents verify the package is your official SDK.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":0.8},{"id":"nlweb-ask","name":"NLWeb /ask endpoint","description":"An NLWeb /ask endpoint that answers natural-language questions about your site directly, no crawling needed.","status":"fail","score":0,"maxScore":1,"details":"No NLWeb-conformant /ask endpoint found via GET or POST","recommendation":"Implement Microsoft's NLWeb protocol by adding a POST /ask endpoint that accepts natural-language queries and returns JSON with _meta (response_type, version). See github.com/microsoft/NLWeb.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"nlweb-streaming","name":"NLWeb streaming support","description":"Your /ask endpoint streams results as they are found, so agents can show progress instead of a spinner.","status":"fail","score":0,"maxScore":1,"details":"NLWeb /ask does not support SSE streaming via GET or POST","recommendation":"Add SSE streaming to your NLWeb /ask endpoint. Accept prefer.streaming: true and respond with Content-Type: text/event-stream using NLWeb event types (start, result, complete).","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"response-schema-coverage","name":"REST response schema coverage","description":"Typed response schemas on most of your API operations, so agents know the shape of what comes back before they call.","status":"na","score":0,"maxScore":2,"details":"No REST API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"mcp-tool-annotations","name":"MCP tool annotations","description":"Labels that tell agents which tools are safe to call freely and which change or destroy things (readOnlyHint, destructiveHint). Essential when your MCP server can mutate real data.","status":"na","score":0,"maxScore":2,"details":"No MCP server detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-server-card","name":"MCP server-card.json","description":"A server card for each MCP server, at <server URL>/server-card or listed in /.well-known/ai-catalog.json, that tells an agent what the server is and where to connect before it does.","status":"fail","score":0,"maxScore":2,"details":"No MCP server card found (checked /.well-known/mcp/server-card.json, the site's ai-catalog.json, servers[].card in mcp.json, and <server>/server-card)","recommendation":"Publish a server card for each MCP server (draft MCP server-card extension). List each card in /.well-known/ai-catalog.json, or serve it at <server URL>/server-card. /.well-known/mcp/server-card.json is still read for a site with one server, but the extension does not recommend it. Include name, description, and version, and put the server's exact address in remotes[].url (serverUrl is also read) so agents match each card to the right server before connecting. Follow the extension schema for full credit: $schema set to https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json, a reverse-DNS name such as com.example/mcp, and no tools[] (agents always trust the live tools/list). Keep the description to 100 characters or fewer, as the schema requires. A card without that $schema is still read, and then an optional tools[] list completes it.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":0.7},{"id":"mcp-multi-surface-coverage","name":"Product + docs MCP coverage","description":"Two MCP servers, cleanly split: one for taking actions in your product, one for answering questions from your docs. The mature pattern for brands that have both.","status":"fail","score":0,"maxScore":2,"details":"This bonus needs two MCP servers: one for your product so agents can take actions, and a separate one for your documentation so agents can answer questions from your docs.","recommendation":"Beyond your product MCP server, expose a documentation MCP surface so agents can pull your docs and reference material over the same protocol they use to act. Covering both the 'do' and the 'learn' surfaces over MCP earns this.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":0.7},{"id":"sandbox-environment","name":"Sandbox / test environment","description":"A sandbox or test mode where agents can build an integration without touching production data. It lowers the stakes of every first call.","status":"warning","score":0,"maxScore":2,"details":"Sandbox/test environment mentioned at https://celesto.ai/docs/llms.txt but no sandbox surface verified","recommendation":"Provide a sandbox or test mode so agents can exercise your API without touching production data, and document how to reach it - this lowers the risk of a destructive call against live data.","bonus":true,"maturity":"verified","tier":"recommended","estScoreGain":0.7},{"id":"batch-endpoints","name":"REST batch / bulk endpoint","description":"Batch operations let an agent do a thousand things in one request instead of a thousand requests. We look for a /batch endpoint or array request bodies.","status":"na","score":0,"maxScore":2,"details":"No REST API surface detected on this domain","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-resource-listing","name":"MCP resources exposed","description":"If your MCP server claims to offer resources, resources/list should return some. Advertising a capability and delivering nothing erodes agent trust.","status":"na","score":0,"maxScore":3,"details":"No MCP server detected","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"graphql-error-type-definition","name":"GraphQL typed error model","description":"Typed errors in your GraphQL schema (userErrors, error unions), so agents can tell 'bad input' from 'try again later' and react correctly.","status":"na","score":0,"maxScore":3,"details":"No GraphQL API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"graphql-versioning-policy","name":"GraphQL versioning / deprecation policy","description":"Deprecations declared in the schema (@deprecated) or a documented evolution policy, so agents learn about breaking changes before the break.","status":"na","score":0,"maxScore":2,"details":"No GraphQL API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"graphql-pagination-pattern","name":"GraphQL pagination pattern","description":"Relay-style cursor pagination (Connection and PageInfo types), the pattern every GraphQL client and agent already knows how to walk.","status":"na","score":0,"maxScore":2,"details":"No GraphQL API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"graphql-async-job-pattern","name":"GraphQL async-job pattern","description":"Async job mutations with status types or progress subscriptions, so long-running work looks like progress instead of a hang.","status":"na","score":0,"maxScore":2,"details":"No GraphQL API surface detected on this domain","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"graphql-schema-completeness","name":"GraphQL schema description coverage","description":"Descriptions on at least 80% of your GraphQL types and fields. A well-described schema documents itself to any agent that introspects it.","status":"na","score":0,"maxScore":3,"details":"No GraphQL API surface detected on this domain","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"graphql-batch-mutations","name":"GraphQL batch mutations","description":"Bulk mutation fields (createMany, updateMany) so agents can act at scale in one round trip instead of hundreds.","status":"na","score":0,"maxScore":2,"details":"No GraphQL API surface detected on this domain","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"agent-friendly-404","name":"Agent-friendly 404s","description":"A real 404/410 status earns partial credit. Full credit also requires a Markdown error body, so agents can read what happened and where to go next.","status":"warning","score":1,"maxScore":2,"details":"The nonexistent path https://celesto.ai/__ora-404-probe-dp2u6xok correctly returns HTTP 404. Partial credit: no Markdown error body was detected.","recommendation":"Keep the correct HTTP 404 status. The remaining requirement is a Markdown error body when agents request Accept: text/markdown. Include at least 20 characters explaining the error and a link to your docs, sitemap, or llms.txt. Verify with `curl -sS -L -i -H 'Accept: text/markdown' https://yourdomain.com/some-path-that-does-not-exist`. Check both the final 404 status and the Markdown body with Content-Type: text/markdown. Checking the status alone does not verify the missing requirement.","bonus":false,"specUrl":"https://www.rfc-editor.org/rfc/rfc9110#name-404-not-found","maturity":"verified","tier":"recommended","estScoreGain":0.8},{"id":"ax-document-structure","name":"Accessible document structure","description":"Agents navigate your page the way screen readers do: by landmarks and headings. We check your HTML is a real document, with a main region, nav, and a sane heading order.","status":"pass","score":3,"maxScore":3,"details":"Server HTML is a well-structured document (main=true, landmarks=3/4, h1=1, maxHeadingSkip=1).","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"ax-native-controls","name":"Native interactive controls","description":"Buttons should be buttons. Clickable divs are invisible to agents that target elements by role and name, so they cannot click what your users can.","status":"pass","score":3,"maxScore":3,"details":"61 native controls, 1 non-native div-soup affordances (98% native).","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"ax-accessible-names","name":"Accessible names on controls","description":"Every control needs a name a machine can compute (text, label, aria-label, alt). An unnamed icon button cannot be referenced, so it cannot be used.","status":"pass","score":2,"maxScore":2,"details":"61/61 interactive elements have a computable accessible name (100%).","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"ax-form-labeling","name":"Form control labeling","description":"Form fields with real labels, so agents know what each one expects. Placeholder text disappears on focus and never counts. N/A when a page has no forms.","status":"na","score":0,"maxScore":2,"details":"No form controls present on the homepage; form labeling not applicable.","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"ax-tree-injection-safe","name":"Accessibility-tree injection safety (bonus)","description":"We scan for hidden instructions in aria-labels, alt text, and off-screen content that could hijack an agent reading your page (prompt injection). Upside only; never costs points.","status":"pass","score":2,"maxScore":2,"details":"No hidden instruction text detected in accessibility-tree attributes or off-screen content.","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-app-registry","name":"MCP Apps support","description":"MCP Apps let you ship real interactive UI inside ChatGPT and Claude, not just text answers. We check whether your server exposes any. N/A for pure API and data services.","status":"na","score":0,"maxScore":4,"details":"No in-agent UI surface - MCP Apps render interactive UI inside an agent host (ChatGPT, Claude). A data / API service does not need one, so this is not applicable.","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"a2ui-support","name":"A2UI / generative UI support","description":"Your product can render UI inside an agent conversation, via MCP Apps, the OpenAI Apps SDK, or generative UI patterns. Where users see you when they never visit your site.","status":"na","score":0,"maxScore":2,"details":"No in-agent UI surface - generative / agent-to-UI rendering does not apply to a backend data / API service.","recommendation":"Support Agent-to-UI rendering via MCP Apps (ui:// resources), OpenAI Apps SDK, or generative UI patterns that let agents render interactive UIs in conversation.","bonus":false,"maturity":"emerging","tier":"emerging"},{"id":"mcp-apps-ui-quality","name":"MCP Apps UI quality","description":"Your in-agent UI holds up to scrutiny: correct MIME type, valid HTML, dark mode support, and no hardcoded secrets in the markup.","status":"na","score":0,"maxScore":4,"details":"No MCP Apps detected","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"mcp-view-domain","name":"MCP App view reachable","description":"The view your MCP App points at loads publicly and serves HTML with no auth wall. A broken or gated view is worse than none: it fails in front of the user.","status":"na","score":0,"maxScore":4,"details":"No MCP App detected","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"mcp-view-csp","name":"MCP App view CSP","description":"ChatGPT, Claude, and other hosts sandbox your MCP App view with the CSP you declare in _meta.ui.csp. We check that it names specific origins, or is left out so hosts apply their strict default.","status":"na","score":0,"maxScore":4,"details":"No MCP App detected","bonus":false,"maturity":"verified","tier":"recommended"},{"id":"api-schema-analysis","name":"API schema complexity analysis","description":"Is your API simple enough for an agent to use without a human explaining it? Deeply nested, ambiguous schemas fail silently in agent hands.","status":"fail","score":0,"maxScore":2,"details":"No API schema detected","recommendation":"Make your API spec self-describing: a unique operationId and a description on every operation, typed parameters, and response schemas. For GraphQL, a fully typed schema with a documented cost or rate limit reads best.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":1.6},{"id":"function-calling-compat","name":"Function calling compatibility","description":"Whether your API spec translates cleanly into the function-calling format ChatGPT, Claude, and Gemini actually consume. Incompatible specs mean agents cannot call you even when they want to.","status":"fail","score":0,"maxScore":2,"details":"No API spec found - function calling requires discoverable endpoints","recommendation":"Ensure API endpoints have unique operation IDs, typed schemas, and descriptions compatible with LLM function-calling formats.","bonus":false,"maturity":"verified","tier":"recommended","estScoreGain":1.6},{"id":"mcp-resource-quality","name":"MCP resource quality","description":"The MCP resources you declare should actually read: valid type, non-empty content. We grade the share that works.","status":"na","score":0,"maxScore":3,"details":"No MCP server detected","bonus":false,"maturity":"verified","tier":"recommended"}],"score":32,"maxScore":56},{"id":"payments","name":"Payments","description":"Can agents pay you?","checks":[{"id":"mpp-support","name":"MPP payment protocol","description":"Machine Payments Protocol lets an agent pay you over plain HTTP. Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":2,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Implement the Machine Payments Protocol so agents can pay for premium resources over HTTP 402. Return a complete WWW-Authenticate: Payment challenge - the full set of standard MPP parameters, not just the bare scheme - and advertise x-payment-info in your OpenAPI spec so agents can discover it.","bonus":true,"maturity":"verified","tier":"required"},{"id":"x402-support","name":"x402 payment protocol","description":"x402 lets an agent pay per request over plain HTTP micropayments. Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":2,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Implement x402 payment protocol so AI agents can pay for API access via HTTP 402. x402 uses PAYMENT-REQUIRED/PAYMENT-SIGNATURE/PAYMENT-RESPONSE headers with Base64-encoded JSON. Add a /discovery/resources endpoint for agent discovery.","bonus":true,"maturity":"verified","tier":"required"},{"id":"ucp-support","name":"UCP - Universal Commerce Protocol","description":"A Universal Commerce Protocol profile at /.well-known/ucp, telling shopping agents how to transact with you. Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":3,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Publish a UCP discovery profile at /.well-known/ucp with a required `version` (YYYY-MM-DD) and advertised `services`/`capabilities` per ucp.dev. Also expose the REST checkout surface (`POST /checkout-sessions` with `UCP-Agent` and `Idempotency-Key` headers) so agents can transact without per-vendor integrations.","bonus":true,"maturity":"verified","tier":"required"},{"id":"acp-support","name":"ACP - Agentic Commerce Protocol","description":"A live Agentic Commerce Protocol checkout endpoint (/checkout_sessions), the flow behind agent-driven purchases in ChatGPT. Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":3,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Implement the Agentic Commerce Protocol checkout REST API: `POST /checkout_sessions` (create), update/get/complete/cancel variants, with `API-Version: YYYY-MM-DD` and `Idempotency-Key` required headers. Preflight OPTIONS should allow POST or return an ACP-shaped error with `supported_versions` so agents can negotiate.","bonus":true,"maturity":"verified","tier":"required"},{"id":"acp-delegate-payment","name":"ACP delegate payment","description":"The ACP endpoint that lets a buyer's agent hand you a payment credential securely (/agentic_commerce/delegate_payment). Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":3,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Expose the ACP Delegate Payment endpoint at `POST /agentic_commerce/delegate_payment`. The request takes `payment_method`, `allowance` (max amount, currency, expiry, merchant scope), and `risk_signals`; the response returns a vault token. This lets agents pay on behalf of users with scoped, revocable credentials.","bonus":true,"maturity":"verified","tier":"recommended"},{"id":"ap2-support","name":"AP2 - Agent Payments Protocol","description":"Google's Agent Payments Protocol: signed mandates that prove a human authorized the purchase, backed by Mastercard, Visa, PayPal and Amex. Supporting any one payment protocol is enough, so this reads N/A when another is detected. Optional for non-commerce sites.","status":"na","score":0,"maxScore":3,"details":"No commerce signals detected - agent-payment protocols are optional for non-commerce sites","recommendation":"Adopt Google's AP2 (Agent Payments Protocol) authorization layer: advertise an AP2 mandate capability (e.g. `dev.ucp.shopping.ap2_mandate`) in your UCP discovery profile, and verify the three signed mandates (Intent, Cart, Payment - SD-JWT verifiable digital credentials) server-side before routing to a settlement rail. Note: one agentic payment protocol is sufficient - AP2 is only needed if you are not already covered by x402 / MPP / ACP / UCP.","bonus":true,"specUrl":"https://ap2-protocol.org/","maturity":"verified","tier":"recommended"}],"score":0,"maxScore":0}],"scannedAt":"2026-10-08T02:28:26.682+00:00","durationMs":11651,"agenticSummary":"Celesto.ai offers a solid developer SDK, but lacks an OpenAPI specification.","analysisStatus":"complete","pendingChecks":[]}