The web is gaining an agent-facing interface layer
Web pages already serve humans, search engines, screen readers, APIs, and automation scripts. AI agents add a new consumer with two distinct needs: a compact representation it can read and a bounded action surface it can call. Combining those needs into “make the site agent-friendly” hides the engineering decisions that matter.
On August 26, 2026, WebMCP was published as a dated Draft Community Group Report by the W3C Web Machine Learning Community Group. Its abstract is narrow: web applications can provide JavaScript-based tools to AI agents. The official repository showed roughly 3.4 thousand stars and 111 open issues during the August 27 scan. Chrome documents an origin trial in Chrome 149, not universal browser support. That status supports prototyping and evaluation, not a claim that the API is settled.
The same day, a Hacker News discussion about serving Markdown with the HTTP Accept header reached 164 points and 95 comments; a WebMCP implementation discussion drew 55 points and 55 comments. The pairing is useful because it exposes a common category error. Accept: text/markdown changes the representation returned by a URL. WebMCP changes the actions a page advertises to an agent. One is primarily a retrieval contract. The other is an execution contract.
A current practitioner report also shows why the apparently simple read path is operational work: a CDN ignored or failed to key correctly on Vary: Accept, and human visitors received raw Markdown. On the action path, Chrome's own security guidance warns about malicious tool definitions and contaminated tool outputs. The hard parts are not the syntax of Markdown or JSON Schema. They are cache identity, authority, untrusted data, observable consequences, and backward compatibility.
September 1 update: the read path now has a concrete software-supply-chain case. Answer.AI's August 10 revision of the llms.txt proposal explicitly describes agent use, path-scoped manifests, Markdown page alternatives, and heavy use in software documentation. On August 26, security researcher Alon Hertz reported that agents followed install guidance found in first-party agent-facing files and executed packages whose names had not been claimed by the vendors. The format did not grant that authority; the runtime inferred it.
Agent-readable does not mean agent-authorized. Representation, capability, authority, and evidence are four different contracts.
Treat agent-facing documentation as a software supply-chain input
The safest interpretation of llms.txt is a map. It helps an agent find relevant material. It is not a signature over every command, package, domain, or side effect that appears behind those links. An official HTTPS origin can authenticate where text came from while saying nothing about who controls a package name in a public registry.
Hertz's first-party report attributes the following measurements to the research team: 8,565 llms.txt files resolved across 6,214 live domains from roughly 15,000 catalogued companies, with more than 237 unclaimed package names, domains, and subdomains referenced in install or setup instructions. The team says it registered a small controlled set on PyPI and npm with inert callback beacons. Its first callback arrived in under four minutes, followed by additional enterprise callbacks. Those are researcher-reported observations, not an independently reproduced census, so the useful engineering response is to test the mechanism rather than repeat the numbers as universal prevalence.
The mechanism is credible because ordinary package resolution creates the handoff. Documentation may say pip install vendor-sdk or show a bare npx tool-name. The agent sees first-party text, the package manager sees a syntactically valid public name, the network proxy sees an approved registry, and endpoint monitoring sees the organization's chosen coding agent as the parent process. Each local signal can look normal while the composition is wrong.
The report also documents a live failure pattern involving a bare command that was intended to come from a vendor's scoped package but could resolve against a separately registered public npm name when invoked before local installation. The vendor responded and addressed the issue after disclosure. The lesson is not that scoped packages or npx are inherently unsafe. It is that command resolution must be made explicit and tested from a clean environment.
| Statement | What it proves | What it does not prove |
| The text came from the vendor's HTTPS site | Origin and transport for that response | Control of a same-named registry package or external domain |
| The package name exists | A registry accepted that namespace | The package belongs to the documented vendor |
| The package has provenance | A verifiable source/build/publisher relationship | That source code is benign or appropriate for this task |
| The command succeeded in a sandbox | It executed under one bounded fixture | That it is safe with secrets, broader egress, or production data |
| A person clicked approve | The prompt was acknowledged | That package ownership, version, digest, or consequences were independently checked |
Convert prose into a candidate action, never a direct command
1. DiscoverRead the manifest or page and retain origin URL, response digest, fetch time, and link chain.
2. NormalizeParse the proposed registry, namespace, package, version, command, arguments, and requested network access.
3. ResolveLook up ownership, repository, release metadata, provenance, signatures, age, and immutable artifact digest.
4. DecideApply organization policy outside the model; block unresolved names and require explicit exceptions.
5. ExecuteInstall the pinned artifact in a disposable sandbox with no ambient secrets and minimal egress.
6. PromoteRecord tests, files, processes, network calls, receipt, reviewer, and the exact lockfile change.
This flow deliberately breaks the transitive trust chain. The agent may use prose to propose a dependency. A deterministic resolver decides what that dependency means. A policy engine decides whether the resolved artifact is eligible. A sandbox measures behavior. A reviewer sees the resolved identity and consequences, not merely the original command string.
install_policy:
default: deny
allowed_registries: [npmjs.org, pypi.org]
require:
exact_version: true
artifact_digest: true
repository_match: true
provenance_or_exception: true
clean_install_fixture: true
deny_if:
- package_age_hours < 168
- owner_unresolved
- documentation_name_mismatch
- lifecycle_scripts_unreviewed
- install_requires_ambient_credentials
sandbox:
secrets: none
filesystem: ephemeral
egress: [registry, source_repository]
promotion:
human_review: required
lockfile_diff: required
receipt: required
function authorizeDocumentedInstall(reference, pageEvidence) {
const candidate = normalizePackageReference(reference);
const artifact = registry.resolve(candidate.name, candidate.version);
assert(pageEvidence.originAllowed);
assert(candidate.version !== "latest");
assert(artifact.digest && artifact.repository);
assert(repositoryMatchesDocumentedOwner(artifact, pageEvidence));
assert(provenanceVerified(artifact) || approvedException(artifact));
assert(policyAllows(candidate, artifact));
return sandbox.installAndObserve({artifact, network: "restricted", secrets: []});
}
Publishers and consumers own different halves of the control
A documentation publisher should inventory every executable reference generated into llms.txt, llms-full.txt, Markdown mirrors, README files, and examples. Resolve each package and domain from a clean environment. Prefer namespaced packages, explicit versions, and commands that identify the intended package rather than relying on a globally resolvable binary name. Link the source repository and explain which organization publishes the artifact. Fail the documentation build when an external executable reference becomes unclaimed, redirected, archived, or inconsistent with the human page.
An agent host cannot outsource the other half to the publisher. It needs registry policy, immutable resolution, provenance and ownership checks, install-script inspection, network restrictions, secret isolation, consequence-based approval, and read-after-install verification. npm's provenance documentation is precise about the boundary: provenance provides a verifiable link to source and build instructions; it does not guarantee that a package contains no malicious code. Provenance is evidence for a decision, not the decision itself.
For npm, trusted publishing can bind release rights to a specific CI workflow through OIDC and can generate provenance automatically for eligible public packages. npm also documents staged publishing and npm audit signatures. These controls raise the cost of impersonating an established package, but they do not rescue an unclaimed name referenced by documentation. The consumer must reject the first-use namespace until ownership has been established through an independent channel.
Audit the whole instruction graph
Removing one llms.txt file would not close the class. Agents read documentation pages, Markdown alternates, README files, GitHub issues, support tickets, email, and community answers. Build an instruction graph that records where a proposed command came from and every link transition used to reach it. Flag transitions from a first-party origin to a public registry, URL shortener, personal gist, package post-install script, or newly claimed hosting subdomain. The control question is always the same: what new authority did the runtime infer at this edge?
The useful metric is not how many manifests were published. Track executable references inventoried, unresolved references blocked, artifacts pinned, provenance checks passed, install scripts reviewed, sandbox policy violations, documentation drift, and exceptions awaiting owners. A read interface becomes safer when its consumers can explain why each executable edge was accepted.
Separate representation from capability
| Plane | Question answered | Primary mechanism | Main failure |
| Human interface | What can a person see and do? | Semantic HTML, forms, accessibility | Unusable or inaccessible UI |
| Agent representation | What content should the agent read? | HTTP negotiation, Markdown alternate | Wrong variant, stale content, lost semantics |
| Agent capability | Which page actions can the agent request? | WebMCP tools and schemas | Wrong tool, invalid arguments, hidden side effects |
| Authority and evidence | May this exact action happen, and how is it proven? | Server policy, confirmation, receipt | Authorized session becomes overbroad agent power |
Do not replace the human interface with the agent interface. Semantic HTML, labels, native controls, keyboard behavior, and accessibility remain the stable baseline and the broadest fallback. An agent may use the rendered UI when WebMCP is absent. A person may need to inspect or take over a run. The two interfaces should describe the same underlying business state without sharing every implementation detail.
Do not expose a write tool merely because the human page has a button. A button may sit behind context a human understands: current account, selected invoice, warning text, permissions, transaction limits, and an irreversible-action dialog. A WebMCP tool must encode or re-check those conditions. Converting the button label into a tool description discards the control environment around it.
Use HTTP negotiation as a correctness feature, not an SEO trick
RFC 7763 registers text/markdown. RFC 9110 defines the Accept request field, quality values, response selection, and Vary. An agent can prefer Markdown while retaining HTML as a fallback:
GET /guides/refunds HTTP/1.1
Host: docs.example.com
Accept: text/markdown, text/html;q=0.8, */*;q=0.1
HTTP/1.1 200 OK
Content-Type: text/markdown; charset=utf-8
Vary: Accept
Link: <https://docs.example.com/guides/refunds>; rel="canonical"
The canonical resource should remain one URL unless the publishing system has a strong reason to expose an explicit .md alternate. A Markdown variant must carry the same factual content, dates, authorship, links, and policy warnings as the HTML page. It may omit navigation, decoration, scripts, and repeated interface chrome. It must not silently omit qualifications or expose text hidden from human users.
Parsing Accept with a substring check is fragile. Respect q-values, explicit refusal such as text/markdown;q=0, and a default HTML representation. Return 406 Not Acceptable only when the server truly cannot supply any requested type. Most public pages should fall back to HTML for broad clients.
function selectRepresentation(acceptHeader) {
const choices = parseAccept(acceptHeader ?? "*/*");
if (quality(choices, "text/markdown") > quality(choices, "text/html")) {
return {type: "text/markdown", variant: "markdown"};
}
if (allows(choices, "text/html") || allows(choices, "*/*")) {
return {type: "text/html", variant: "html"};
}
return {status: 406};
}
Test at the edge, not only at the origin. Vary: Accept tells compliant caches that variants differ, but real CDN products may normalize, ignore, or incompletely key on high-cardinality headers. Use an explicit cache-key rule, separate cache buckets, or bypass caching for the Markdown response until production behavior is proven.
curl -sSI -H 'Accept: text/html' https://example.com/guide
curl -sSI -H 'Accept: text/markdown' https://example.com/guide
curl -sS -H 'Accept: text/markdown' https://example.com/guide | head
# Repeat in both orders against a warm edge cache.
# Confirm Content-Type, Vary, cache status, canonical identity, and body markers.
Measure your own pages. Byte count and token count can fall sharply when navigation and scripts disappear, but there is no universal reduction. Record HTML bytes, Markdown bytes, extracted text parity, link parity, heading parity, fetch latency, and task-answer accuracy. Do not publish a token-savings claim copied from another site's layout.
WebMCP turns page functionality into typed tools
WebMCP's imperative API lets a page register a named tool with a description, an input schema, annotations, and an execute function. Chrome also documents a declarative route based on forms. The imperative shape is useful when the action is backed by application state or an API:
document.modelContext.registerTool({
name: "draftRefundRequest",
title: "Draft a refund request",
description: "Create a reviewable draft for one settled charge. Does not issue money.",
inputSchema: {
type: "object",
properties: {
chargeId: {type: "string"},
reason: {type: "string", maxLength: 500}
},
required: ["chargeId", "reason"],
additionalProperties: false
},
annotations: {readOnlyHint: false},
execute: async ({chargeId, reason}) => {
return api.createRefundDraft({chargeId, reason});
}
});
The useful detail is in the verb: draft. A tool that creates a reviewable object has a smaller consequence surface than one that transfers money. The server must still authenticate the user, authorize the charge, validate state and amount, enforce rate and policy limits, and bind the result to an idempotency key. Tool annotations help selection; they are not enforcement.
Descriptions are untrusted input to the agent. Chrome warns that a malicious site can hide instructions in tool names, parameters, or descriptions, and that a legitimate tool can return third-party content containing indirect prompt injection. The agent host should treat the page as a principal making capability claims, not as a trusted system prompt.
Keep tool results structured and minimal. Return business data, stable identifiers, next allowed states, user-visible messages, and a receipt reference. Do not return a wall of prose that mixes instructions with user-generated content. When untrusted text must be returned, label it as data and keep it out of control fields.
A production design uses four independent gates
1. Representation gatewaySelect HTML or Markdown, preserve canonical identity, and key caches correctly.
2. Capability registryExpose only page-relevant tools with exact names, schemas, versions, and consequence classes.
3. Policy runtimeRe-check user identity, tenant, object state, data class, side effect, amount, and approval outside the model.
4. Evidence ledgerRecord tool version, arguments digest, policy decision, result, confirmation, and user-visible outcome.
The representation gateway can ship without WebMCP. It is useful for documentation, policies, product pages, and public reference material. WebMCP can ship on a rich application that has no Markdown representation. Treating the deployments independently reduces blast radius and makes adoption observable.
Capability availability should follow current page and session state. A logged-out pricing page should not advertise an account mutation. An authenticated admin page may expose tools that a standard user never sees. Still, client-side hiding is not authorization: the server is the final decision point.
Design a human handoff. The user must be able to inspect a proposed action, edit inputs, reject it, or continue manually. Preserve the visible page state that explains the action. An agent receipt without a corresponding user-visible state creates a debugging artifact, not accountability.
Assume page content and tool output can be hostile
| Threat | Example | Boundary |
| Malicious manifest | A description tells the model to ignore user intent | Host sanitization, allowlist, policy outside prompt |
| Contaminated output | A support ticket contains instructions aimed at the agent | Typed data fields, taint labels, no instruction promotion |
| Session-riding | An extension invokes a write in the logged-in user's session | Origin/host permission, server authorization, confirmation |
| Semantic collision | cancelOrder is chosen instead of cancelDraft | Exact names, negative examples, selection evals |
| Replay or retry | A timeout causes the same purchase twice | Idempotency key, consequence lookup, retry ownership |
| Cross-variant leak | Private or raw content appears only in Markdown | Parity tests, access control before rendering |
| Documentation-to-package confusion | First-party text names an unclaimed or differently resolved artifact | Ownership resolution, version/digest pin, policy, sandbox |
Recent WebMCP-Phalanx research is a reminder that browser-integrated tools create a security boundary worth measuring. A draft paper is not final consensus, but it asks the right engineering question: can enforcement be characterized outside probabilistic model behavior? Use deterministic controls for permissions, parameter limits, transaction state, and user confirmation. Model judgment can propose; it should not certify.
Keep reads bounded too. A Markdown variant can accidentally aggregate text that the human page loads only after an entitlement check. Generate the variant after authentication and authorization, not from a privileged build artifact served to every agent user agent.
Evaluate reading, choosing, executing, and recovering
Chrome's WebMCP evaluation guidance separates whether an agent understands when to call a tool, executes it correctly, and returns an acceptable answer. Extend that idea across both interface planes.
| Stage | Fixture | Release metric |
| Representation | HTML/Markdown pairs, q-values, warm-cache order | Correct variant, factual parity, no cross-variant leak |
| Discovery | Relevant, irrelevant, and absent tools by page state | Eligible-tool recall and forbidden-tool exposure |
| Selection | Near-duplicate tools and explicit no-tool cases | Correct choice and safe abstention rate |
| Arguments | Missing, malformed, oversized, and adversarial fields | Schema validity and server rejection accuracy |
| Consequence | Timeout, retry, stale state, concurrent change | Exactly-once effect or verified no effect |
| Handoff | Cancellation, user correction, manual continuation | State preserved and named owner assigned |
Repeat probabilistic runs and pin browser, agent, model, page, tool, and policy versions. A tool that succeeds nine times and selects a dangerous neighbor once is not a 90 percent success story. It is a severity problem. Weight failures by consequence and inspect traces.
Failure modes that demos rarely show
| Failure | Why it happens | Fix |
| Markdown leaks to browsers | Edge cache ignores or miskeys Vary | Explicit cache key, separate bucket, two-order probe |
| HTML and Markdown disagree | Two publishing pipelines drift | One content source and automated parity checks |
| Tool exists only in a demo browser | Origin trial mistaken for universal support | Feature detection and conventional UI/API fallback |
| Agent calls the fluent description | Metadata optimized for persuasion, not distinction | Exact boundaries, negative examples, collision evals |
| Confirmation becomes ceremonial | User cannot inspect the actual consequence | Show object, amount, delta, policy result, and rollback |
| Success without receipt | Tool returned prose but state is unknown | Read-after-write verification and durable receipt |
| Official docs install the wrong artifact | HTTPS origin trust is transferred to an unrelated registry namespace | Independent ownership check and deny unresolved names |
| Bare binary resolves from the public registry | Clean environment lacks the intended local scoped package | Install/pin the package first and invoke its exact local binary |
| Provenance becomes a safety badge | Origin evidence is mistaken for code review | Inspect behavior, sandbox, and apply task policy |
Roll out the read plane before the write plane
- Choose five high-value public pages. Produce Markdown and
llms.txt from the same source as HTML and define required parity fields.
- Inventory every package, command, domain, subdomain, and executable example. Resolve it from a clean environment and assign an owner.
- Implement standards-aware negotiation. Test q-values, fallbacks, 406 behavior,
Content-Type, Vary, canonical links, and authentication.
- Warm the CDN in both request orders. Verify the correct variant from multiple regions and record cache keys or bypass rules.
- Measure bytes, extraction accuracy, link preservation, answer quality, latency, and unsupported-client behavior. Publish no universal token claim.
- Select one reversible application task for WebMCP. Prefer a read or a reviewable draft over an irreversible write.
- Define the tool name, schema, negative boundaries, consequence class, server-side policy, idempotency, timeout, and receipt before registering it.
- Build fixtures for correct use, abstention, collision, injection, stale state, retries, cancellation, and human continuation.
- Run the origin-trial implementation behind a feature flag. Preserve semantic HTML and the conventional API as fallbacks.
- Require the consumer runtime to pin package versions and digests, verify ownership/provenance, deny unresolved names, and install without ambient secrets.
- Review traces weekly. Promote additional tools only after accepted-task evidence and zero unresolved high-severity failures.
Frequently asked questions
Is WebMCP a W3C standard?
It is a W3C Community Group Draft dated August 26, 2026, not a W3C Recommendation. Chrome 149 provides an origin trial. Use feature detection, pin the draft version you test, and retain fallbacks.
Does Accept: text/markdown replace WebMCP?
No. Markdown is a representation for reading. WebMCP describes callable page functionality. A documentation site may need only Markdown; a transactional app may need tools; many sites need both.
Does Markdown improve AI citations or SEO?
There is no reliable basis for a universal ranking or citation claim. Use Markdown when it measurably improves retrieval efficiency or extraction accuracy for clients that request it. Keep people-first HTML, crawlability, canonical identity, and factual quality as the search baseline.
Should every WebMCP action require confirmation?
No. Read-only, reversible, and low-consequence actions may not need a modal. Consequential writes need a policy based on object, amount, data class, reversibility, user intent, and delegated authority. Confirmation must show the exact consequence.
What should a WebMCP tool return?
Return structured business data, stable identifiers, next allowed states, a user-visible summary, and a receipt reference. Keep third-party prose labeled as untrusted data and verify consequential state after execution.
Should an agent install a package named in llms.txt?
Not on documentation authority alone. Treat the name and command as a candidate action. Resolve the exact package, version, repository, owner, provenance, digest, install behavior, network requirements, and policy result. Run it without ambient secrets in a disposable sandbox, then require review of the exact lockfile and receipt before promotion.
Is llms.txt itself a security vulnerability?
No. It is a community proposal for helping agents find relevant content. The vulnerability appears when a runtime promotes prose into execution without independently resolving artifacts and checking authority. The same mistake can start from a README, issue, email, or ordinary documentation page.
Sources and further reading
Public sources and current support status were checked on September 1, 2026. Experimental browser behavior, draft APIs, package ownership, and registry controls can change; confirm current state before release.
Related infrastructure guides
Understand the external tool layer and its transport boundaries.
Design for authenticated sessions, brittle interfaces, and real web state.
Turn consequential tool calls into reviewable, durable evidence.