Teach any agent how to use your site. No server required.
llms.txt already tells agents WHAT your site is. This adds a standard
way to say HOW to use it: a `## Skills` section pointing at your
SKILL.md files — discovered, verified, and used with explicit opt-in.
llms.txt tells an agent what your site is. Agent Skills (SKILL.md)
tell it how to use it. Today there is no standard way for a site to
say "here is the skill for working with me" — so an agent that reads
your llms.txt has no signal a skill even exists.
Without this standard
Agent reads llms.txt, sees prose about your API
No signal that a SKILL.md exists or where
Agent invents a generic call and gets it wrong
## Skills in llms.txt
One `## Skills` section, same llms.txt fetch
Agent discovers title, description, and URL
Verified by sha256 (and ed25519 if signed), then used
How it works
Four steps. The user's opt-in is never skipped.
A publisher adds a ## Skills section to the llms.txt it already serves — one line of markdown per skill.
An agent that reads llms.txt now sees the skills available and lists them to the user.
The user opts in explicitly. Agents MUST NOT auto-install a skill.
The agent fetches the SKILL.md, verifies its sha256 (and ed25519 signature if declared), then loads it as context.
Three ways to consume it today
All three are real and working, not roadmap.
Claude Code plugin recommended
Install the llms-txt-aware consumer skill as a Claude Code plugin. It activates automatically whenever you're about to touch a web domain.
Copy the 6-step procedure into your agent's system prompt. No plugin system required, works with any model that follows instructions.
skill
cat skills/llms-txt-aware/SKILL.md
Three rings of trust
sha256 alone proves integrity, not authenticity — the same document that points to a skill also asserts its hash. Signing closes that gap. And neither says whether the content is still true — signed freshness covers that.
01
Integrity — sha256
Declared inline in ## Skills and in /.well-known/agent-skills/index.json. Agents MUST verify it and refuse to load on mismatch.
02
Authenticity — ed25519 + key pinning
The publisher signs each SKILL.md with a key kept offline. Agents pin the key per origin (TOFU) and flag a silent change across sessions.
03
Freshness — signed “still true”
Hashes freeze bytes, not truth. A registered reviewer signs a freshness attestation bound to the exact content sha — voided by any edit, expiring on a date — and llms-skills freshness turns stale knowledge into a failing CI build.
Does publishing a skill change what an agent does?
Measured, not asserted — 6 local models, 7 scenarios, 3 reference sites.
0%
baseline: uses the real endpoint
given only the task, models mostly invent a local fallback
0%
discovery: uses the real endpoint
given the site's llms.txt + SKILL.md, most get it right
0
models tested locally
0.5B to 9B parameters, via LM Studio
0
scenarios × sites
image API, storefront, wireframe validator
Small-N proof of mechanism, not a benchmark — all 3 sites are
first-party. Full methodology, caveats, and raw data in
evals/results.md.
Live publishers you can consume right now
Seven first-party origins dogfood the full stack — ## Skills, hash-pinned BM25 knowledge, executable tools, SKILL.md recipes, signed index. The root origin is directly consumable (npx -y @rckflr/mcpwasm https://mauricioperera.github.io) and now aggregates a second project on the same llms.txt: KDD under the kdd scope — kdd__search_knowledge, with its own verified memory (scopes, Executable Skills v0.5 §2.5; live in mcpwasm 0.6.0, llms-skills memory --scope in 0.3.0). Other project pages are consumed via clone + --serve.
mauricioperera.github.io — root origin: site_facts + the standard's own skills + KDD aggregated under the kdd scope, live-consumable
/llms-txt-skills/ — this spec: 4 skills incl. a custom validator + 6-concept knowledge bundle
/KDD/ — a real pre-existing OKF bundle, 40 concepts — also served from the root as kdd__*
This does not replace MCP or A2A — it fills the gap below them: publishing a skill for a simple API or static site, with no server to run.
MCP
A2A
/.well-known/skills/
## Skills in llms.txt
Requires a running server
Yes
Yes
No
No
Works on static sites
No
No
Yes
Yes
Multiple skills per domain
Yes
Yes
No (one only)
Yes
Co-located with llms.txt
No
No
No
Yes
Implementation complexity
High
High
Low
Low
Adopt it in 3 steps
Fastest path: the GitHub template — a working publisher out of the box (example knowledge bundle, generated skills, validation CI). Click Use this template, replace knowledge/, run two commands.
The CLI (@rckflr/llms-skills)
computes the sha256, syncs .well-known/agent-skills/index.json,
and signs — so none of it is done by hand. In CI, a reusable GitHub
Action (uses: MauricioPerera/llms-txt-skills@master) fails
the build if what you serve drifts from your sources. Full guide in the
README.
From a static site to a live MCP server
llms-txt-skills is the format; mcpwasm is a runtime for it. A publisher serves hash-pinned, attested skills once, the standard way — the runtime discovers, verifies, and runs each as an MCP tool. The whole contract between them is one tool_sha256 and its attestation.
A publisher serves an llms.txt whose ## Skills section lists each executable skill with its tool.js and tool_sha256 — mirrored in /.well-known/agent-skills/index.json and signed in attestations.json. Optionally, a hash-pinned BM25 snapshot (one llms-skills memory command over an OKF bundle) adds serverless search over the site's own knowledge. This is exactly what this spec defines.
A runtime like mcpwasm points at that origin, fetches the llms.txt, and verifies every tool.js against its tool_sha256 and its attestation — rejecting any mismatch before loading it.
Each verified skill becomes an MCP tool, and its SKILL.md recipe is served alongside as an MCP resource (with a get_skill_guide fallback) — the agent gets the manual, not just the hammer. Claude, Cursor, any MCP host list and call it like any other tool.
On a call, the runtime executes that tool.jsverbatim inside a QuickJS-wasm sandbox — no network or filesystem except the host capabilities it grants (a scoped fetchOrigin back to the site, and search over the site's own content). The result returns to the client.
Neither side has to trust the other's prose: the runtime re-derives the hash and checks the signature itself. Static hosting + a verifying runtime = an MCP server with no server to run.
Part of a growing spec
This RFC (v0.10) has two provisional extensions: Executable
Skills, sandboxed tool.js a runtime executes
verbatim instead of asking a model to improvise, and Skill
Attestations, signed human review with an expiry window.
Both are field-tested end-to-end in
mcpwasm,
their reference implementation.