# `PhoenixKit.API.OutputShape`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.64.1/lib/phoenix_kit/api/output_shape.ex#L1)

The output schema a client is told a tool answers with: MCP's `outputSchema`
and the `200` response of the OpenAPI document.

A read-only tool answers with its own `output_schema`. Any other tool (a
write tool, `PhoenixKit.API.ControlFields.write_tool?/1`) may answer with a
**preview** instead: a dry run, a confirmation request or a pending approval.
Its schema is therefore
`{"type": "object", "anyOf": [success, preview]}`. It is `anyOf`, not
`oneOf`, because a preview also satisfies a success schema that does not
forbid extra properties, which would make `oneOf` reject it. The root keeps
`"type": "object"` because MCP client libraries require an object schema
there. The preview of a public tool (`preview_shape/1`) knows no approval:
an anonymous call is never held for one, and a document served without a key
does not mention them.

A tool with no `output_schema` has no output shape. Keys are turned into
strings at every depth and the root is forced to `"type": "object"` (a tool
answers with a map); the rest of the schema is passed through as declared,
`PhoenixKit.API.ToolLint` is what checks that it is sound.

# `for_tool`

```elixir
@spec for_tool(PhoenixKit.API.Tool.t()) :: map() | nil
```

The output schema to show for `tool`, with string keys, or `nil` when the tool has none.

# `preview_shape`

```elixir
@spec preview_shape() :: map()
```

The schema of a preview or approval answer of an admin tool.

# `preview_shape`

```elixir
@spec preview_shape(PhoenixKit.API.Tool.audience()) :: map()
```

The schema of a preview answer of a tool of `audience`: the admin one may also
be a pending approval, a public one never is.

---

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