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.
Summary
Functions
The output schema to show for tool, with string keys, or nil when the tool has none.
The schema of a preview or approval answer of an admin tool.
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.
Functions
@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.
@spec preview_shape() :: map()
The schema of a preview or approval answer of an admin tool.
@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.