---
target: "notion.so"
lane: web
tier: cache
scorecard_url: "https://anc.dev/score/notion.so"
markdown_url: "https://anc.dev/score/notion.so/md"
json_url: "https://anc.dev/score/notion.so/json"
negotiate: "Accept: text/markdown or Accept: application/json on https://anc.dev/score/notion.so serve the twin and the JSON"
---

# Notion — Agent-Readiness Audit

Website: [https://notion.so/](https://notion.so/)

**Score:** 50% (relative to the checks that apply to this site)
**Global:** 15% of a maximally agent-ready site

Scored 2026-09-15T19:02:08.022Z. Refresh available now. This is cache-reuse eligibility; a fresh audit is still subject to service limits.

## Discoverability (3/6)

### PASS — /robots.txt present

- Tier: SHOULD
- Goal: Publish robots.txt and state your crawl policy explicitly.
- Result: Verified (https://notion.so/robots.txt -> 200)
- Resources: [RFC 9309](https://www.rfc-editor.org/rfc/rfc9309), [Fix skill](https://anc.dev/fix/robots)

### PASS — /sitemap.xml present

- Tier: MAY
- Goal: Publish sitemap.xml so agents can enumerate your content URLs.
- Result: Verified (https://notion.so/sitemap.xml -> 200)
- Resources: [sitemaps.org](https://www.sitemaps.org/protocol.html), [Fix skill](https://anc.dev/fix/sitemap)

### MISSING — Homepage sends RFC 8288 Link headers pointing at agent resources

- Tier: SHOULD
- Goal: Advertise machine surfaces in a Link response header on / for header-only discovery.
- Result: Not found (https://notion.so/ -> 200 (header link no match /rel="?(service-desc|describedby|api-catalog|service-doc)"?/))
- Fix: Send a `Link` response header on `/` (RFC 8288) whose `rel` points at your machine surfaces, so an agent reading only response headers finds them without parsing HTML or probing `/.well-known`. Use the RFC 8631 service trio and the RFC 9727 catalog: `rel="service-desc"` at a machine-readable description (OpenAPI, or an MCP server card), `rel="service-doc"` at the human-readable doc, `rel="service-meta"` at the service-context declaration, and `rel="api-catalog"` at your `/.well-known/api-catalog` index. Example: `Link: </.well-known/api-catalog>; rel="api-catalog", </.well-known/mcp/server-card.json>; rel="service-desc"`.
- Resources: [RFC 8288 (Link)](https://www.rfc-editor.org/rfc/rfc8288), [RFC 8631 (service links)](https://www.rfc-editor.org/rfc/rfc8631), [RFC 9727 (api-catalog)](https://www.rfc-editor.org/rfc/rfc9727), [Fix skill](https://anc.dev/fix/link-headers)

```text
Goal: Advertise machine surfaces in a Link response header on / for header-only discovery
Fix: Send a `Link` response header on `/` (RFC 8288) whose `rel` points at your machine surfaces, so an agent reading only response headers finds them without parsing HTML or probing `/.well-known`. Use the RFC 8631 service trio and the RFC 9727 catalog: `rel="service-desc"` at a machine-readable description (OpenAPI, or an MCP server card), `rel="service-doc"` at the human-readable doc, `rel="service-meta"` at the service-context declaration, and `rel="api-catalog"` at your `/.well-known/api-catalog` index. Example: `Link: </.well-known/api-catalog>; rel="api-catalog", </.well-known/mcp/server-card.json>; rel="service-desc"`.
Skill: https://anc.dev/fix/link-headers
Docs: https://www.rfc-editor.org/rfc/rfc8288, https://www.rfc-editor.org/rfc/rfc8631, https://www.rfc-editor.org/rfc/rfc9727
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/ -> 200 (header link no match /rel="?(service-desc|describedby|api-catalog|service-doc)"?/)
--- end evidence ---
```

### PASS — Root HTML links to machine surfaces via <link rel>

- Tier: SHOULD
- Goal: Point link rel elements at your machine surfaces from the root HTML head.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [RFC 8631 (service-desc/doc)](https://www.rfc-editor.org/rfc/rfc8631), [Fix skill](https://anc.dev/fix/root-link-rel)

### N/A — DNS for AI Discovery (DNS-AID) records under _agents (IETF draft)

- Tier: MAY
- Goal: Publish DNSSEC-signed SVCB records under _agents for DNS-level agent discovery.
- Result: Not implemented, optional (no DNS-AID records)
- Resources: [DNS-AID draft](https://datatracker.ietf.org/doc/draft-mozleywilliams-dnsop-dnsaid/), [Fix skill](https://anc.dev/fix/dns-aid)

### BROKEN — 404 body is markdown with a recovery link

- Tier: SHOULD
- Goal: Serve a short markdown 404 that links at least one agent recovery surface.
- Result: Present but broken (https://notion.so/anc-web-audit-no-such-page -> 401 (status 401 not in [404, 410]))
- Fix: When `Accept: text/markdown` hits an unknown path, return 404 or 410 with a short markdown body that includes at least one recovery link: sitemap, `llms.txt`, a docs index, or an equivalent same-origin href. Linking both sitemap and `llms.txt` as absolute URLs is the stronger pattern. Zero links is a miss even when the status is correct.
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/agent-friendly-404-md)

```text
Goal: Serve a short markdown 404 that links at least one agent recovery surface
Fix: When `Accept: text/markdown` hits an unknown path, return 404 or 410 with a short markdown body that includes at least one recovery link: sitemap, `llms.txt`, a docs index, or an equivalent same-origin href. Linking both sitemap and `llms.txt` as absolute URLs is the stronger pattern. Zero links is a miss even when the status is correct.
Skill: https://anc.dev/fix/agent-friendly-404-md
Docs: https://llmstxt.org/
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/anc-web-audit-no-such-page -> 401 (status 401 not in [404, 410])
--- end evidence ---
```

### BROKEN — Unknown paths return HTTP 404 or 410

- Tier: SHOULD
- Goal: Return a real HTTP 404 or 410 for unknown paths instead of a 200 SPA shell.
- Result: Present but broken (https://notion.so/anc-web-audit-no-such-page -> 401 (status 401 not in [404, 410]))
- Fix: Configure the origin so a nonsense path under the site returns HTTP 404 or 410, not 200 with the application shell. A soft-404 hides recovery from agents: they treat the page as content and never look for a sitemap or `llms.txt`. Verify with `curl -sS -o /dev/null -w "%{http_code}" https://example.com/this-path-does-not-exist` — it MUST print `404` (or `410`).
- Resources: [RFC 9110 status codes](https://www.rfc-editor.org/rfc/rfc9110#name-status-codes), [Fix skill](https://anc.dev/fix/agent-friendly-404)

```text
Goal: Return a real HTTP 404 or 410 for unknown paths instead of a 200 SPA shell
Fix: Configure the origin so a nonsense path under the site returns HTTP 404 or 410, not 200 with the application shell. A soft-404 hides recovery from agents: they treat the page as content and never look for a sitemap or `llms.txt`. Verify with `curl -sS -o /dev/null -w "%{http_code}" https://example.com/this-path-does-not-exist` — it MUST print `404` (or `410`).
Skill: https://anc.dev/fix/agent-friendly-404
Docs: https://www.rfc-editor.org/rfc/rfc9110#name-status-codes
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/anc-web-audit-no-such-page -> 401 (status 401 not in [404, 410])
--- end evidence ---
```

## Content for agents (6/10)

### PASS — /llms.txt present with a summary and link index

- Tier: SHOULD
- Goal: Serve /llms.txt with a title, summary, and categorized link index.
- Result: Verified (https://notion.so/llms.txt -> 200)
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-txt)

### N/A — /llms-full.txt present (single-fetch full corpus)

- Tier: MAY
- Goal: Serve the whole docs corpus as markdown at /llms-full.txt for one-fetch ingestion.
- Result: Not implemented, optional (https://notion.so/llms-full.txt -> 404 (status 404 not in [200]))
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-full-txt)

### MISSING — Accept text/markdown content negotiation returns markdown

- Tier: SHOULD
- Goal: Honor Accept text/markdown on content URLs with raw markdown, not HTML chrome.
- Result: Not found (https://notion.so/ -> 200 (content-type "text/html; charset=utf-8" !~ /markdown|text/plain/))
- Fix: Honor `Accept: text/markdown` on content URLs and return raw markdown rather than HTML chrome. Agents parse markdown far more reliably than a JS-rendered page. Serve the markdown twin at the same URL via content negotiation, invisibly to crawlers.
- Resources: [RFC 7763 (text/markdown)](https://www.rfc-editor.org/rfc/rfc7763), [Fix skill](https://anc.dev/fix/accept-markdown)

```text
Goal: Honor Accept text/markdown on content URLs with raw markdown, not HTML chrome
Fix: Honor `Accept: text/markdown` on content URLs and return raw markdown rather than HTML chrome. Agents parse markdown far more reliably than a JS-rendered page. Serve the markdown twin at the same URL via content negotiation, invisibly to crawlers.
Skill: https://anc.dev/fix/accept-markdown
Docs: https://www.rfc-editor.org/rfc/rfc7763
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/ -> 200 (content-type "text/html; charset=utf-8" !~ /markdown|text/plain/)
--- end evidence ---
```

### N/A — Per-section llms-full.txt files resolve under content subdirectories

- Tier: MAY
- Goal: Serve a scoped llms-full.txt corpus inside each major content section.
- Result: Not applicable (root llms-full.txt not present)
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-full-txt-scoped)

### MISSING — llms.txt has H1, summary, and a link index

- Tier: SHOULD
- Goal: Structure /llms.txt with an H1, a blockquote summary, and a markdown link index.
- Result: Not found (https://notion.so/llms.txt -> error (link index present))
- Fix: Follow the llmstxt.org shape: start with `# Title`, add a `>` summary blockquote, then a categorized list of markdown links. A file that is present but is only a heading, or only a blob of prose, fails this row even when the presence check passes.
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-txt-format)

```text
Goal: Structure /llms.txt with an H1, a blockquote summary, and a markdown link index
Fix: Follow the llmstxt.org shape: start with `# Title`, add a `>` summary blockquote, then a categorized list of markdown links. A file that is present but is only a heading, or only a blob of prose, fails this row even when the presence check passes.
Skill: https://anc.dev/fix/llms-txt-format
Docs: https://llmstxt.org/
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/llms.txt -> error (link index present)
--- end evidence ---
```

### MISSING — llms.txt has a when-to-use or programmatic-access section

- Tier: SHOULD
- Goal: Tell agents when to use the MCP or docs from a short llms.txt heading.
- Result: Not found (https://notion.so/llms.txt -> error (no when-to-use heading))
- Fix: Add a heading such as `## When to use` or `## Programmatic access` with a few lines on when an agent should connect (for example: "Use the MCP when you need to search or score a CLI"). The audit looks for that heading; it does not grade the prose with an LLM.
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-txt-when-to-use)

```text
Goal: Tell agents when to use the MCP or docs from a short llms.txt heading
Fix: Add a heading such as `## When to use` or `## Programmatic access` with a few lines on when an agent should connect (for example: "Use the MCP when you need to search or score a CLI"). The audit looks for that heading; it does not grade the prose with an LLM.
Skill: https://anc.dev/fix/llms-txt-when-to-use
Docs: https://llmstxt.org/
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/llms.txt -> error (no when-to-use heading)
--- end evidence ---
```

### N/A — Per-section llms.txt files resolve under content subdirectories

- Tier: MAY
- Goal: Serve a scoped llms.txt inside each major content section.
- Result: Not implemented, optional (llms-txt-scoped -> error (no section directories in the root llms.txt or sitemap))
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-txt-scoped)

### MISSING — Negotiated responses carry Vary Accept, User-Agent

- Tier: SHOULD
- Goal: Emit Vary Accept, User-Agent so shared caches never serve one client the wrong variant.
- Result: Not found (https://notion.so/ -> 200 (header vary no match /(?=.*accept(?!-))(?=.*user-agent)/))
- Fix: When the same URL serves HTML or markdown depending on the request, emit `Vary: Accept, User-Agent` on every response. Without it a shared cache (a CDN or a corporate proxy) can store the markdown twin under the bare URL and then hand it to a browser, or vice versa. Listing both request headers you negotiate on tells every cache to key its stored copies by them, so each client class gets the variant it asked for. If the CDN ignores or strips Vary (Cloudflare's zone cache historically keeps only `Accept-Encoding`), do not give that cache a long `s-maxage` on negotiated responses — otherwise HIT replies reach clients with no Vary and the check still fails.
- Resources: [RFC 9110 (Vary)](https://www.rfc-editor.org/rfc/rfc9110#name-vary), [Fix skill](https://anc.dev/fix/markdown-vary)

```text
Goal: Emit Vary Accept, User-Agent so shared caches never serve one client the wrong variant
Fix: When the same URL serves HTML or markdown depending on the request, emit `Vary: Accept, User-Agent` on every response. Without it a shared cache (a CDN or a corporate proxy) can store the markdown twin under the bare URL and then hand it to a browser, or vice versa. Listing both request headers you negotiate on tells every cache to key its stored copies by them, so each client class gets the variant it asked for. If the CDN ignores or strips Vary (Cloudflare's zone cache historically keeps only `Accept-Encoding`), do not give that cache a long `s-maxage` on negotiated responses — otherwise HIT replies reach clients with no Vary and the check still fails.
Skill: https://anc.dev/fix/markdown-vary
Docs: https://www.rfc-editor.org/rfc/rfc9110#name-vary
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/ -> 200 (header vary no match /(?=.*accept(?!-))(?=.*user-agent)/)
--- end evidence ---
```

### N/A — Accept text/plain returns the markdown twin

- Tier: MAY
- Goal: Treat Accept text/plain as a request for the raw markdown source.
- Result: Not implemented, optional (https://notion.so/ -> 200 (content-type "text/html; charset=utf-8" !~ /markdown|text/plain/))
- Resources: [RFC 7763 (text/markdown)](https://www.rfc-editor.org/rfc/rfc7763), [Fix skill](https://anc.dev/fix/markdown-accept-plain)

### PASS — Root HTML has a descriptive <meta name="description">

- Tier: SHOULD
- Goal: Add a meta description naming what the service does and its agent entry points.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [MDN meta description](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/name), [Fix skill](https://anc.dev/fix/root-meta-description)

### N/A — Root HTML embeds Schema.org JSON-LD

- Tier: MAY
- Goal: Embed Schema.org JSON-LD so agents get typed facts without inference.
- Result: Not implemented, optional (https://notion.so/ -> 200 (body no match /application/ld\+json/))
- Resources: [Schema.org](https://schema.org/docs/gs.html), [Fix skill](https://anc.dev/fix/schema-org-jsonld)

### PASS — Root HTML has an H1 and readable text without JavaScript

- Tier: SHOULD
- Goal: Put an H1 and enough visible text in the raw root HTML that a non-JS agent can read the page.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/content-without-js)

### PASS — Root HTML uses semantic landmarks

- Tier: MAY
- Goal: Use semantic landmarks so the HTML path is parseable structure, not div soup.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [MDN content sectioning](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements#content_sectioning), [Fix skill](https://anc.dev/fix/semantic-html)

### PASS — Root HTML has a <noscript> with machine entry points

- Tier: SHOULD
- Goal: Give non-JS agents a noscript block listing your machine entry points.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [MDN noscript](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/noscript), [Fix skill](https://anc.dev/fix/noscript-fallback)

### N/A — Bare CLI User-Agent receives the markdown twin

- Tier: MAY
- Goal: Serve the markdown twin to shell HTTP clients that state no content-type preference.
- Result: Not implemented, optional (https://notion.so/ -> 200 (content-type "text/html; charset=utf-8" !~ /markdown|text/plain/))
- Resources: [RFC 7763 (text/markdown)](https://www.rfc-editor.org/rfc/rfc7763), [RFC 9110 (User-Agent)](https://www.rfc-editor.org/rfc/rfc9110#name-user-agent), [Fix skill](https://anc.dev/fix/markdown-cli-ua)

### N/A — AI user-fetch User-Agent receives the markdown twin

- Tier: MAY
- Goal: Serve the markdown twin to AI on-demand user-fetchers that state no content-type preference.
- Result: Not implemented, optional (https://notion.so/ -> 200 (content-type "text/html; charset=utf-8" !~ /markdown|text/plain/))
- Resources: [RFC 7763 (text/markdown)](https://www.rfc-editor.org/rfc/rfc7763), [OpenAI bots and User-Agents](https://platform.openai.com/docs/bots), [Fix skill](https://anc.dev/fix/markdown-agent-ua)

### N/A — Markdown twin carries YAML frontmatter

- Tier: MAY
- Goal: Prefix the markdown twin with a YAML frontmatter block so agents read page metadata without parsing the body.
- Result: Not implemented, optional (https://notion.so/ -> 200 (root served HTML, not a markdown twin))
- Resources: [YAML front matter (Jekyll)](https://jekyllrb.com/docs/front-matter/), [RFC 7763 (text/markdown)](https://www.rfc-editor.org/rfc/rfc7763), [Fix skill](https://anc.dev/fix/markdown-frontmatter)

### PASS — llms.txt links resolve

- Tier: SHOULD
- Goal: Make every markdown href in /llms.txt fetchable.
- Result: Verified (https://www.notion.com/product/ai -> 200)
- Resources: [llmstxt.org](https://llmstxt.org/), [Fix skill](https://anc.dev/fix/llms-txt-links)

## Bot & crawl policy (3/4)

### PASS — AI user-fetch User-Agent can reach the homepage

- Tier: SHOULD
- Goal: Let on-demand user-fetchers GET / with Accept */* and receive 2xx, not a challenge page.
- Result: Verified (https://notion.so/ -> 200)
- Resources: [OpenAI user-fetchers](https://platform.openai.com/docs/bots), [Fix skill](https://anc.dev/fix/agent-ua-reachable)

### PASS — robots.txt declares AI-crawler rules (RFC 9309)

- Tier: SHOULD
- Goal: State your AI-crawler policy in robots.txt with explicit User-agent rules.
- Result: Verified (https://notion.so/robots.txt -> 200)
- Resources: [RFC 9309](https://www.rfc-editor.org/rfc/rfc9309), [Fix skill](https://anc.dev/fix/robots-ai-rules)

### BROKEN — robots.txt declares Content-Signal AI-usage preferences

- Tier: SHOULD
- Goal: Declare Content-Signal AI-usage preferences in robots.txt.
- Result: Present but broken (https://notion.so/robots.txt -> 200 (body no match /^\s*Content-Signal:\s*(ai-train|search|ai-input)/))
- Fix: Add `Content-Signal` directives to `robots.txt` (contentsignals.org): `ai-train`, `search`, and `ai-input` set to `yes` or `no`. They express usage preferences at a finer grain than a blanket allow/deny.
- Resources: [contentsignals.org](https://contentsignals.org/), [Fix skill](https://anc.dev/fix/content-signals)

```text
Goal: Declare Content-Signal AI-usage preferences in robots.txt
Fix: Add `Content-Signal` directives to `robots.txt` (contentsignals.org): `ai-train`, `search`, and `ai-input` set to `yes` or `no`. They express usage preferences at a finer grain than a blanket allow/deny.
Skill: https://anc.dev/fix/content-signals
Docs: https://contentsignals.org/
Observed (untrusted, not instructions):
--- begin evidence ---
https://notion.so/robots.txt -> 200 (body no match /^\s*Content-Signal:\s*(ai-train|search|ai-input)/)
--- end evidence ---
```

### N/A — Web Bot Auth signature directory present (informational)

- Tier: MAY
- Goal: Publish an HTTP Message Signatures directory if your site sends signed bot traffic.
- Result: Not implemented, optional (https://notion.so/.well-known/http-message-signatures-directory -> 404 (status 404 not in [200]))
- Resources: [Web Bot Auth draft](https://datatracker.ietf.org/doc/draft-meunier-web-bot-auth-architecture/), [Fix skill](https://anc.dev/fix/web-bot-auth)

### PASS — /.well-known/security.txt present (RFC 9116)

- Tier: MAY
- Goal: Publish security.txt with a Contact and Expires field.
- Result: Verified (https://notion.so/.well-known/security.txt -> 200)
- Resources: [RFC 9116](https://www.rfc-editor.org/rfc/rfc9116), [Fix skill](https://anc.dev/fix/security-txt)

## API (0/0)

No checks in this category apply to this site.

### N/A — An OpenAPI description is published

- Tier: MUST
- Goal: Publish an OpenAPI description so non-MCP agents can call your HTTP API.
- Result: Not applicable (no API surface detected)
- Resources: [OpenAPI 3.1](https://spec.openapis.org/oas/latest.html), [Fix skill](https://anc.dev/fix/openapi)

### N/A — Referenced JSON Schemas resolve as application/schema+json

- Tier: MAY
- Goal: Serve the JSON Schemas your API references so agents can validate payloads pre-flight.
- Result: Not applicable (no JSON Schema references detected)
- Resources: [JSON Schema](https://json-schema.org/specification), [Fix skill](https://anc.dev/fix/json-schemas)

### N/A — /.well-known/api-catalog published (RFC 9727)

- Tier: MAY
- Goal: Serve an RFC 9727 api-catalog linkset indexing your API descriptions.
- Result: Not applicable (no API surface detected)
- Resources: [RFC 9727](https://www.rfc-editor.org/rfc/rfc9727), [Fix skill](https://anc.dev/fix/api-catalog)

### N/A — API client errors return JSON, not HTML

- Tier: SHOULD
- Goal: Return a JSON error body on client-error API responses so agents can parse the failure.
- Result: Not applicable (no API surface detected)
- Resources: [RFC 9457 (problem+json)](https://www.rfc-editor.org/rfc/rfc9457), [Fix skill](https://anc.dev/fix/json-errors)

### N/A — API responses advertise rate-limit headers

- Tier: SHOULD
- Goal: Advertise remaining quota on API responses so agents can back off instead of retrying blindly.
- Result: Not applicable (no API surface detected)
- Resources: [IETF RateLimit header draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/), [Fix skill](https://anc.dev/fix/rate-limit-headers)

## MCP (0/0)

No checks in this category apply to this site.

### N/A — initialize handshake returns serverInfo + protocolVersion

- Tier: MUST
- Goal: Answer JSON-RPC initialize with serverInfo and protocolVersion so clients can begin a session.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle](https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-initialize)

### N/A — server/discover answers with server identity on the modern lane

- Tier: SHOULD
- Goal: Answer server/discover with supported versions, capabilities, and server identity.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-server-discover)

### N/A — initialize advertises capabilities (tools / resources / prompts)

- Tier: SHOULD
- Goal: Advertise the capability groups your MCP server implements in the initialize result.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle](https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-capabilities)

### N/A — tools/list returns a tools array with input schemas

- Tier: MUST
- Goal: Return tools/list entries with name, description, and a JSON inputSchema.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools), [Fix skill](https://anc.dev/fix/mcp-tools-list)

### N/A — resources/list returns at least one resource when advertised

- Tier: SHOULD
- Goal: Honor capabilities.resources with a non-empty resources/list result.
- Result: Not applicable (neither initialize nor server/discover advertises capabilities.resources)
- Resources: [MCP resources](https://modelcontextprotocol.io/specification/2025-06-18/server/resources), [Fix skill](https://anc.dev/fix/mcp-resources-list)

### N/A — header-routed tools/list (2026-07-28) returns tools without initialize

- Tier: MUST
- Goal: Answer a modern header-routed tools/list without requiring an initialize handshake.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [MCP tools (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools), [Fix skill](https://anc.dev/fix/mcp-modern-tools-list)

### N/A — unknown JSON-RPC method returns -32601

- Tier: SHOULD
- Goal: Reject unknown JSON-RPC methods with error -32601 instead of a hang or 500.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [Fix skill](https://anc.dev/fix/mcp-unknown-method)

### N/A — a non-JSON body draws -32700 (or a typed HTTP 400/415 refusal)

- Tier: SHOULD
- Goal: Refuse an unparseable request body with a parse-error envelope or a typed HTTP refusal.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [Fix skill](https://anc.dev/fix/mcp-malformed-body)

### N/A — a batch carrying a modern-envelope request is rejected -32600

- Tier: SHOULD
- Goal: Refuse JSON array batches that carry modern-era envelopes with -32600.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [MCP transports (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports), [Fix skill](https://anc.dev/fix/mcp-batch-reject)

### N/A — tools/call with an unknown tool name returns -32602

- Tier: SHOULD
- Goal: Reject an unknown tool name with -32602 instead of a hang, a 500, or a fake result.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools), [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [Fix skill](https://anc.dev/fix/mcp-unknown-tool)

### N/A — an unknown method on the modern lane returns -32601

- Tier: SHOULD
- Goal: Reject unknown header-routed methods with -32601 on the 2026-07-28 lane.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-modern-unknown-method)

### N/A — _meta missing clientCapabilities is rejected (-32602 or -32600)

- Tier: SHOULD
- Goal: Enforce the mandatory clientCapabilities key on every modern request.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-modern-clientcaps)

### N/A — an Mcp-Method header disagreeing with the body method draws -32020

- Tier: SHOULD
- Goal: Validate the SEP-2243 header mirror between Mcp-Method and the body method.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-modern-header-mismatch)

### N/A — an unsupported protocol version is rejected -32022 with data.supported

- Tier: SHOULD
- Goal: Refuse unsupported protocol version claims with -32022 and advertise the served revisions.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP lifecycle (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/lifecycle), [Fix skill](https://anc.dev/fix/mcp-modern-version-reject)

### N/A — modern resources/read with an unknown URI returns -32602

- Tier: SHOULD
- Goal: Answer an unknown resource URI with the typed miss code, not a hang or a fake result.
- Result: Not applicable (neither initialize nor server/discover advertises capabilities.resources)
- Resources: [MCP resources (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/resources), [JSON-RPC 2.0](https://www.jsonrpc.org/specification#error_object), [Fix skill](https://anc.dev/fix/mcp-modern-resources-miss)

### N/A — a JSON-only Accept is answered without SSE framing

- Tier: SHOULD
- Goal: Serve a single application/json response to a client whose Accept names only application/json.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports), [RFC 9110 section 12.5.1 (Accept)](https://www.rfc-editor.org/rfc/rfc9110#name-accept), [Fix skill](https://anc.dev/fix/mcp-accept-json)

### N/A — an unsatisfiable Accept draws a 406 rather than an unasked-for type

- Tier: SHOULD
- Goal: Refuse an Accept you cannot satisfy with 406, never a 200 carrying a type the client did not request.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [RFC 9110 section 15.5.7 (406 Not Acceptable)](https://www.rfc-editor.org/rfc/rfc9110#name-406-not-acceptable), [MCP transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports), [Fix skill](https://anc.dev/fix/mcp-accept-unsatisfiable)

### N/A — GET on the MCP endpoint answers fast (not a held-open hang)

- Tier: SHOULD
- Goal: Answer GET on the MCP endpoint fast (a fast-fail status or a documented surface), never a held-open hang.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MCP transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports), [Fix skill](https://anc.dev/fix/mcp-get-fast-fail)

### N/A — CORS preflight (OPTIONS) succeeds with Access-Control-Allow-* headers

- Tier: SHOULD
- Goal: Serve one consistent CORS posture on the MCP endpoint, full preflight support or none.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MDN CORS preflight](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request), [Fix skill](https://anc.dev/fix/mcp-cors-preflight)

### N/A — POST response carries Access-Control-Allow-Origin

- Tier: SHOULD
- Goal: Mirror the declared CORS posture on the actual MCP POST response.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [MDN CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS), [Fix skill](https://anc.dev/fix/mcp-cors-actual)

### N/A — A .well-known MCP server card is published (SEP-1649)

- Tier: SHOULD
- Goal: Publish an MCP server card at the canonical SEP-1649 path.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [SEP-1649](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127), [Fix skill](https://anc.dev/fix/well-known-mcp-card)

### N/A — Legacy MCP card paths redirect to the canonical card

- Tier: MAY
- Goal: Point every legacy MCP card path at the canonical card instead of serving its own copy.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [SEP-1649](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127), [Fix skill](https://anc.dev/fix/mcp-card-legacy-aliases)

### N/A — A human/agent usage doc for the server resolves

- Tier: MAY
- Goal: Publish a one-fetch markdown usage doc for your MCP server.
- Result: Not applicable (no MCP endpoint discovered)
- Resources: [anc.dev example](https://anc.dev/mcp-skill.md), [Fix skill](https://anc.dev/fix/mcp-usage-doc)

### N/A — Root HTML exposes WebMCP browser tools

- Tier: MAY
- Goal: Expose page tools to browser agents via WebMCP.
- Result: Not implemented, optional (https://notion.so/ -> 200 (no WebMCP markers in root HTML))
- Resources: [WebMCP spec](https://webmachinelearning.github.io/webmcp/), [Fix skill](https://anc.dev/fix/webmcp)

## Agent discovery & auth (0/0)

No checks in this category apply to this site.

### N/A — OAuth/OIDC discovery metadata published

- Tier: MAY
- Goal: Publish OAuth/OIDC discovery metadata if agents authenticate to your service.
- Result: Not applicable (no auth surface detected)
- Resources: [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414), [Fix skill](https://anc.dev/fix/oauth-discovery)

### N/A — OAuth Protected Resource Metadata published (RFC 9728)

- Tier: MAY
- Goal: Publish RFC 9728 protected-resource metadata for your authenticated MCP server.
- Result: Not applicable (MCP endpoint does not challenge for auth)
- Resources: [RFC 9728](https://www.rfc-editor.org/rfc/rfc9728), [Fix skill](https://anc.dev/fix/oauth-protected-resource)

### N/A — Agent auth/registration metadata doc published

- Tier: MAY
- Goal: Publish an auth.md telling agents how to obtain credentials.
- Result: Not applicable (no auth surface detected)
- Resources: [anc.dev example](https://anc.dev/auth.md), [Fix skill](https://anc.dev/fix/auth-md)

### N/A — A2A Agent Card published for agent-to-agent discovery

- Tier: MAY
- Goal: Publish an A2A Agent Card for agent-to-agent discovery.
- Result: Not implemented, optional (https://notion.so/.well-known/agent-card.json -> 404 (status 404 not in [200]))
- Resources: [A2A protocol](https://a2a-protocol.org/latest/specification/), [Fix skill](https://anc.dev/fix/a2a-agent-card)

### N/A — /.well-known/ai-catalog.json published (ARD)

- Tier: MAY
- Goal: Publish an Agentic Resource Discovery catalog so agents can enumerate your AI artifacts.
- Result: Not implemented, optional (https://notion.so/.well-known/ai-catalog.json -> 404 (status 404 not in [200]))
- Resources: [AI Catalog](https://agenticresourcediscovery.org/ai_catalog_spec/), [Fix skill](https://anc.dev/fix/ai-catalog)

### N/A — Agent-skills discovery index published

- Tier: MAY
- Goal: Publish an agent-skills discovery index so agents can enumerate your skills.
- Result: Not implemented, optional (https://notion.so/.well-known/agent-skills/index.json -> 404 (status 404 not in [200]))
- Resources: [Agent Skills Discovery](https://github.com/cloudflare/agent-skills-discovery), [Fix skill](https://anc.dev/fix/agent-skills)

## Re-run this audit

Re-audit from [https://anc.dev/audit?lane=web&target=notion.so](https://anc.dev/audit?lane=web&target=notion.so), or call the `audit_website` MCP tool.
