# `Alloy.Tool.Inline`
[🔗](https://github.com/alloy-ex/alloy/blob/v0.12.4/lib/alloy/tool/inline.ex#L1)

A tool defined as data instead of a module.

Module tools (`Alloy.Tool`) are the right shape for tools you own and
test. Inline tools cover the cases modules can't: tools discovered at
runtime (an MCP server's tool list, a database of user-defined actions)
and one-off tools that don't warrant a file.

Build one with `Alloy.Tool.inline/1`:

    weather =
      Alloy.Tool.inline(
        name: "get_weather",
        description: "Get current weather for a location",
        input_schema: %{
          type: "object",
          properties: %{location: %{type: "string"}},
          required: ["location"]
        },
        execute: fn %{"location" => loc}, _context ->
          {:ok, "22°C and clear in " <> loc}
        end
      )

    Alloy.run("What's the weather in Sydney?",
      provider: provider,
      tools: [weather, Alloy.Tool.Core.Read]
    )

`tools:` accepts inline tools and tool modules interchangeably.

## Fields

Required:

- `:name` - unique tool name (string, used in API calls)
- `:description` - what the tool does, for the model
- `:input_schema` - JSON Schema map for the input
- `:execute` - 2-arity function `(input, context)` returning
  `{:ok, text}`, `{:ok, text, structured_data}`, or `{:error, reason}` —
  the same contract as `c:Alloy.Tool.execute/2`

Optional:

- `:concurrent?` - safe to run in parallel with other tools
  (default `true`, matching module tools without a `concurrent?/0`)
- `:max_result_chars` - cap on result text, or `:unlimited`
  (default `nil`, no cap)
- `:allowed_callers` - as `c:Alloy.Tool.allowed_callers/0`
  (default `nil`, omitted from the tool definition)
- `:result_type` - as `c:Alloy.Tool.result_type/0`
  (default `nil`, omitted from the tool definition)
- `:strict` - request provider strict-mode schema enforcement
  (default `false`)
- `:input_examples` - example input maps for providers that support them
  (default `[]`)
- `:defer_loading` - request provider-side deferred tool loading
  (default `false`)

# `t`

```elixir
@type t() :: %Alloy.Tool.Inline{
  allowed_callers: [atom()] | nil,
  concurrent?: boolean(),
  defer_loading: boolean(),
  description: String.t(),
  execute: (map(), map() -&gt;
              {:ok, String.t()}
              | {:ok, String.t(), map()}
              | {:error, String.t()}),
  input_examples: [map()],
  input_schema: map(),
  max_result_chars: pos_integer() | :unlimited | nil,
  name: String.t(),
  result_type: :text | :structured | nil,
  strict: boolean()
}
```

---

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