Loaders
Reference
Cross-language parity
A conforming loader parses an agent.3md once with a 3md parser, builds an index
over the plane attributes, and exposes a small contract: manifest, route,
get, resolve, and command. The format does the parsing; the loader is the
thin agent layer on top.
Because the canonical 3md parser is maintained against a shared conformance suite
in TypeScript, Rust, and Swift, the same agent.3md loads and routes
identically in all three. Routing in particular is defined down to the
tokenizer (maximal runs of Unicode letters and digits, lowercased) so it never
diverges between languages.
TypeScript: the reference loader
TypeScript is the reference implementation and the package you embed in an agent.
It carries the spec, the validator, and the MCP server. Install from public npm:
npm install @corvidlabs/agent3md (see Quickstart).
import { Agent, validateAgent, fillCommand, commandPlaceholders } from "@corvidlabs/agent3md";
import { readFileSync } from "node:fs";
const src = readFileSync("agent.3md", "utf8");
const report = validateAgent(src); // { ok, errors, warnings }
const agent = new Agent(src);
The Agent class
| Method | Returns |
|---|---|
manifest() | Agent name, model, tools, persona, the identity body, and a body-less skill catalog (name, z, triggers, cost, tool). |
route(text) | Skills whose triggers text satisfies, ranked by distinct phrases matched (ties broken by lower z); each result is { skill, score, hits }. Empty array on no match. |
get(name | z) | One skill including its full body, O(1). undefined if missing. |
resolve(name | z) | The skill plus its transitive dependency chain (via [[z=N]] links), each skill once. |
command(name | z, values) | The skill's tool with its {placeholder} slots filled (shell-quoted) from values; null if the skill has no tool. |
const ranked = agent.route("find every TODO"); // [{ skill, score, hits }, ...]
const top = ranked[0].skill; // the search skill
const body = agent.get(top.name)?.body; // load just that plane
const cmd = agent.command(top.name, { pattern: "TODO", path: "src" });
// -> rg --line-number 'TODO' 'src'
Command helpers
Two standalone helpers back command() and are exported for reuse:
commandPlaceholders(template): the placeholder names a template references, in order, de-duplicated. Use it to learn what still needs filling.fillCommand(template, values): swap each{name}for a shell-quoted value; placeholders without a value are left visible.
commandPlaceholders("rg --line-number {pattern} {path}"); // ["pattern", "path"]
fillCommand("rg {pattern} {path}", { pattern: "TODO" }); // rg 'TODO' {path}
Rust: the native crate
Rust is the default native CLI, published to crates.io as
agent3md. It depends on the published
threemd crate (threemd = "1.0"), so nothing local is needed.
cargo install agent3md
agent3md manifest agent.3md
The Rust loader mirrors the TypeScript model: it parses with threemd, parses
the same typed-input grammar (name, name:type, name:type?), and exposes the
same manifest / skills / route / get / resolve / validate commands.
To run it from a clone instead of installing:
cd loaders/rust && cargo run -- manifest ../../agent.3md
Swift: the third language
The Swift loader proves the format ports to a third language. It depends on the
canonical ThreeMD package straight from git, so nothing local is needed:
.package(url: "https://github.com/CorvidLabs/3md.git", from: "1.7.17")
cd loaders/swift && swift run
It uses the same Skill / SkillInput model and the same shared input grammar
as the TypeScript and Rust loaders, so a typed inputs="limit:number?" parses to
the same required/optional, typed result in every language.
A JSON projection
For consumers that are not 3md-aware, the repo also ships a JSON projection of the
manifest (bun run export, schema: agent3md/1) so the catalog can be discovered
across processes without a 3md parser.
See also
- CLI reference: the commands these loaders power.
- MCP server: expose a loader's skills to an MCP client.
- Conformance and spec: the contract every loader implements.