Skip to main content
The Python SDK (meerkat-sdk) is a runtime-backed client over rkat-rpc.
  • Contract version: 0.8.33
  • Python: >=3.10
  • Runtime dependencies: websockets>=12,<16

Install

For local development:

Quick start

Method overview

Session lifecycle

  • await client.create_session(...) -> Session
  • client.create_session_streaming(...) -> EventStream
  • await client.create_deferred_session(...) -> DeferredSession
  • await client.list_sessions(...) -> list[SessionSummary]
  • await client.read_session(session_id) -> SessionDetails
  • await client.read_session_history(session_id, offset=0, limit=None) -> SessionHistory

Session runtime inputs

  • await client.inject_context(session_id, text, source=None, idempotency_key=None)
  • await session.inject_context(...)
  • await client.send_external_event(session_id, event_type, payload, blocks=None)
  • await session.send_external_event(event_type, payload, blocks=None)

Turn APIs

Session.turn(...), Session.stream(...), and DeferredSession.start_turn(...) support:
  • injected_context, transient_turn_context
  • skill_refs, turn_tool_overlay
  • additional_instructions
  • keep_alive, model, provider, self_hosted_server_id, max_tokens, system_prompt
  • output_schema, structured_output_retries, provider_params
Immediate session creation also accepts injected_context, transient_turn_context, auth_binding, the schedule/WorkGraph/web-search feature toggles, and a typed system-prompt override. Deferred creation accepts the same durable setup except transient_turn_context; supply request-only host facts to DeferredSession.start_turn(...) instead. Injected context becomes ordered user-channel context immediately before the prompt. Transient turn context is not durable transcript history.

Config APIs

  • await client.get_config() -> ConfigEnvelope
  • await client.set_config(config, expected_generation=None) -> ConfigWriteResult
  • await client.patch_config(patch, expected_generation=None) -> ConfigWriteResult
All config APIs return an envelope (config, generation, realm metadata), not a bare config object; writes additionally carry live_propagation.

Additional runtime surfaces

  • await client.get_models_catalog()
  • await client.create_schedule(...)
  • await client.get_schedule(...)
  • await client.list_schedules(labels=None, limit=None, offset=None)
  • await client.update_schedule(...)
  • await client.pause_schedule(...)
  • await client.resume_schedule(...)
  • await client.delete_schedule(...)
  • await client.list_schedule_occurrences(...)
  • await client.list_schedule_tools()
  • await client.call_schedule_tool(...)

WorkGraph observability

WorkGraph mutation remains agent-owned through tools. Host SDK callers can inspect the graph and its goal/attention projections:
  • await client.get_workgraph_item(...)
  • await client.list_workgraph_items(...)
  • await client.list_ready_workgraph_items(...)
  • await client.get_workgraph_snapshot(...)
  • await client.list_workgraph_events(...)
  • await client.get_workgraph_goal_status(...)
  • await client.list_workgraph_attention(...)

Jobs, approvals, artifacts, and projected event replay

  • detached jobs: jobs_get, jobs_list, jobs_cancel, jobs_progress, jobs_result, jobs_artifacts, jobs_retry, jobs_health, jobs_subscribe, jobs_unsubscribe
  • monitors: monitors_start
  • MobKit workers: mobkit_job_heartbeat, mobkit_job_progress, mobkit_job_checkpoint, mobkit_job_complete, mobkit_job_fail, mobkit_job_cancel_ack
  • approvals: request_approval, list_approvals, get_approval, decide_approval
  • artifacts: list_artifacts, get_artifact, download_artifact
  • projected events: latest_event_cursor, list_events_since, event_snapshot when host event projection is enabled
Approval methods maintain audit records only. Requesting or deciding a record does not automatically gate, authorize, or execute an action. Records persist when the RPC bundle exposes a store path. See JSON-RPC approvals. Every public Python RPC wrapper binds its request and result transport boundary to generated RPC-schema contracts. For the families above, the generated parameter and result class names in 0.8.24 are imported from meerkat.generated.types rather than re-exported at the package root.

Transcript history, revisions, and recovery

  • input_state(...) reconciles an admitted input by input id or idempotency key
  • export_session_atif(...) exports a session trajectory
  • read_session_transcript_revision(...) and list_session_transcript_revisions(...) inspect durable revisions
  • fork_session_at(...) and fork_session_replace(...) create a new branch
  • rewrite_session_transcript(...), update_system_prompt(...), and restore_session_transcript_revision(...) perform guarded edits

Live channel APIs

