# `AttestoMCP.Server.Result`
[🔗](https://github.com/XukuLLC/attesto_mcp_server/blob/v2.8.0/lib/attesto_mcp_server/result.ex#L1)

Typed MCP result constructors and explicit client-visible business failures.

`tool/2` and `resource/2` emit canonical string-key maps and validate their
complete aggregate against the same bounds used for raw handler output.
They use the secure 2,000,000-byte default; pass
`max_json_bytes: server_budget` when the supervised server explicitly uses a
larger finite JSON budget.

Inside an arity-two tool handler, `tool_from_context/2` and
`tool_from_context/3` inherit the supervised server's JSON budget and output
canonicalization mode from the handler context without allowing those
settings to be overridden. Standalone `tool/1` and `tool/2` retain their
secure defaults and explicit configuration options.

Protocol-owned `resultType`, cache, and server-identity fields are added by
the server after a handler returns.

Arbitrary handler errors and exceptions remain private. Use `error/2` only
for bounded text and a machine-readable code that are safe to disclose to
the calling client.

# `canonicalization_mode`

```elixir
@type canonicalization_mode() :: :strict | :json | :jason
```

# `context_tool_option`

```elixir
@type context_tool_option() ::
  {:structured_content, term()} | {:is_error, boolean()} | {:meta, map()}
```

# `resource_option`

```elixir
@type resource_option() :: {:meta, map()} | {:max_json_bytes, pos_integer()}
```

# `resource_result`

```elixir
@type resource_result() :: %{required(String.t()) =&gt; term()}
```

# `result_context`

```elixir
@type result_context() :: %{
  :max_json_bytes =&gt; pos_integer(),
  :output_canonicalization =&gt; canonicalization_mode(),
  optional(term()) =&gt; term()
}
```

# `tool_option`

```elixir
@type tool_option() ::
  {:structured_content, term()}
  | {:is_error, boolean()}
  | {:meta, map()}
  | {:max_json_bytes, pos_integer()}
  | {:output_canonicalization, canonicalization_mode()}
```

# `tool_result`

```elixir
@type tool_result() :: %{required(String.t()) =&gt; term()}
```

# `error`

```elixir
@spec error(String.t(), String.t() | nil) :: AttestoMCP.Server.Result.ClientError.t()
```

Builds one explicitly client-visible business error.

# `resource`

```elixir
@spec resource(
  AttestoMCP.Server.Content.resource_content()
  | [AttestoMCP.Server.Content.resource_content()],
  [resource_option()]
) :: resource_result()
```

Builds a complete resource result from one resource-content entry or a list.

The server owns modern cache and result-discrimination fields. Unknown and
duplicate options are rejected.

# `tool`

```elixir
@spec tool(AttestoMCP.Server.Content.t() | [AttestoMCP.Server.Content.t()], [
  tool_option()
]) ::
  tool_result()
```

Builds a complete tool result from one content block or a list of blocks.

`:structured_content`, when present, must be a bounded JSON value. Pass
`output_canonicalization: :json` or `:jason` to opt into the corresponding
encoder protocol for structs and string conversion for non-boolean atoms.
`:meta` must be a bounded JSON object. Unknown and duplicate options are
rejected.

# `tool_from_context`

```elixir
@spec tool_from_context(
  AttestoMCP.Server.Content.t() | [AttestoMCP.Server.Content.t()],
  result_context(),
  [context_tool_option()]
) :: tool_result()
```

Builds a complete tool result using the supervised server settings in a
handler context.

The context must contain valid atom-keyed `:max_json_bytes` and
`:output_canonicalization` values. The inherited settings cannot be
overridden through this constructor; use standalone `tool/2` when an
intentional per-result override is required. Unknown and duplicate options
are rejected.

Use this constructor inside a tool handler when its result must follow the
server's configured JSON budget and output-canonicalization mode.

---

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