# `Issho.Tool`
[🔗](https://github.com/hattoriai/issho/blob/v0.4.0/lib/issho/tool.ex#L1)

A tool an agent uses in Issho's rooms, however it reaches your app: an
MCP client (`Issho.MCP`), your app's own model through an API
(`Issho.Tools`), or whatever comes next. A tool says what it does and
what it takes, as a JSON Schema; it runs as the agent of an
`Issho.Tool.Context`, under your policy, as anyone in a room does.

Issho's room tools are `Issho.Tools.room/0`; a component brings its own
(`Kotoba.Issho.tools/0`, `Hakushi.Issho.tools/0`).

    defmodule MyApp.Tools.Rename do
      use Issho.Tool,
        name: "rename_board",
        description: "Renames a board.",
        annotations: [idempotent: true]

      arg :board, :string, required: true
      arg :title, :string, required: true, max_length: 120

      @impl true
      def call(%{board: board, title: title}, ctx) do
        with {:ok, agent, _doc, _snapshot} <- Issho.Tool.Context.open(ctx, board) do
          ops = [%{"op" => "set", "path" => ["title"], "value" => title}]

          case Issho.Participant.transact(agent, board, ops) do
            {:ok, _receipt} -> {:ok, "Renamed."}
            {:error, reason} -> Issho.Tool.Context.error(reason)
          end
        end
      end
    end

`arg name, type, opts` declares an argument; the types are `:string`,
`:integer`, `:number`, `:boolean`, `:any`, `{:array, type}`,
`{:enum, values}` and `{:object, [{name, type, opts}]}`, and the options
`required`, `description`, `min`, `max`, `min_length` and `max_length`.
`call/2` gets the declared arguments with atom keys, the ones given.

`call/2` gives `{:ok, result}` (text, or a map or list as JSON) or
`{:error, text}`: what went wrong, in words the model reads.

# `result`

```elixir
@type result() :: {:ok, String.t() | map() | list()} | {:error, String.t()}
```

# `annotations`

```elixir
@callback annotations() :: keyword()
```

# `call`

```elixir
@callback call(args :: map(), Issho.Tool.Context.t()) :: result()
```

# `description`

```elixir
@callback description() :: String.t()
```

# `input_schema`

```elixir
@callback input_schema() :: map()
```

# `name`

```elixir
@callback name() :: String.t()
```

# `arg`
*macro* 

Declares an argument of the tool.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
