Give the Agent a new Tool
Build, install, run, disable, and remove one real Agent Tool Plugin.
In this tutorial you will add an uppercase Tool to the Lenso Agent Host. You
will write the behavior once, run it through a real Execution Adapter, package
it, install it into an App, ask the Agent to use it, and remove it again.
The current public CLI scaffolds Plugins; it does not scaffold a generic product Host. This tutorial therefore uses the maintained Lenso Agent as the concrete Host.
Complete Run your first Agent Turn first. This tutorial starts from an installed, authenticated Host and its visible Plugin Root:
lenso-agent-cli doctor --json
mkdir -p "$HOME/.lenso/agent/plugins"
lenso plugins list --root "$HOME/.lenso/agent"
What you will build
company.uppercase Plugin
provides lenso.agent.tool-provider@2
packages Wasm + trusted Process implementations
installs into ~/.lenso/agent/plugins/
becomes the uppercase Tool in the Agent App
1. Install the authoring tools
You need Rust 1.94 or newer, the Wasm target, Git, and either distribution of the Lenso CLI:
rustup target add wasm32-unknown-unknown
npm install -g @lenso/cli
# or: cargo install lenso-cli
Confirm the workflow exposed by your installed version:
lenso --version
lenso plugin new --help
2. Create the Plugin
Run this in an empty tutorial directory:
lenso plugin new company.uppercase
cd company.uppercase
The default Rust project has one editable src/lib.rs. It produces a portable
Wasm implementation and a trusted native Process implementation of the same
Plugin Contract.
Replace the generated execute body with uppercase behavior:
fn execute(arguments: Arguments) -> Result<ExecuteResponse, ExecuteError> {
if arguments.text.is_empty() {
return Err(ExecuteError::InvalidArguments);
}
Ok(ExecuteResponse {
content: arguments.text.to_uppercase(),
content_type: ContentType::Text,
metadata_json: r#"{"operation":"uppercase"}"#
.try_into()
.expect("static metadata is valid JSON"),
})
}
Keep the generated #[lenso::plugin], #[tool_provider], and #[tool]
annotations. They own the Plugin descriptor and Agent Tool projection.
3. Run it before packaging
lenso plugin check
lenso plugin dev \
--implementation auto \
--operation execute \
--request-json '{"name":"company.uppercase","arguments_json":"{\"text\":\"hello lenso\"}"}'
The result contains HELLO LENSO. For a multi-output Rust project, auto
uses the fastest declared local implementation. Run --implementation wasm
and --implementation process when you need implementation-specific evidence.
During editing, rerun automatically with the same request:
lenso plugin dev --watch \
--operation execute \
--request-json '{"name":"company.uppercase","arguments_json":"{\"text\":\"hello lenso\"}"}'
4. Package one Release
lenso plugin pack
The command creates and reopens
dist/company.uppercase-0.1.0.lenso-plugin. That archive contains both
implementations and one shared Contract.
Keep the absolute bundle path before leaving the Plugin directory:
PLUGIN_BUNDLE="$PWD/dist/company.uppercase-0.1.0.lenso-plugin"
5. Load the installed Host Catalog
lenso-agent-cli contexts --profile code
The contexts command boots the Host without starting a model Turn and
publishes the matching Host Catalog. The App owner changes only the visible
Plugin Root under ~/.lenso/agent/plugins/.
6. Add the Plugin to the App
lenso plugins add "$PLUGIN_BUNDLE" --root "$HOME/.lenso/agent"
lenso plugins list --root "$HOME/.lenso/agent"
lenso app check --root "$HOME/.lenso/agent"
plugins add validates the received Bundle, derives a candidate App from the
Host Catalog and Plugin Root, and commits the files only when the candidate is
valid.
7. Use the new behavior
From any Workspace where you want the Agent to work:
lenso-agent-cli --profile code \
"Use company.uppercase to convert 'hello lenso' to uppercase."
The observable result is an Agent Turn that calls company.uppercase and
returns HELLO LENSO. The Plugin is now application behavior, not only a
locally callable package.
8. Disable, enable, and remove it
lenso plugins disable company.uppercase default --root "$HOME/.lenso/agent"
lenso plugins enable company.uppercase default --root "$HOME/.lenso/agent"
lenso plugins remove company.uppercase --root "$HOME/.lenso/agent"
lenso app check --root "$HOME/.lenso/agent"
Disable keeps the package and configuration available. Omitting the Instance
key from remove deletes the whole Plugin directory and moves it into the
App’s recoverable .lenso/trash/. In both cases the Host resolves a new immutable App
Generation; existing work keeps the Generation on which it started.
You have now completed the full author workflow. Continue with Choose a Plugin path when the next behavior is not an Agent Tool, or Add Plugins to an App for configuration, resources, and Catalog operations.
Clone the Agent repository only when you need to change the Host’s Rust implementation. The source-development path is documented in the Agent README.