Skip to main content
After this guide, the model calls a tool you wrote whenever an end user’s request needs it. A tool runs only when the model calls it during a conversation; for work that starts outside one, handle a webhook or create a trigger instead. Verified against lua-cli 3.33.0. Before you begin
1

Write the tool

Create a class that implements LuaTool. name is what you test and log by, description is prompt text the model reads to decide when to call the tool, and inputSchema is the Zod object the model’s arguments are parsed with before execute runs.
src/skills/tools/CalculateRefundTool.ts
Return plain data, not prose: the value is serialized to JSON and handed to the model, which writes the reply. Each .describe() reaches the model too; use it to say what a field means and how to fill it.
2

Register it in a skill

A tool is compiled only when a skill on the LuaAgent references it. The skill’s context tells the model when and how to use the tool (Write skill context).
src/skills/returns.skill.ts
Register the new skill on the agent. The file below is the quickstart’s; if yours differs, add only the highlighted lines to your own LuaAgent.
src/index.ts
3

Compile

lua compile bundles every primitive the agent references into dist-v2/ and reports what it found.
Output
The counts are the quickstart project plus the new skill; in any project the tool count goes up by one, and a class no registered skill references is left out without a message. A name outside lowercase letters, digits, hyphens, and underscores gets the warning Tool name should be lowercase with hyphens or underscores and still compiles.
4

Run it locally

lua test skill runs execute with the JSON you pass. --name takes the tool’s name, not the skill’s.
Output
No model is involved and the input isn’t parsed against inputSchema, so the output is exactly what execute returned. A tool that throws still exits 0 and prints { status: 'error', error: '<message>' }.
5

Try it in the sandbox

lua chat compiles the project, uploads your skills as sandbox versions, and runs a conversation with them; nothing is pushed and end users see no change (About environments). The first sandbox run after adding a skill registers it, prints Skipping skill returns - no skillId found in lua.skill.yaml, and answers without the tool, so run the command twice. -t starts a fresh thread so earlier messages don’t shape the answer.
The reply quotes 102 and the 15% restocking fee.
6

Release

lua push uploads a skill version and changes nothing for end users. lua version create snapshots every primitive into an agent version, and lua version promote makes that snapshot live for everyone on their next message; it is also the rollback path.
lua version create prints ✓ Created v<n> (staged). Run `lua version promote v<n>` to deploy.; <n> comes from that line, promote accepts <n> or v<n> and asks no confirmation, and in a script n=$(lua version list --limit 1 --json --ci | jq -r '.[0].version') reads it. lua deploy skill --name <skill> --set-version <v> serves that version from the agent’s next turn, but the next lua version promote resets every skill to the version pinned in the promoted agent version, so a skill deployed without a new agent version is reverted by the next promote; for an immediate rollback of one skill, deploy the earlier version. The full flow, review, and rollback are in Release an agent to production.
7

Verify

List the production skills. Each is printed as 📦 <name> with its Skill ID; returns shows Deployed ⭐ and a Deployed: line with the time of the promote.
Then send the sandbox message to production and read the call in the skill’s log (--name is the skill).

If it isn’t working

--name takes the tool’s name, not the skill’s or the class’s, and the tool must be in a skill listed in LuaAgent.skills. Run lua compile --ci and check the tool count.
On the first sandbox run after adding a skill this is expected; run it again. Otherwise the skill’s context or the tool’s description doesn’t say when the tool applies; see Write skill context. Use -t so an earlier answer doesn’t anchor the next one.
A later lua version promote reset the skill to the version pinned in that agent version, or --set-version latest picked the most recently created version rather than the one you meant. Run lua version create --ci -m "Add calculate_refund" and lua version promote <n> after the push so the change survives the next promote.

Next steps

Write skill context

Make the model call the right tool with the right arguments.

Call your API

Read a key from the environment and call an HTTP API from execute.

LuaTool reference

Every member, the voice flags, and condition.

lua test reference

Types, input shapes, and JSON output.