Server-side do_get: implement do_get(self, context, ticket) to return a pyarrow.flight.RecordBatchStream wrapping a RecordBatchReader or a list of RecordBatches
Client-side do_get: call reader = client.do_get(ticket); table = reader.read_all() to receive the full stream, or iterate reader for batch-by-batch processing
Server-side do_put: implement do_put(self, context, descriptor, reader, writer) to read incoming batches with reader.read_chunk()
Use FlightDescriptor.for_command(bytes) or FlightDescriptor.for_path(list) to identify the data stream on both ends
Known gotchas
The do_put client-side writer must be explicitly closed (writer.close() or used as a context manager); leaving it open without closing can cause the server to hang waiting for the end-of-stream signal
Ticket contents are opaque bytes; the server must be able to decode them back to a meaningful query or table identifier — establish a clear serialization convention (e.g., JSON or Protobuf) before deployment
Schema negotiation happens at the start of do_put; if the client's schema does not match what the server expects, the server should raise a FlightServerError with a descriptive message rather than silently accepting mismatched data
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp