Skip to main content
Output schemas make tool responses predictable. AI clients can know in advance what shape the data will have, enabling structured reasoning without parsing guesswork.
This page covers output schemas from the formal specification. See Route Tests for how output schemas are generated from captured responses.

Purpose

Without output schemas, an AI client calling a FlowMCP tool receives an opaque blob of JSON. Output schemas solve this by declaring the expected response shape at the route level:
  • AI clients can pre-allocate structured reasoning about response fields
  • Schema validators can verify handler output matches the declaration
  • Documentation generators can produce accurate response tables automatically

Route-Level Output Definition

Each route can optionally define an output field:
routes: {
    getTokenPrice: {
        method: 'GET',
        path: '/simple/price',
        description: 'Get current token price',
        parameters: [ /* ... */ ],
        output: {
            mimeType: 'application/json',
            schema: {
                type: 'object',
                properties: {
                    id: { type: 'string', description: 'Token identifier' },
                    symbol: { type: 'string', description: 'Token symbol' },
                    price: { type: 'number', description: 'Current price in USD' },
                    marketCap: { type: 'number', description: 'Market capitalization', nullable: true },
                    volume24h: { type: 'number', description: 'Trading volume (24h)' }
                }
            }
        }
    }
}
The output field lives in the main block and is part of the hashable, JSON-serializable schema surface.

Output Fields

FieldTypeRequiredDescription
mimeTypestringYesResponse content type
schemaobjectYesSimplified JSON Schema describing the data field
Both fields are required when output is present. If a route does not declare output, omit the entire field.

Supported MIME Types

MIME TypeDescriptionSchema type
application/jsonJSON response (default)object or array
image/pngPNG image, base64-encodedstring with format: 'base64'
text/plainPlain text responsestring

Standard Response Envelope

Every FlowMCP tool response is wrapped in a standard envelope:
{
    status: true,
    messages: [],
    data: { /* described by output.schema */ }
}
FieldTypeDescription
statusbooleantrue on success, false on error
messagesarrayEmpty on success, error descriptions on failure
dataobject or nullResponse payload on success, null on error
The output.schema describes only the data field when status: true. Schema authors do not declare the envelope — it is implicit and standardized.

Supported JSON Schema Subset

FlowMCP uses a deliberately constrained subset of JSON Schema:

Supported Keywords

KeywordDescriptionExample
typeValue type'string', 'number', 'boolean', 'object', 'array'
propertiesObject properties{ name: { type: 'string' } }
itemsArray item schema{ type: 'object', properties: {...} }
descriptionHuman-readable description'Current price in USD'
nullableCan be nulltrue
enumAllowed values['active', 'inactive']
formatSpecial format hint'base64', 'date-time', 'uri'

Intentionally Excluded Keywords

  • $ref — no schema references; output schemas are self-contained
  • oneOf, anyOf, allOf — no union types
  • required — all declared properties are informational
  • additionalProperties — APIs may return extra fields
  • pattern, minimum, maximum — no regex or range validation on output

Response Examples

Object Response

output: {
    mimeType: 'application/json',
    schema: {
        type: 'object',
        properties: {
            id: { type: 'string', description: 'Token identifier' },
            price: { type: 'number', description: 'Current price in USD' },
            marketCap: { type: 'number', description: 'Market cap', nullable: true }
        }
    }
}

Array Response

output: {
    mimeType: 'application/json',
    schema: {
        type: 'array',
        items: {
            type: 'object',
            properties: {
                name: { type: 'string', description: 'Protocol name' },
                tvl: { type: 'number', description: 'Total value locked in USD' }
            }
        }
    }
}

Nested Objects

Properties can be objects up to 4 levels deep:
output: {
    mimeType: 'application/json',
    schema: {
        type: 'object',
        properties: {
            token: {
                type: 'object',
                description: 'Token metadata',
                properties: {
                    name: { type: 'string', description: 'Token name' },
                    contract: {
                        type: 'object',
                        description: 'Contract details',
                        properties: {
                            address: { type: 'string', description: 'Contract address' },
                            verified: { type: 'boolean', description: 'Verification status' }
                        }
                    }
                }
            }
        }
    }
}

Image Response

output: {
    mimeType: 'image/png',
    schema: {
        type: 'string',
        format: 'base64',
        description: 'Chart image as base64-encoded PNG'
    }
}

Text Response

output: {
    mimeType: 'text/plain',
    schema: {
        type: 'string',
        description: 'Raw contract source code'
    }
}

Nullable Fields

Fields that may be null in a successful response must declare nullable: true:
properties: {
    marketCap: { type: 'number', description: 'Market cap', nullable: true },
    website: { type: 'string', description: 'Project URL', nullable: true }
}
This helps AI clients differentiate between “field not available” (nullable) and “field should always be present” (not nullable).

Format Hints

FormatDescriptionExample Value
base64Base64-encoded binary data'iVBORw0KGgo...'
date-timeISO 8601 date-time'2026-02-16T12:00:00Z'
uriValid URI'https://etherscan.io/address/0x...'
Format is informational — the runtime does not validate format compliance.

Output Schema and Handlers

When a route has a postRequest handler, the output schema describes the final response after handler transformation, not the raw API response.
  • The output.schema describes the shape after postRequest transforms the data
  • If postRequest flattens nested responses, the schema describes the flat structure
  • If no postRequest handler exists, the schema describes the raw API response

Non-Blocking Validation

Output schema validation is non-blocking. A mismatch between the actual handler output and the declared schema produces a validation warning, not an error. The response is still delivered. This design reflects reality: external APIs may change response shapes without notice. A strict error would break the tool even though the data might still be usable.