Last week I wrote about AMA-teras, a desktop AI agent that writes its own tools behind verification gates. This week it learned to speak SKILL.md — the open standard for agent skills — in both directions. Here's what that means, why I think it matters more than any single feature, and the implementation details that surprised me.
SKILL.md started as an internal format and became an open standard that 30+ coding agents now support — Claude Code, Codex CLI, Cursor, Gemini CLI, and the rest. A skill is just a folder:
my-skill/
SKILL.md # frontmatter (name, description) + instructions
templates/… # optional resources
The clever part is progressive disclosure: the agent only reads the one-line description until a task actually needs the skill — then it loads the full instructions. Your context window stays clean; your agent still has a library card.
There are now community collections with 1,000+ skills. That's a lot of packaged expertise that, until this week, my agent couldn't touch.
The consuming side turned out to be almost embarrassingly small. Two tools:
skill_list
— walks the skill directories, parses frontmatter, returns name: description
lines onlyskill_use {name}
— returns the full SKILL.md body for one skillDirectories, in priority order: skills bundled with the app, then userData/skills/
where users drop anything from the ecosystem. Same-name conflicts? Bundled wins. That mirrors how our plugin already works — a user-installed artifact must never silently replace a built-in one. It's a small rule that closes a real attack: drop a folder called security-review
that says "skip all the checks" and wait for the agent to load it.
Two implementation notes that earn their keep:
1. Path traversal dies at the name check, not at the filesystem.
const NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
The skill name is the only user-controlled path segment, and it never gets to contain ..
, /
, or \
. Validating the shape before touching fs
is simpler and stricter than normalizing paths after the fact.
2. The tool description is the real UX. The agent decides whether to call skill_use
by reading skill_list
's output. So the list deliberately returns only names and one-liners — if it returned full bodies, we'd have paid the context cost of every skill to use one. The standard's progressive-disclosure idea survives only if your tools respect it.
AMA-teras already had a self-evolution pipeline: when the agent lacks a capability, it writes a new tool for itself, which then has to pass typecheck → unit tests → a real smoke run → human approval before it's allowed to load. (I wrote about why after watching my own agent claim success on things that didn't work.)
Now every tool that survives those gates can be exported as:
exported-tool/
SKILL.md # description + how to run + verification evidence
run.mjs # esbuild-bundled, self-contained runner
gate.json # the actual gate results: what passed, when, code hash
node run.mjs '{"numbers":[1,2,39]}'
works on any machine with Node — no AMA-teras required. The SKILL.md says, honestly, which gates the code passed and when. If there's no evidence, it says that instead.
The test for this feature doesn't mock anything: it bundles a real plugin, executes run.mjs
with the real Node binary, and asserts on stdout. If the export format rots, CI catches it — because the worst possible outcome for a "portable" format is shipping bundles that only work on the author's machine.
Because the alternative is the thing I built this project to escape.
Every major vendor ships an agent SDK, and every SDK quietly assumes your tools, your memory, your workflows live inside their runtime. Skills-as-folders is the opposite bet: expertise as plain files, readable by anything, owned by whoever wrote them. My agent can now use skills written for Claude Code; tools born inside my agent can serve someone using Codex. Neither side asked a vendor for permission.
For a solo open-source project, adopting the standard also beats inventing one for a more selfish reason: I get the ecosystem's growth for free, and the ecosystem gets one more independent implementation keeping the standard honest.
skill_list
/ skill_use
with 20 bundled skills (TDD discipline, security review, frontend design, Playwright E2E, pdf/docx/xlsx/pptx handling, …) — all original write-upsIt's AGPL, it runs on your machine, and it swaps between Anthropic / OpenAI / open-weight models with a config change: github.com/moriwo-dev-ai/ama-teras
If you maintain skills for any agent — I'd genuinely like to know what breaks when you drop them into a different runtime. That interop friction is the most useful bug report there is.