The code below is the Rust template, which
noorle plugin init <name> --template rust scaffolds. The per-language layouts
and build commands are under Languages; everything on
this page about wit/world.wit, noorle.yaml, and the archive applies to all
of them.Layout
noorle plugin build, not with cargo directly — the CLI drives
build.sh and packages the archive.
wit/world.wit — the interface
The WIT world defines your tools: their names, parameter types, and return
types. Two things follow from it.
Exported functions become tools. Discovery walks the compiled component’s
exports, so what you export is what agents see.
Doc comments become tool descriptions. The /// line above an export is
the text a model reads when deciding whether to call it. Write it for the
model, not for a compiler.
result<T, string> so failures reach the caller as errors rather than
as a success carrying an error string.
The .wit file is packaged into the archive and stored with the version, but
it is not what produces the tool schema — the schema is generated from the
component’s own types. Shipping the file gets you descriptions; omitting it
gets you tools with no descriptions.
src/lib.rs — the implementation
wit_bindgen generates a Guest trait from the world; you implement it and
export the implementing type.
- Outbound HTTP goes through
waki.reqwestdoes not compile to a WASI component. - Environment variables are read with
std::env::var, and only the keys you list underpermissions.environmentare visible. - Files live under the mounts you grant —
/workspace/input,/workspace/output,/workspace/home. There is no host filesystem behind them; see Permissions. - Avoid
unsafe.
noorle.yaml — configuration
Metadata, the permission policy, and credential declarations. This is the file
that decides what your plugin can reach at runtime; without it, the plugin
runs with no network, no storage, and no environment access.
Cargo.toml
crate-type = ["cdylib"] is required — without it the build produces
something that is not a component, and admission validation rejects it.
What ends up in the archive
noorle plugin build writes a .npack to dist/. When the platform unpacks
it, it looks for four things by filename pattern:
Everything else in the archive is ignored. Your source is not uploaded —
the upload path stores the component, the manifest, the environment defaults,
and the WIT file, and nothing else. (Plugin versions produced by Plugin
Builder do keep a source archive, so a later build can iterate on them.)
Size
There is no minimum, and no hard maximum below the upload limit. Validation warns above 20 MB for the component binary — a warning, not a rejection. If you approach it, reach for your toolchain’s size levers: in Rust, release settings such as anopt-level tuned for size, LTO, and symbol stripping; in
Go, the -opt=2 -no-debug flags TinyGo already builds with; in Python and
JavaScript, trimming dependencies, since the runtime is bundled into the
component.