# `ConduitMcp.Client.ToolCall`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/client/tool_call.ex#L1)

One intended `tools/call`: which server, which tool, with which arguments.

This is the value hooks, policy and approvers see. `args_digest` is the
lower-case hex SHA-256 of the arguments' canonical JSON (object keys sorted
recursively, atom and string keys treated alike), so an approval can be
bound to the exact arguments that were shown and a later change to them is
detectable.

`meta` is user `_meta` for the request; reserved keys are added (and win)
when the request is encoded, not here.

`call_id` is the LLM provider's id for the call (Anthropic `tool_use.id`,
OpenAI `call_id`, Gemini `functionCall.id`), set by the
`ConduitMcp.Client.Adapters.*` modules so a result can be routed back to
the model. It is never sent to the server; it is kept out of `meta`
because `meta` is forwarded as the request's `_meta`.

# `t`

```elixir
@type t() :: %ConduitMcp.Client.ToolCall{
  args: map(),
  args_digest: String.t(),
  call_id: String.t() | nil,
  meta: map(),
  name: String.t(),
  server_id: String.t()
}
```

# `new`

```elixir
@spec new(String.t(), String.t(), map(), keyword()) :: t()
```

Builds a call and computes its `args_digest`.

Raises when `args` is not JSON-encodable (including when it contains a
`ConduitMcp.Client.Secret`).

## Options

  * `:meta` - user `_meta` for the request (default `%{}`).
  * `:call_id` - the LLM provider's call id (default `nil`).

## Example

    iex> a = ConduitMcp.Client.ToolCall.new("files", "read", %{"path" => "/a", "n" => 1})
    iex> b = ConduitMcp.Client.ToolCall.new("files", "read", %{n: 1, path: "/a"})
    iex> a.args_digest == b.args_digest
    true

# `put_args`

```elixir
@spec put_args(t(), map()) :: t()
```

Replaces the arguments and recomputes the digest (used when a pre-hook
rewrites them).

---

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