The old RealtimeChannel helper has been removed. Use LiveChannel.session(...) for a session-bound wrapper, or call the direct live/* RPC helpers on MeerkatClient.
For WebSocket instead, connect with live_ws=True and request transport="websocket"; only that bootstrap has a URL. The server exposes one offer-to-answer exchange and no candidate-trickle RPC. Install the returned answer_sdp as the browser peer’s remote description.
live_webrtc=True passes the --live-webrtc process flag, which exists only when rkat-rpc was compiled with its non-default live-webrtc Cargo feature. The 0.8.24 auto-downloaded release binary and a normal default-feature build do not include that flag. From the Meerkat repository, build an explicit binary with ./scripts/repo-cargo build -p meerkat-rpc --features live-webrtc, then put it on PATH or pass its path as MeerkatClient(rkat_path).
  • await client.live_open(session_id, turning_mode=None, transport=None, seed_max_chars=None)
  • await client.live_webrtc_answer(channel_id, token, offer_sdp)
  • await client.live_status(channel_id)
  • await client.live_close(channel_id)
  • await client.live_send_input_text(channel_id, text)
  • await client.live_send_input_audio(channel_id, data_base64, sample_rate_hz, channels)
  • await client.live_send_input_image(channel_id, idempotency_key, mime, data_base64)
  • await client.live_send_input_video_frame(channel_id, codec, data_base64, timestamp_ms)
  • await client.live_commit_input(channel_id, response_modality=None)
  • await client.live_interrupt(channel_id)
  • await client.live_truncate(channel_id, item_id, content_index, audio_played_ms)
  • await client.live_refresh(channel_id)
Image keys are required, caller-stable, and session-scoped. The helper returns after queue acceptance; wait for user_content_committed with the matching key before treating the image as durable context. See Live Channels for replay, conflict, and reconnect limits. seed_max_chars is an optional positive serialized-character budget for a core-selected whole-turn seed suffix. Omit it for the full canonical seed. Every ordered System message must fit. Runtime context and complete image identity, tombstone, and accounting sidecars remain outside the window; any truncation reports degraded continuity. Zero is rejected by the server.

Mob APIs

  • await client.create_mob(...) -> Mob
  • await client.list_mobs()
  • await mob.spawn(...)
  • await mob.spawn_many(...)
  • await mob.read_events(after_cursor=0, limit=100)
  • await mob.wait_for_kickoff_complete(...)
  • await mob.spawn_helper(..., result_label=..., max_text_bytes=..., role_name=...)
  • await mob.fork_helper(..., result_label=..., max_text_bytes=..., role_name=...)
  • host/grant control: mob.hosts(), mob.route_installs(), mob.bind_host(...), mob.revoke_host(...), mob.grant_scopes(...), mob.revoke_scopes(...), mob.grants()
  • remote member control: mob.hard_cancel(...), member history, member live open/status/control/close, and member/mob event subscriptions
Multi-host placement and host/grant mutations are trusted operator APIs on the JSON-RPC SDK surface. They are intentionally not exposed as agent-callable mob tools. The agent-callable spawn wire also cannot declare the Rust-only resume_from_role durable role-migration authority.

Realm profile CRUD

  • await client.create_mob_profile(name, profile)
  • await client.get_mob_profile(name) -> StoredMobProfile | None
  • await client.list_mob_profiles()
  • await client.update_mob_profile(name, profile, expected_revision=...)
  • await client.delete_mob_profile(name, expected_revision=...)

Additional wrappers

The Python client also exposes:
  • realm helpers: list_realms(), get_realm(...)
  • auth helpers: list_auth_profiles(...), get_auth_profile(...), create_auth_profile(...), delete_auth_profile(...), auth_login_*, auth_provision_api_key(...), auth_status(...), auth_logout(...)
  • blob/skill/MCP helpers: get_blob(...), list_skills(), mcp_add(...), mcp_remove(...), mcp_reload(...)
  • comms helpers: session.send(...), session.peers()
  • typed ingress helpers: send_peer_response_terminal(...)
  • runtime host inspection: get_runtime_host_info(), get_runtime_host_capabilities(), get_runtime_host_health()
Auth profiles and credentials are realm-scoped. Login/provisioning yields an auth binding that sessions and mob member specs can reference without carrying the provider secret itself; a remote member host resolves the binding within its authorized realm.

Generated assistant images

When a session model calls the built-in generate_image tool, generated images appear in committed history as SessionAssistantBlock entries with block_type == "image". The SDK preserves image_id, blob_id, media_type, width, height, revised_prompt, and provider metadata.
Image-generation wire contracts are also exported for integrations that inspect tool results directly: WireGenerateImageRequest, WireGenerateImageExecutionPlan, WireImageGenerationToolResult, WireImageOperationPhase, and WireAssistantImageRef.

Typed session metadata

  • SessionSummary (from session/list) includes total_tokens
  • SessionDetails (from session/read) includes model, provider, last_assistant_text
  • both use integer unix timestamps for created_at / updated_at

Streaming model

EventStream is an async context manager returned by session.stream() and client.create_session_streaming(). Iterate it to receive typed event dataclasses, then read events.result.
TurnCompleted.usage is optional. Absence means the provider supplied no normalized accounting for that call; skip the row instead of treating it as zero.
The generated 0.8.24 inventory has eight event types with no handwritten parser case, so they arrive as UnknownEvent. Current Rust server_tool_content and transcript_rewrite_audit_receipt_committed are missing from that inventory and are rejected as UNKNOWN_EVENT_TYPE. RunStarted, RunFailed, Retrying, and HookFailed also retain legacy parser field shapes and can arrive malformed. See the reference page for the exact list; do not treat these SDK fallbacks as alternate wire contracts.