# `Sake.Tool`
[🔗](https://github.com/hattoriai/sake/blob/v0.4.3/lib/sake/tool.ex#L1)

A tool: `use Sake.Tool` with options, `arg` lines, an optional `output`
block, and `execute/2`.

    defmodule MyApp.MCP.SearchIssues do
      use Sake.Tool, name: "search_issues", description: "Search issues", scope: "issues:read"
      arg :query, :string, required: true
      @impl true
      def execute(%{query: q}, ctx), do: {:ok, Issues.search(ctx.scope, q)}
    end

Options: `name` (default: the module's last segment in snake case),
`title`, `description`, `icons`, `scope` (one or many), `annotations`
(`read_only`, `destructive`, `idempotent`, `open_world`), `stream`,
`ttl`, `meta`, `input_schema` (a schema map instead of `arg` lines),
`task` (`:optional` or `true`, or `:required`: the tool runs as a task
for a client that takes one, see `Sake.Tasks`), `ui` (a `Sake.UI`
module: the app the host shows with the tool's result), `visibility`
(`[:model, :app]` by default; `[:app]` for a tool only an app calls,
which a client without MCP Apps does not see), `authentication`
(`[acr: ["mfa"], max_age: 300]`: how the person must have signed in
to call it, see "Step-up authentication" in `Sake.Server`).

# `complete`
*optional* 

```elixir
@callback complete(arg :: String.t(), partial :: String.t(), ctx :: Sake.Context.t()) ::
  {:ok, [String.t()]} | {:ok, [String.t()], keyword()}
```

# `execute`

```elixir
@callback execute(args :: map(), ctx :: Sake.Context.t()) ::
  {:ok, term()}
  | {:ok, term(), keyword()}
  | {:error, String.t()}
  | {:error, {:missing_capability, map()}}
```

# `prepare`
*optional* 

```elixir
@callback prepare(args :: map(), ctx :: Sake.Context.t()) ::
  {:ok, map()} | {:error, String.t()}
```

Runs before `execute/2`, in the request itself, and returns the
arguments `execute/2` receives (or a tool error). A task tool asks the
client for input here when the answer decides whether the task should
start at all: inside the request, the question travels as a multi
round-trip request; inside the task, it would wait on the task.

# `spec`

```elixir
@callback spec() :: Sake.Tool.Spec.t()
```

# `arg`
*macro* 

Declares an argument (or, inside `output`, an output property).

# `output`
*macro* 

Declares the output schema with `arg` lines.

---

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