> ## Documentation Index
> Fetch the complete documentation index at: https://docs.atonom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Your first Lua tool

> Create, test, and save your first Lua tool with the Atonom CLI.

Create an order-total tool, test it with a fixture, and run the stored version through Atonom. Complete [Install & connect](/atonom-script/cli/install) first. Sign in to your Atonom environment before starting. The optional sandbox step requires [sandbox access](/atonom-script/cli/install#connect-the-sandbox-optional).

## 1. Create or choose a tool

```sh theme={null}
atonom create "Order total"
```

The CLI selects the sole available Atonom agent or prompts you to choose one. It creates a disabled Lua script tool and links a starter file locally. Record the returned **tool ID** and **path**; naming collisions can change the filename.

For a coding agent or noninteractive shell, specify the owner explicitly:

```sh theme={null}
atonom create "Order total" --comm-agent-id 7 --json
```

`7` is an example Atonom agent ID, not a tool ID. Use the actual owner ID from your platform. `create --json` reports available choices if multiple owners exist and none was supplied.

To edit an existing tool instead:

```sh theme={null}
atonom list --json
atonom get 42 --json
atonom pull 42 --json
```

The following steps use example tool ID `42` and path `.atonom/scripts/order-total.lua`. Substitute your returned values.

## 2. Define inputs

In the platform's tool editor, configure the input schema to include `qty` (integer) and `unit_price` (number), both required. This CLI edits script bodies; it has no command to change the input schema or enable the tool.

Inspect the stored schema with:

```sh theme={null}
atonom get 42 --json
```

Inputs supplied to the tool arrive directly as `context.qty` and `context.unit_price`.

## 3. Write the transform

Replace the starter file's body with:

```lua theme={null}
function transform(context)
  local qty = context.qty
  local price = context.unit_price

  if type(qty) ~= "number" or qty < 0 or qty % 1 ~= 0 then
    error("qty must be a non-negative integer")
  end
  if type(price) ~= "number" or price < 0 then
    error("unit_price must be a non-negative number")
  end

  return { qty = qty, total = qty * price }
end
```

For this example, the output is a numeric calculation. For production currency calculations, choose and document a rounding policy or use integer minor units.

## 4. Test without saving (optional)

If you have sandbox access, test the local file before saving it. Otherwise, continue to step 5 to save and test through Atonom.

```sh theme={null}
atonom eval .atonom/scripts/order-total.lua \
  --transform '{"qty":2,"unit_price":12.5}' --json
```

The result should contain:

```json theme={null}
{
  "outcome": {"status":"DONE","value":{"qty":2,"total":25}},
  "traps": [],
  "unanswered_trap": null,
  "exit_code": 0
}
```

Also test missing and invalid inputs:

```sh theme={null}
atonom eval .atonom/scripts/order-total.lua --transform '{}' --json
atonom eval .atonom/scripts/order-total.lua \
  --transform '{"qty":-1,"unit_price":12.5}' --json
```

Both should produce `FAIL` and exit code `2`. Defining a function alone does not invoke it: `--transform` binds `context` and appends `return transform(context)`.

## 5. Review, save, and run

```sh theme={null}
atonom diff 42 --json
atonom push 42 --json
atonom run 42 --no-save --inputs '{"qty":2,"unit_price":12.5}' --json
```

Review the diff before pushing. A normal push of a changed, linked file sends the last synced hash, allowing the server to reject conflicting remote edits. The final command executes the saved body and should return `status: "ok"` with `value.total: 25`.

<Warning>
  **Saving and testing are separate outcomes**

  A saved script can fail when executed. `run` without `--no-save` persists the local body before execution, and its request does not send a conflict hash. The `push` → `run --no-save` sequence makes conflict handling explicit.
</Warning>

## 6. Make it available to the platform agent

Review the tool description, input schema, ownership, and status in Atonom. Enable the tool there when ready and test it from its owning Atonom agent. A successful CLI test does not automatically enable a tool or prove that the agent will choose it with the intended inputs.

Next: [Use a coding agent](/atonom-script/cli/agents) or [add mocked tool calls](/atonom-script/cli/testing).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.