diff --git a/README.md b/README.md
index 7281f99..f0d9296 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,8 @@
-**[letsauth.eu](https://letsauth.eu/)** is an open, vendor-neutral lab for seeing, testing and breaking how AI agents are authorized.
-MCP, A2A and agent delegation meet OAuth, OpenID Connect and workload identity, with a European lens.
+**[letsauth.eu](https://letsauth.eu/)** is an open, vendor-neutral lab for how AI agents are authorized.
+It covers where MCP, A2A and agent delegation meet OAuth, OpenID Connect and workload identity, with EU law in view.
@@ -40,25 +40,23 @@ MCP, A2A and agent delegation meet OAuth, OpenID Connect and workload identity,
## Why this lab exists
Vendors explain agent authorization through their own product. Conformance testers run against one
-server, by its owner, pinned to an older revision of the spec. Nobody shows, over time and for
-everyone, which public MCP servers validate the issuer, bind the audience, or still lean on dynamic
-client registration. Nobody draws WIMSE, AAuth, ID-JAG, A2A and the EU acts on one map.
-
-letsauth measures instead of asserting. It keeps one open dataset of what the agent protocols
-require and what real servers do:
-
-- **Every claim cites a revision.** Each requirement links to the section of the specification
- revision it comes from. When the spec moves, the atlas says what changed and keeps the old
- reading intact.
-- **Every status cites an observation.** A cell is only ever a dated observation with a method and
- evidence a reviewer can open. Nothing is inferred from silence: an empty cell reads *unknown*,
- never failure.
-- **Open, append-only data.** The dataset is YAML in this repository under CC BY 4.0. Observations
- are never edited, so the atlas is also a record of how the ecosystem moved.
-- **Neutral and passive.** Rows are alphabetical, nothing is ranked, and the site contacts no server
- at build time. The scanner reads public metadata only, never with a token.
-- **European by default.** Hosting, storage and analytics run in the EU. eIDAS 2.0, the AI Act and
- NIS2 are first-class content wherever they touch agent delegation.
+server, by its owner, pinned to an older revision of the spec. Nobody shows which public MCP
+servers validate the issuer, bind the audience or still rely on dynamic client registration, for
+all of them and over time. Nobody draws WIMSE, AAuth, ID-JAG, A2A and the EU acts on one map.
+
+letsauth keeps one open dataset of what the agent protocols require and what real servers do:
+
+- **Each requirement cites a revision.** It links to the section of the specification revision it
+ comes from. When the spec changes, the atlas says what changed and keeps the old reading.
+- **Each status cites an observation.** A cell is a dated observation with a method and evidence a
+ reviewer can open. A cell with no observation on record reads *unknown*, and never reads as a
+ failure.
+- **Open, append-only data.** The dataset is YAML in this repository under CC BY 4.0. We never edit
+ an observation, so the atlas also records how servers changed over time.
+- **Neutral and passive.** Rows are in alphabetical order and nothing is ranked. The site build
+ contacts no server. The scanner reads public metadata only and never sends a token.
+- **European.** Hosting, storage and analytics run in the EU. The site covers eIDAS 2.0, the AI
+ Act and NIS2 wherever they touch agent delegation.
## What is live
@@ -82,14 +80,14 @@ the data.
One shared model, many views. Specifications, features, servers, observations and the relations
-between standards live as YAML under [`data/`](data/), validated by a Zod schema at build time and
-changed only through reviewed pull requests. The site is pre-rendered from that data; the scanner
-is the one backend, and its output flows back into the repository as data. The full picture is in
+between standards live as YAML under [`data/`](data/). A Zod schema validates them at build time,
+and they change only through reviewed pull requests. The build pre-renders the site from that
+data. The scanner is the one backend, and its output comes back into the repository as data. The full picture is in
[`docs/architecture.md`](docs/architecture.md).
## Use the data
-Everything the site shows is yours to download under CC BY 4.0:
+You can download everything the site shows, under CC BY 4.0:
```sh
curl -s https://letsauth.eu/mcp/data.json | jq '.servers | length'
@@ -120,5 +118,5 @@ issue.
## Licences
Code is [MIT](LICENSE). Data under `data/` and the JSON exports are
-[CC BY 4.0](LICENSE-DATA). Operated by [Jan Brennenstuhl](https://www.janbrennenstuhl.eu/) in
-Berlin as Let's Auth Labs; see the [imprint](https://letsauth.eu/imprint/).
+[CC BY 4.0](LICENSE-DATA). [Jan Brennenstuhl](https://www.janbrennenstuhl.eu/) runs the site in
+Berlin as Let's Auth Labs. The [imprint](https://letsauth.eu/imprint/) has the details.
diff --git a/docs/data-model.md b/docs/data-model.md
index be00ee6..7bf690d 100644
--- a/docs/data-model.md
+++ b/docs/data-model.md
@@ -61,8 +61,8 @@ Metadata Documents", "RFC 9207 `iss` validation", "Resource indicators (RFC 8707
| `category` | enum | `discovery`, `registration`, `authorization`, `token`, `session`, `transport`, `delegation`, `consent` |
| `description` | string | |
| `supersedes` | string? | Feature id this replaces (e.g. CIMD supersedes DCR as the default) |
-| `observable` | enum | `passive`, `active`, `manual` — how support can be verified |
-| `party` | enum | `mcp-server`, `authorization-server`, `client` — who the requirement is on |
+| `observable` | enum | `passive`, `active`, `manual`: how support can be verified |
+| `party` | enum | `mcp-server`, `authorization-server`, `client`: who the requirement is on |
| | | (`levelNote` lives inside each `revisions` entry) |
### Relation
@@ -91,7 +91,7 @@ A public MCP server (or, later, another agent endpoint) that the MCP Atlas track
| `url` | url | MCP endpoint |
| `homepage` | url? | |
| `transport` | enum | `streamable-http`, `sse`, `stdio-only` |
-| `listed` | enum | `opt-in`, `public-directory`, `maintainer-added` — why it is in the atlas |
+| `listed` | enum | `opt-in`, `public-directory`, `maintainer-added`: why it is in the atlas |
| `source` | url | Where the listing came from; required unless `opt-in` |
| `access` | Classification? | Who can connect: `public` (anyone; where an account is needed, anyone can create one by self-service), `closed` (an existing contract, a tenant an admin must enable, a sales process or a private beta stands in the way; a catalog of approved clients is not an obstacle to the person and stays in the evidence note), `unknown` |
| `auth` | Classification? | How the endpoint authenticates clients: `oauth` (an OAuth 2.x authorization through the server's authorization server), `api-key` (a static credential the user pastes into the client), `none`, `unknown` |
diff --git a/docs/development.md b/docs/development.md
index 7f36f70..be79b6c 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -33,7 +33,7 @@ set.
| `pnpm typecheck` | `astro sync` and `tsc --noEmit`. |
| `pnpm test` | Unit tests (Vitest) over `src/lib` and `src/scanner`. |
| `pnpm test:e2e` | Playwright against `astro preview`; run `pnpm build` first. |
-| `pnpm check:prose [--fail]` | Lists copy in `src/pages`, `src/components`, `README.md` and `docs/*.md` that breaks the mechanical voice rules (banned words, em dash). Warns only until the content pass; `--fail` makes hits fail. |
+| `pnpm check:prose` | Lists copy in `src/pages`, `src/components`, `README.md` and `docs/*.md` that breaks the mechanical voice rules (banned words, em dash) and fails on any hit. |
| `pnpm check:budgets [dir]` | Byte budgets over `dist/` (gzip level 6): CSS, JavaScript, HTML, inline SVG and preloaded fonts per page, plus each island. Run `pnpm build` first. |
| `pnpm check:contrast [--markdown] [--hex]` | WCAG contrast of the colour pairs in `src/styles/tokens.css`, light and dark; fails under 4.5:1 for text and 3:1 for glyphs and outlines. `--markdown` prints the table in `docs/design.md`, `--hex` the sRGB value of each token. |
| `pnpm check` | validate:data, lint, check:prose, check:contrast, typecheck, unit tests, build, check:links, check:budgets. Must pass before a push. |
@@ -58,8 +58,8 @@ set.
`enforce` flag in `LIMITS` at the top of `scripts/check-budgets.ts`, and the package that meets
a target flips it.
- **Prose lint** (`pnpm check:prose`) reports the voice rules a script can check, from section 8
- of the same plan. It prints `file:line: rule: text` and exits 0. Set `FAIL` in
- `scripts/check-prose.ts` to make it a gate.
+ of the same plan. It prints `file:line: rule: text` and fails on any hit, so `pnpm check`
+ fails too. A quotation of a source may use "ecosystem"; nothing else is exempt.
- **Contrast** (`pnpm check:contrast`) recomputes every colour pair in `docs/design.md` from the
OKLCH values in `tokens.css` and fails when one is under its minimum.
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 8776a7c..4734d64 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -13,7 +13,7 @@ features and the review point after each. Each feature gets its own spec under `
| 006 | **Agents under EU rules** | eIDAS 2.0 and EUDI wallet mandates, AI Act oversight, NIS2 duties, as explorer scenarios and long-form pages. | Planned |
| 007 | **Changelog and newsletter** | Generated from merged data and content changes. Runs once there is something to report. | Planned |
| 008 | **Discovery challenge check** | The first nightly run withheld grades for servers that publish no protected resource metadata at a well-known URL (Atlassian, Plaid, Stack Overflow), because the other allowed mechanism, a `resource_metadata` pointer in the 401 `WWW-Authenticate` challenge, needs a request the passive scanner does not make. One unauthenticated request per server to its MCP endpoint, reading only the challenge header, would fill `mcp.prm.www-authenticate` beside `mcp.prm.well-known`, so the atlas shows which mechanism each server offers, or both. It is the first request beyond well-known metadata, so the spec must justify it against the constitution before it runs. | Implemented (pull request open); `specs/008-discovery-challenge/` records why it is still passive |
-| 009 | **Server access and auth classes** | Today the atlas mixes servers anyone can connect to with ones that need an account, tenant or enterprise contract, and OAuth servers with API-key and open ones, using only the directory's unverified `authClaimed` label. Make access (public or closed) and auth (OAuth, API key, none) first-class, evidenced fields; let the atlas group and filter by them; and let the scanner and the grade use them; drop the label. | Implemented; `specs/009-access-auth-classes/` |
+| 009 | **Server access and auth classes** | Today the atlas mixes servers anyone can connect to with ones that need an account, tenant or enterprise contract, and OAuth servers with API-key and open ones, using only the directory's unverified `authClaimed` label. Make access (public or closed) and auth (OAuth, API key, none) evidenced fields of their own; let the atlas group and filter by them; and let the scanner and the grade use them; drop the label. | Implemented; `specs/009-access-auth-classes/` |
| 010 | **Composable discovery strategies** | After the first nightly runs, several requirements stayed `unknown` for every server for the same few reasons: streamable HTTP servers answer the scanner's `GET` with 405 before authenticating, listed `/sse` endpoints had moved, metadata documents name no scopes, and the `scope` parameter the endpoint already sends was not read. Make each check an ordered list of strategies over the sources the probe found, make the endpoint request a ladder, read the scope challenge, and let the run summary flag stale URLs. | Implemented; `specs/010-discovery-strategies/` |
| 016 | **Visual redesign** | The site works but looks generated: boxes, shadows, glow, a slogan hero. Move it to one calm system shared with the maintainer's blog (flat surfaces, hairlines, two brand accents, Geist), with motion only where it explains a state, tighter byte and Lighthouse budgets, and a copy pass. No change to data, schema or URLs. | Planned; `specs/016-visual-redesign/plan.md` |
diff --git a/scripts/check-prose.ts b/scripts/check-prose.ts
index 288200c..5ebdee0 100644
--- a/scripts/check-prose.ts
+++ b/scripts/check-prose.ts
@@ -2,8 +2,8 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join, relative } from "node:path";
// Mechanical rules from the voice checklist (specs/016-visual-redesign/plan.md section 8, rule 4).
-// Warn-only until WP9 rewrites the copy: then set FAIL to true (or pass --fail meanwhile).
-const FAIL = false;
+// A gate since WP9 rewrote the copy: any hit fails `pnpm check`.
+const FAIL = true;
const root = process.cwd();
const fail = FAIL || process.argv.includes("--fail");
@@ -20,6 +20,8 @@ const WORDS = [
"cutting-edge",
"next level",
"game-changing",
+ "game-changer",
+ "holistic",
"in the era of",
"in the age of",
"measured instead of asserted",
@@ -114,5 +116,5 @@ if (hits.length) {
for (const [name, count] of [...perFile].sort((a, b) => b[1] - a[1]))
log(` ${String(count).padStart(4)} ${name}`);
if (fail) process.exitCode = 1;
- else console.log("(warn only; WP9 switches this check to fail)");
+ else console.log("(warn only)");
} else console.log(`Prose OK: ${files.length} files`);
diff --git a/specs/016-visual-redesign/tasks.md b/specs/016-visual-redesign/tasks.md
index 61eb851..2d5b980 100644
--- a/specs/016-visual-redesign/tasks.md
+++ b/specs/016-visual-redesign/tasks.md
@@ -157,6 +157,21 @@ reveal, the token rail and the toggle rails; breach pages on `.rows`, `.panel` a
- [x] W6-T13 Breach layout rework after review: the entry page puts the account (summary after its first sentence, the missing control, the replay as a rail in the toggle's ink) at reading width beside a sticky facts panel (timeline, affects, sources as short labels); the index is a ledger with the date, class and id in a narrow column beside each entry and its missing control and replay as labelled lines
- [x] W6-T12 Screenshot baselines for `explorer.spec.ts` and `breaches.spec.ts`: refreshed through the `refresh-screenshots` label on the pull request
+## WP9: Content pass
+
+The copy that WP3 to WP7 did not rewrite, against plan section 8 and the Plain English layer of
+the review (sentences under 20 words on average and none over 30, active voice with a named
+actor, "you" and "we", no em dashes or semicolons in body copy, no triads, no "X, not Y").
+Taken as review follow-up 9. Legal content keeps its substance; only the wording changes.
+
+- [x] W9-T01 Section-root h1 under 24 characters: `/mcp/` (and the revision pages, which share `MatrixPage.astro`), `/standards/`, `/explorer/`, `/breaches/`, `/mcp/scanner/`; the lede carries what the old headline said
+- [x] W9-T02 `src/layouts/Base.astro`: the home `
Servers
-
The public MCP servers we list, against what the MCP Authorization specification requires
of servers and their authorization servers. Each cell opens the observation behind it.
@@ -266,10 +266,6 @@ const classWords = (counts: { value: string; count: number }[], label: Record Breach anatomy
Each entry is a vulnerability or incident written from its advisory, with the control
that was missing and the MCP auth atlas requirements that stand for it. Where the
diff --git a/src/pages/contribute.astro b/src/pages/contribute.astro
index 91d3faa..11fafc9 100644
--- a/src/pages/contribute.astro
+++ b/src/pages/contribute.astro
@@ -21,11 +21,11 @@ const entry = `- server: stripe # must equal the file's serv
@@ -37,10 +37,10 @@ const entry = `- server: stripe # must equal the file's serv
Path A
- The quickest route. The form asks for the same fields as a data entry: server, feature,
- revision, status, method, date, evidence and your handle. A maintainer turns an accepted
- issue into a pull request and links the issue as evidence where the issue itself is the
- evidence.
+ This is the quickest route. The form asks for the same fields as a data entry: server,
+ feature, revision, status, method, date, evidence and your handle. A maintainer turns an
+ accepted issue into a pull request. When the issue itself is the evidence, the entry
+ links to it.
Path B
- Append an entry to the server's observation file yourself. Validation runs locally and
- again in CI, so a reviewer only has to open the evidence. The steps are below.
+ You append an entry to the server's observation file yourself. The checks run on your
+ machine and again in CI, so a reviewer only has to open the evidence. The steps are
+ below.
- Evidence is a URL a reviewer can open (a metadata document, a
- documentation page, a response capture) or a precise note. Method says
- how you know:
+ When a cell has two observations, the atlas shows the newest. If both have the same time,
+ the stronger method wins: active-scan, then passive-scan, then manual, then vendor-claim.
- For the {scannerChecks} requirements the passive scanner can read
- from public metadata, prefer Observations are never edited or removed
- A correction is a new entry with a newer
- Add
- If you maintain a server and do not want it listed, use the issue form with
- "withdraw my server" and a way to verify that you maintain it. A pull request then sets
-
- Data you contribute is published under CC BY 4.0;
- the site's code is MIT.
+ Data you contribute is published under CC BY 4.0.
+ The site's code is MIT.
letsauth is a personal project. I, {OPERATOR.name}, build it in my own time to make agent
- authentication easier to understand, and everything here reflects my own views and my
- experience in usable security and web authentication. I do not speak for the company I work
+ authentication easier to understand. Everything here reflects my own views and my experience
+ in usable security and web authentication. I do not speak for the company I work
for, or for any company I worked for in the past, and nothing on this site is an official
position of any of them.
- The atlases are compiled with care from specifications, vendor documentation, public
+ We compile the atlases with care from specifications, vendor documentation, public
directories and passive reads of public metadata. Each cell shows its source, method and
- date. Products change and observations age, so a cell can be out of date or wrong, and an{" "}
- unknown cell says only that nothing has been observed. The site is not a security
- audit, a certification or a compliance statement for any product, and it does not replace
- your own assessment. Please send a correction when you
+ date. Products change and observations age, so a cell can be out of date or wrong. An{" "}
+ unknown cell says only that no observation is on record. The site is not a security
+ audit, a certification or a compliance statement for any product. It does not replace your
+ own assessment. Please send a correction when you
find a mistake.
The content is provided as is, without warranty. Liability for its accuracy, completeness
- or timeliness is excluded as far as the law permits; liability for intent and gross
- negligence, and for injury to life, body or health, is unaffected.
+ or timeliness is excluded as far as the law permits. This does not affect liability for
+ intent and gross negligence, or for injury to life, body or health.
The site links to specifications, vendor pages and repositories run by others. Their
owners are responsible for them. When a link was added, the target showed no apparent
- breach of law; we do not monitor linked pages continuously. If you notice a link to unlawful
+ breach of law. We do not monitor linked pages continuously. If you notice a link to unlawful
content, tell us and we will remove it.
Delegation chain explorer
Each scenario is a chain of requests between a user, agents, MCP servers and
authorization servers, written from the specification sections it cites. Every step
diff --git a/src/pages/imprint.astro b/src/pages/imprint.astro
index 0d12fd9..5aedb8f 100644
--- a/src/pages/imprint.astro
+++ b/src/pages/imprint.astro
@@ -10,7 +10,7 @@ import { LAB, OPERATOR, REPO } from "@/lib/site";
path="/imprint/"
eyebrow="Legal"
lede={`letsauth.eu is published by ${LAB}, an independent project run by one person in Berlin.`}
- updated="2026-10-14"
+ updated="2026-10-22"
>
Information under § 5 of the German Digital Services Act (DDG).
For corrections to the atlas data, the quickest route is an issue or a pull request in the{" "}
- public repository; see how
- to contribute. To report a security problem with this site, follow the{" "}
+ public repository. The contribute
+ page explains how. To report a security problem with this site, follow the{" "}
security.txt instructions.
- How this site handles data is in the privacy note. What the site is
- and is not, and the limits of liability, are in the disclaimer.
+ The privacy note says how this site handles data. The{" "}
+ disclaimer says what the site is and the limits of liability.
- This lab studies who gets to act on whose behalf. Where your data goes, and under which law,
- is part of the same question. European rules (the GDPR, eIDAS 2.0 and the EUDI wallet, the
- AI Act, NIS2) shape how agents may be delegated authority, so the site that writes about them
- keeps to them too: no cookies that need consent, visitor data handled only by EU companies,
- and no third-party scripts beyond EU analytics.
+ This lab studies who may act on whose behalf. Where your data goes, and under which law, is
+ part of the same question. European rules shape how agents may receive authority: the GDPR,
+ eIDAS 2.0 and the EUDI wallet, the AI Act and NIS2. A site that writes about them should keep
+ to them. So the site sets no cookies that need consent, and only EU companies handle visitor
+ data. The only third-party script is the EU analytics.
- The code, the data and the automated checks live on GitHub, a US company, because that is where open-source
- contributors already are and where a pull request can be reviewed in public. Visitors to
- letsauth.eu never touch it: no script, font or image on the site is loaded from GitHub. If
- you contribute, GitHub's terms apply to what you do there; the{" "}
+ The code, the data and the automated checks live on GitHub, a US company. We use it because
+ open-source contributors are already there and a pull request can be reviewed in public.
+ Visitors to letsauth.eu never touch it, because the site loads no script, font or image from
+ GitHub. If you contribute, GitHub's terms apply to what you do there, and the{" "}
privacy note has the details. The whole history is in git, so the
project can move to a European forge without losing anything.
- Open your browser's network panel on any page: every request goes to letsauth.eu. Even the
- analytics count is sent there and forwarded to Plausible by the CDN. The deployment and hosting setup is documented in the{" "}
- repository.
+ Open your browser's network panel on any page. Every request goes to letsauth.eu, even the
+ analytics count, which the CDN forwards to Plausible. The{" "}
+ deployment guide in the
+ repository documents the hosting setup.
Scanner
- The scanner reads the public authorization metadata an MCP server publishes for every
- client and judges the {checks.length} requirements of MCP Authorization {revision.id} that
- metadata can answer. Nothing else is sent: no token, no authorization flow, no protocol
- message; the one request to the endpoint itself carries no credentials and only its
- status and headers are read. Results land in the atlas as observations, by pull request.
+ Every night the scanner reads the public authorization metadata of each listed MCP server
+ and judges the {checks.length} requirements of MCP Authorization {revision.id} that this
+ metadata can answer. It sends no token and no credentials, and starts no authorization
+ flow. Its results reach the atlas as observations, by pull request.
- The site is a set of static files served by Bunny.net (BunnyWay d.o.o., Ljubljana,
- Slovenia) from a storage zone in the EU. To deliver a page, its servers necessarily process
- your IP address, the requested address, the time, and the browser identification your
- browser sends. Bunny.net processes this on our behalf under a data processing agreement and
+ Bunny.net (BunnyWay d.o.o., Ljubljana, Slovenia) serves the site as static files from a
+ storage zone in the EU. To deliver a page, its servers must process your IP address, the
+ requested address, the time and the browser identification your browser sends. Bunny.net processes this on our behalf under a data processing agreement and
may keep it in short-lived technical logs for security and operation. We do not use it to
identify or profile visitors.
We count visits with Plausible
- Analytics (Plausible Insights OÜ, Tartu, Estonia), which is built to work without
- cookies or personal data and stores its data in the EU. It records, per page view:
+ Analytics (Plausible Insights OÜ, Tartu, Estonia). It works without cookies or personal
+ data and stores its data in the EU. For each page view it records:
To count unique visitors per day without a cookie, Plausible combines the IP address and
browser identification with a salt that changes every 24 hours and keeps only the resulting
- hash; the salt is deleted, so a visitor cannot be recognised the next day or across sites.
+ hash. The salt is then deleted, so nobody can recognise a visitor the next day or across
+ sites.
IP addresses are never stored. The statistics are aggregate and nobody can trace them back
to you.
Pages read fully without JavaScript; nothing else is stored. Pages read fully without JavaScript. Nothing else is stored.
- letsauth does not scan anything on a visitor's request, and there is no form that triggers a
- scan. A scheduled job on the project's own backend (Scaleway, EU region) reads, once a night, the
- public metadata of the MCP
- servers listed in the atlas (the documents a server publishes for any client to read), with
- no credentials and without starting any authorization flow. Its findings are published as
- data in the public repository. This job processes
- technical data about services, not personal data about visitors. Server maintainers can ask
- for their server to be withdrawn; see how to contribute.
+ letsauth scans nothing on a visitor's request, and no form can start a scan. Once a night, a
+ scheduled job on the project's own backend (Scaleway, EU region) reads the public metadata of
+ the MCP servers listed in the atlas. These are the documents a server publishes for any
+ client to read. The job uses no credentials and starts no authorization flow. Its findings
+ are published as data in the public repository. The job
+ processes technical data about services and no personal data about visitors. Server
+ maintainers can ask for their server to be withdrawn, as the
+ contribute page describes.
- Corrections and new data go through issues and pull requests on GitHub (GitHub, Inc., USA).
+ Corrections and new data arrive as issues and pull requests on GitHub (GitHub, Inc., USA).
When you contribute there, GitHub's{" "}
privacy statement{" "}
applies. The handle you give in an observation ( Links to GitHub and to specification publishers are plain links; nothing is loaded from them until you follow one. Links to GitHub and to specification publishers are plain links. Nothing loads from them until you follow one.
@@ -125,10 +125,10 @@ import { LAB, OPERATOR, REPO } from "@/lib/site";
Under the GDPR you have the right to:
Write to {OPERATOR.email}. You can also complain
diff --git a/tests/e2e/__screenshots__/breaches.spec.ts/breaches-phone.png b/tests/e2e/__screenshots__/breaches.spec.ts/breaches-phone.png
index 02d8130..edbd048 100644
Binary files a/tests/e2e/__screenshots__/breaches.spec.ts/breaches-phone.png and b/tests/e2e/__screenshots__/breaches.spec.ts/breaches-phone.png differ
diff --git a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-dark.png b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-dark.png
index 7ecaaea..80de5c3 100644
Binary files a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-dark.png and b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-dark.png differ
diff --git a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-light.png b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-light.png
index 53d56b9..0a5c935 100644
Binary files a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-light.png and b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-light.png differ
diff --git a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-phone.png b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-phone.png
index 34a0c90..61e9976 100644
Binary files a/tests/e2e/__screenshots__/explorer.spec.ts/explorer-phone.png and b/tests/e2e/__screenshots__/explorer.spec.ts/explorer-phone.png differ
diff --git a/tests/e2e/__screenshots__/matrix.spec.ts/matrix-phone.png b/tests/e2e/__screenshots__/matrix.spec.ts/matrix-phone.png
index 9dd84a9..929e81e 100644
Binary files a/tests/e2e/__screenshots__/matrix.spec.ts/matrix-phone.png and b/tests/e2e/__screenshots__/matrix.spec.ts/matrix-phone.png differ
diff --git a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-dark.png b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-dark.png
index 2b44ae3..78856e1 100644
Binary files a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-dark.png and b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-dark.png differ
diff --git a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-light.png b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-light.png
index 1473e37..444d505 100644
Binary files a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-light.png and b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-light.png differ
diff --git a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-phone.png b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-phone.png
index 6619ab2..81c371f 100644
Binary files a/tests/e2e/__screenshots__/scanner.spec.ts/scanner-phone.png and b/tests/e2e/__screenshots__/scanner.spec.ts/scanner-phone.png differ
Published failures in how agents were authorized
+ Agent auth failures
Two ways in
Open an issue
Open a pull request
Entry format
{entry}manual for something you checked by hand,
- vendor-claim for what the vendor says, passive-scan for reading
- public metadata, active-scan for sending requests. When two observations of a
- cell exist, the newest one is shown; equal timestamps are broken by method strength
- (active-scan over passive-scan over manual over vendor-claim).
+ Evidence is a URL a reviewer can open, such as a metadata document, a
+ documentation page or a response capture. A precise note works too.
+ Method says how you know. Use manual for something you checked
+ by hand, vendor-claim for what the vendor says, passive-scan for
+ reading public metadata and active-scan for sending requests.
+ Let the scanner write it
pnpm scan <server-id> --write over a hand-written
- entry. It appends exactly the observations whose status or evidence changed, with evidence
- anyone can reproduce by running the same command. The nightly run does the same for every
+ The passive scanner can read {scannerChecks} requirements from
+ public metadata. For those, run pnpm scan <server-id> --write instead of
+ writing the entry by hand. It appends only the observations whose status or evidence changed,
+ and anyone can repeat the same command to check them. The nightly run does this for every
listed server and opens its own pull request.
observedAt; the old one stays in the
+ A correction is a new entry with a newer observedAt. The old one stays in the
history on the server page. CI fails any pull request that changes or deletes an existing
entry.
Listing a server
data/servers/<id>.yaml with the endpoint, transport and
- listed. If you maintain the server, use listed: opt-in; otherwise
- give the source that lists it publicly. Servers are listed as they appear in
- public directories; nobody is scored or ranked.
+ Add data/servers/<id>.yaml with the endpoint, the transport and
+ listed. If you maintain the server, use listed: opt-in. If not,
+ give the source that lists it publicly. We list servers as they appear in public
+ directories, and we score or rank nobody.
Withdrawing a server
withdrawn on the server. It leaves the matrix and the export; its observations
- stay in the repository history.
+ If you maintain a server and do not want it listed, use the issue form. Choose "withdraw my
+ server" and give us a way to check that you maintain it. A pull request then sets
+ withdrawn on the server. It leaves the matrix and the export, and its
+ observations stay in the repository history.
Licences
No employer affiliation
Reference material, not advice
Liability
External links
How authority moves from a person through agents to an API
+ Delegation chains
Provider
More
Why it matters here
What the site runs on
@@ -88,19 +88,20 @@ const stack: { what: string; who: string; note: string; where: keyof typeof WHER
The exception
Check it yourself
What a server's metadata says, measured every night
+ The nightly scanner
In short
@@ -39,10 +39,9 @@ import { LAB, OPERATOR, REPO } from "@/lib/site";
Hosting and delivery
Analytics
Scanning of MCP servers
Contributions and GitHub
observedBy) becomes part of the
public dataset under CC BY 4.0, which requires attribution. If you want it removed, write to
- us and we will act on your request under Art. 17 GDPR; copies in the public history of the
- repository or made by others may remain.
+ us and we will act on your request under Art. 17 GDPR. Copies in the public history of the
+ repository, or copies others made, may remain.
Email
Your rights
-