Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/docs/_content/architecture-rendering-output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ stateDiagram-v2
Collecting --> Collecting: attach(image)
Collecting --> StructuredReady: setStructuredOutput(output)
StructuredReady --> StructuredReady: setNextSteps(steps, runtime)
Collecting --> ErrorTracked: error fragment emitted
StructuredReady --> ErrorTracked: structured result didError=true

ErrorTracked --> Finalizing: finalize()
Expand All @@ -60,7 +59,7 @@ stateDiagram-v2
RuntimeBoundary --> [*]
```

The render session is the collection point for the tool invocation. It receives fragments as work happens, stores attachments, stores the final structured output, stores next steps, tracks error state, and finalizes the transcript for the selected render strategy.
The render session is the collection point for the tool invocation. It receives fragments as work happens, stores attachments, stores the final structured output, stores next steps, derives error state from the structured result, and finalizes the transcript for the selected render strategy.

## Render strategy vs CLI output mode

Expand Down
2 changes: 0 additions & 2 deletions app/docs/_content/architecture-tool-lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ interface ToolHandlerContext {
| `nextSteps` | Provide explicit dynamic follow-ups when templates cannot express the result. |
| `structuredOutput` | Set the final canonical result, schema ID, and schema version. |

The omitted progress flags are internal boundary controls. They exist in source today, but the public docs intentionally do not teach tool authors to branch on them.

## Fragments versus structured output

A handler produces two different things, and they serve different readers. Fragments are live progress and transcript material — log lines, build output, attachments — that callers and pipelines consume while the work is running. Structured output is the one final canonical result the handler sets at the end of the call. Fragments are never the final result; the structured output is what powers CLI `--output json`, MCP `structuredContent`, schema validation, fixtures, and stable integrations.
Expand Down
2 changes: 1 addition & 1 deletion app/docs/_content/mcp-protocol-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The envelope wraps every tool's structured payload in the same shape, so consume
}
```

The envelope fields are documented in [Output Formats](/docs/output-formats). Canonical JSON schemas live in [`schemas/structured-output/`](https://github.com/getsentry/XcodeBuildMCP/tree/main/schemas/structured-output). Tools advertise their output schema in `tools/list`.
The envelope fields are documented in [Output Formats](/docs/output-formats). Canonical JSON schemas live in [`schemas/structured-output/`](https://github.com/getsentry/XcodeBuildMCP/tree/main/schemas/structured-output). Tools advertise their output schema in `tools/list` as an object-shaped union of the domain schema OR `xcodebuildmcp.output.error`, so clients can always branch on `schema` to determine whether a structured result is a normal domain payload or a generic error.

The one exception is the [Xcode IDE bridge](/docs/xcode-ide): bridge tools forward calls to Xcode's own MCP service, so their output shape comes from Xcode and does not use the XcodeBuildMCP envelope.

Expand Down
47 changes: 42 additions & 5 deletions app/docs/_content/output-formats.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,31 @@ The response has these fields:
|-------|------|---------|
| `schema` | `string` | Schema identifier, for example `xcodebuildmcp.output.build-result`. |
| `schemaVersion` | `string` | Version of that schema contract. |
| `didError` | `boolean` | Whether the tool reported a domain error. |
| `didError` | `boolean` | Whether the final result is an error. |
| `error` | `string \| null` | Human-readable error text when `didError` is true. |
| `data` | `object \| null` | Tool-specific data. |
| `data` | `object \| null` | Schema-specific payload. Domain schemas use tool-specific data; `xcodebuildmcp.output.error` uses generic error metadata. |

Structured output is a tagged union. Consumers should branch on `schema`, then parse `data` according to that schema:

```typescript
type XcodeBuildMCPOutput =
| {
schema: "xcodebuildmcp.output.simulator-list"
schemaVersion: "1"
didError: boolean
error: string | null
data: { simulators: Simulator[] }
}
| {
schema: "xcodebuildmcp.output.error"
schemaVersion: "1"
didError: true
error: string
data: { category: "runtime" | "validation" | "schema"; code: string }
}
```

For example, `list_sims` normally returns `xcodebuildmcp.output.simulator-list`, but a validation or runtime failure before simulator listing begins returns `xcodebuildmcp.output.error`. Do not assume a tool always returns only its domain schema; always check `schema` first.

```json
{
Expand Down Expand Up @@ -91,7 +113,22 @@ The response has these fields:
}
```

`data` can be `null` when a tool succeeds but has no structured payload. If a tool does not produce structured output for `--output json`, the CLI emits an error response with `schema: "xcodebuildmcp.output.error"`, `didError: true`, and exits with a non-zero status.
`data` can be `null` when a tool succeeds but has no structured payload. If a tool produces no structured output, or if a pre-domain failure occurs (validation, schema, or runtime error before the tool executes), the response uses the generic error branch and the CLI exits with a non-zero status:

```json
{
"schema": "xcodebuildmcp.output.error",
"schemaVersion": "1",
"didError": true,
"error": "Parameter validation failed: Invalid parameters...",
"data": {
"category": "validation",
"code": "PARAMETER_VALIDATION_FAILED"
}
}
```

Domain failures still use their domain schema. For example, an attempted build that fails returns `xcodebuildmcp.output.build-result` with `didError: true` and build diagnostics in `data`.

## `--output jsonl`

Expand Down Expand Up @@ -133,7 +170,7 @@ Do not script against `raw`. The transcript is intentionally close to the underl

## Structured content for MCP clients

MCP mode always returns the normal `content` array. When a tool sets structured output, XcodeBuildMCP also attaches [`structuredContent`](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#structured-content) with the same shape as `--output json`.
MCP mode always returns the normal `content` array. When a tool sets structured output, XcodeBuildMCP also attaches [`structuredContent`](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#structured-content) with the same shape as `--output json`. Pre-domain failures — validation errors, schema mismatches, or runtime errors before the tool executes — also produce `structuredContent` using `schema: "xcodebuildmcp.output.error"`.

```json
{
Expand Down Expand Up @@ -178,7 +215,7 @@ MCP mode always returns the normal `content` array. When a tool sets structured
}
```

Tools that declare an [output schema](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#output-schema) also advertise it during MCP registration. Clients can use that schema to validate `structuredContent` or render typed UI.
Tools that declare an [output schema](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#output-schema) also advertise it during MCP registration. For tools with structured output, the advertised schema is a union of the tool's domain envelope and the generic `xcodebuildmcp.output.error` envelope. Clients can use that schema to validate `structuredContent` or render typed UI, but should still branch on the returned `schema` value at runtime.

## Response schema reference

Expand Down
Loading