Default handler simply logger.debug()’s each entry.
2 Progress Tracking (v2.3.5+)
Long‑running tools can call ctx.report_progress(p, total, msg). Clients receive ProgressEvents. Provide either:
Globalprogress_handler when instantiating the client.
Per‑call handler via call_tool(..., progress_handler=…).
Edge cases
total may be None → treat as unknown size.
Handler is invoked from transport thread—keep it non‑blocking.
3 Client‑Side LLM Sampling
Servers can delegate generation tasks to the caller’s local/remote model (useful for retrieval‑augmented workflows).
Handler Signature
Example with OpenAI Assistants API
If you return a SamplingResponse object you can attach tool‑calls or images (per MCP spec v1.7).
4 Dynamic Roots (Capability Hints)
Root URIs tell the server where it’s allowed to operate (file‑system scope, tenant boundary, etc.).
Real‑time Updates
Supply an async callback that returns the current root list—Hyperia will re‑poll when the server sends roots/request.
5 Auto‑Reconnect & Back‑off
Network transports can retry transient failures automatically.
Streamable HTTP includes idempotency keys on tools/call so safe to retry.
6 Chunk Streaming Handlers (v2.4.0)
For very large outputs, servers may stream TextContent chunks. Register a chunk_handler to receive partial data in real‑time (avoids buffering entire string).
When a chunk_handler is present, the return value of call_tool contains only the final chunk(s) (may be empty). Use chunk events for incremental UI.
7 Cancellation Tokens
Pass cancel_event (an asyncio.Event) to any call—flip it to abort client‑side; Hyperia sends tools/call/cancel upstream.
8 Custom Content Codecs
Need protobuf instead of JSON for binary blobs? Implement Codec and register globally:
Servers & clients negotiate via mime_type fields.
9 Putting It All Together
Now you have a fully‑featured client: live logs, progress bar, on‑device completions, abort switch, and streaming output.