Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt

Use this file to discover all available pages before exploring further.

Meerkat exposes a JSON-RPC 2.0 surface for IDE integration, desktop apps, and automation tools. Stdio is the default, and the binary also supports TCP plus an optional live audio WebSocket listener (--live-ws). Unlike REST and MCP, the RPC server keeps agents alive between turns for fast multi-turn conversations. The RPC surface is fully runtime-backed:
  • keep_alive is runtime/session behavior
  • session/external_event queues runtime-backed external work
  • committed success is not rewritten to cancellation

Getting started

1

Start the server

rkat-rpc
The server reads newline-delimited JSON (JSONL) from stdin and writes JSONL to stdout. Each line is a complete JSON-RPC 2.0 message.Optional listener modes:
rkat-rpc --tcp 127.0.0.1:9001
rkat-rpc --tcp 127.0.0.1:9001 --live-ws 127.0.0.1:9002
TCP and live WebSocket listeners are local-only by default. Binding a non-loopback address such as 0.0.0.0:9001 requires --allow-remote; that flag only opts in to network exposure and does not add authentication or encryption. Use it behind a production-safe transport wrapper such as SSH tunneling, mTLS, or another authenticated encrypted channel. Plain TCP host capabilities continue to report secure_remote_rpc: false.
2

Send the handshake

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
3

Create a session

{"jsonrpc":"2.0","id":2,"method":"session/create","params":{"prompt":"Hello!"}}
rkat-rpc defaults to a new isolated realm each time. Use --realm <id> to share config/sessions with other surfaces or processes.

Runtime scope

rkat-rpc accepts global scope flags:
rkat-rpc [--realm <id>] [--isolated] [--instance <id>] [--realm-backend <sqlite|jsonl>] [--state-root <path>] [--context-root <path>] [--user-config-root <path>]
  • --realm: explicit sharing/isolation key
  • --instance: optional instance metadata
  • --realm-backend: creation hint only; actual backend is pinned per realm manifest

Method overview

This table mirrors the generated catalog in artifacts/schemas/rpc-methods.json (meerkat_contracts::rpc_method_catalog). initialize returns the methods enabled in the running binary, so reduced or feature-limited builds expose a subset.
MethodCategoryDescription
initializeHandshakeReturns server capabilities
help/askHelpAsk Meerkat usage help with the embedded platform skill
runtime/host_infoRuntimeRead host identity, endpoints, capabilities, health, and realm projection
runtime/capabilitiesRuntimeRead runtime host capability flags
runtime/healthRuntimeRead runtime host health
session/createSessionCreate session and run first turn
session/listSessionList active sessions
session/readSessionGet session state
session/historySessionGet committed session transcript messages
session/fork_atSessionFork an idle session at a transcript message index
session/fork_replaceSessionFork an idle session and apply a typed transcript replacement
blob/getSessionFetch a blob payload by id
artifact/listArtifactList stable artifact records
artifact/getArtifactGet one stable artifact record
artifact/downloadArtifactDownload blob-backed artifact payload bytes
approval/requestApprovalCreate a durable approval request
approval/listApprovalList approval records
approval/getApprovalGet one approval record
approval/decideApprovalRecord an approval decision
events/latest_cursorEventsRead the latest replay cursor for a typed event scope
events/list_sinceEventsList replayable events after a typed cursor
events/snapshotEventsRead a point-in-time snapshot with its replay cursor
session/archiveSessionRemove session from runtime
session/external_eventSessionQueue a runtime-backed external event
session/peer_response_terminalSessionAdmit a correlated terminal peer response through the typed runtime ingress
session/inject_contextSessionAppend runtime-backed system context to the next turn
turn/startTurnStart a new turn on existing session
turn/interruptTurnCancel in-flight turn
live/openLiveOpen a live audio/text channel for a session
live/webrtc/answerLiveAnswer a browser WebRTC offer for an already-open live channel
live/statusLiveGet the status of a live channel
live/closeLiveClose a live channel
live/send_inputLiveSend an input chunk (audio/text) to a live channel
live/commit_inputLiveCommit pending input on a live channel (turn boundary)
live/interruptLiveInterrupt the assistant turn on a live channel (barge-in)
live/truncateLiveTruncate assistant output at a client-tracked playback cursor
live/refreshLiveApply mutable session config (instructions/tools/audio) to an open live channel
session/stream_openSessionOpen a standalone session event stream
session/stream_closeSessionClose a standalone session event stream
mob/createMobCreate a mob from a definition (mob feature)
mob/listMobList mobs (mob feature)
mob/statusMobGet mob status (mob feature)
mob/membersMobList mob members (mob feature)
mob/spawnMobSpawn a member into a mob (mob feature)
mob/spawn_manyMobSpawn multiple members into a mob (mob feature)
mob/retireMobRetire a mob member (mob feature)
mob/respawnMobRespawn a mob member (mob feature)
mob/wireMobWire two mob members for comms (mob feature)
mob/unwireMobRemove mob comms wiring (mob feature)
mob/lifecycleMobStop, resume, complete, destroy, or reset a mob (mob feature)
mob/eventsMobRead mob events by cursor (mob feature)
mob/ingress_interactionMobEnsure an ingress member and deliver user input with replay anchors (mob feature)
mob/stream_openMobOpen mob or member event stream (mob feature)
mob/stream_closeMobClose mob or member event stream (mob feature)
mob/member_sendMobDeliver ordinary content to a specific mob member via the host control plane (mob feature)
mob/append_system_contextMobStage system context for a member session (mob feature)
mob/flowsMobList mob flows (mob feature)
mob/flow_runMobStart a mob flow run (mob feature)
mob/flow_statusMobGet flow run status (mob feature)
mob/flow_cancelMobCancel a flow run (mob feature)
mob/ensure_memberMobIdempotent spawn — returns existing entry if member already exists (mob feature)
mob/reconcileMobDeclarative roster reconcile against a desired spec list (mob feature)
mob/list_members_matchingMobLabel-filtered member listing with server-side filter (mob feature)
mob/spawn_helperMobSpawn a helper member and wait for its result (mob feature)
mob/fork_helperMobFork a helper from an existing member and wait for its result (mob feature)
mob/force_cancelMobForce-cancel a member’s active work (mob feature)
mob/turn_startMobStart a turn on a mob member by identity (mob feature)
mob/member_statusMobRead canonical status for a specific member (mob feature)
mob/snapshotMobPoint-in-time aggregate of mob status plus member list (mob feature)
mob/destroyMobDestroy a mob and surface the structured MobDestroyReport (mob feature)
mob/rotate_supervisorMobRotate the supervisor bridge for all members of a mob (mob feature)
mob/submit_workMobSubmit a unit of work to a mob member through the work lane (mob feature)
mob/cancel_workMobCancel a previously submitted unit of work (mob feature)
mob/cancel_all_workMobCancel all in-flight work for a mob member (mob feature)
mob/wait_kickoffMobWait for kickoff completion for a member (mob feature)
mob/wait_readyMobWait for mob startup readiness (members bound but kickoff not required, mob feature)
mob/profile/createMobCreate a realm-scoped mob profile (mob feature)
mob/profile/getMobRead a realm-scoped mob profile (mob feature)
mob/profile/listMobList realm-scoped mob profiles (mob feature)
mob/profile/updateMobUpdate a realm-scoped mob profile (mob feature)
mob/profile/deleteMobDelete a realm-scoped mob profile (mob feature)
schedule/createScheduleCreate a new schedule (schedule feature)
schedule/getScheduleGet a schedule by ID (schedule feature)
schedule/listScheduleList schedules (schedule feature)
schedule/updateScheduleUpdate a schedule (schedule feature)
schedule/pauseSchedulePause a schedule (schedule feature)
schedule/resumeScheduleResume a paused schedule (schedule feature)
schedule/deleteScheduleDelete a schedule (schedule feature)
schedule/occurrencesScheduleList occurrences for a schedule (schedule feature)
schedule/toolsScheduleList schedule tools (schedule feature)
schedule/callScheduleCall a schedule tool directly (schedule feature)
workgraph/getWorkGraphRead a WorkGraph item (workgraph feature)
workgraph/listWorkGraphList WorkGraph items (workgraph feature)
workgraph/readyWorkGraphList ready WorkGraph items (workgraph feature)
workgraph/snapshotWorkGraphRead a WorkGraph observability snapshot (workgraph feature)
workgraph/eventsWorkGraphRead WorkGraph event history (workgraph feature)
comms/sendCommsDispatch a comms command to a session
comms/peersCommsList discoverable peers (comms feature)
skills/listSkillsList skills with provenance
mcp/addMCPStage live MCP server addition (mcp feature)
mcp/removeMCPStage live MCP server removal (mcp feature)
mcp/reloadMCPReload one or all MCP servers (mcp feature)
models/catalogModelsList available models with capabilities and provider profiles
capabilities/getCapabilitiesRuntime capability report
config/getConfigRead current config
config/setConfigReplace config
config/patchConfigMerge-patch config (RFC 7396)
auth/profile/listAuthList auth profiles in a realm
auth/profile/getAuthGet one auth profile
auth/profile/createAuthCreate an auth profile (CLI-driven for now)
auth/profile/deleteAuthDelete an auth profile (CLI-driven for now)
auth/login/startAuthBegin interactive authorization-code OAuth (returns authorize_url + pkce_verifier)
auth/login/completeAuthExchange authorization code for tokens; persists to TokenStore
auth/login/device_startAuthBegin device-code OAuth; returns user_code + verification URL
auth/login/device_completeAuthSingle-poll completion for a device-code OAuth login
auth/login/provision_api_keyAuthConsole-OAuth → API key provisioning (Anthropic oauth_to_api_key)
auth/status/getAuthGet auth status for a profile
auth/logoutAuthRevoke + remove persisted credentials
realm/listRealmList realm summaries
realm/getRealmGet full realm connection set
Generated assistant images use the same surface-neutral history and blob APIs as other blob-backed artifacts. Read session/history, find assistant blocks with block_type: "image", then call blob/get with data.blob_ref.blob_id to retrieve the base64 payload.
Live channels provide low-latency audio/text streaming. Create a session with a realtime-capable model (e.g. gpt-realtime-2), then call live/open to start the channel. The --live-ws <addr> flag on rkat-rpc enables the WebSocket listener required for audio transport. Use live/status to observe channel state.
RPC is the canonical typed substrate for the SDKs: use explicit mob/* lifecycle, host-ingress, and observation methods from apps. Inside running sessions, mob capability is exposed by composing meerkat-mob-mcp (MobMcpState + AgentMobToolSurfaceFactory) into SessionBuildOptions.mob_tools, which provides authorized mob_* tools to the agent. external_tools remains for callback and MCP-backed tool dispatchers.
WorkGraph RPC methods are read-only observability. Programmatic hosts should inspect WorkGraph through workgraph/get, list, ready, snapshot, and events; agents mutate WorkGraph through the workgraph_* tools.

Protocol

Standard JSON-RPC 2.0 with "jsonrpc": "2.0" on every message. Three message types:
  • Request (client -> server): has id, method, params
  • Response (server -> client): has id, result or error
  • Notification (server -> client): has method, params, no id
Client                          Server
  |                                |
  |-- initialize ----------------->|
  |<-- result { capabilities } ----|
  |-- initialized (notification) ->|
  |                                |
  |-- session/create { prompt } -->|
  |<-- session/event (notif) ------|  // AgentEvent stream
  |<-- session/event (notif) ------|
  |<-- result { session_id, ... } -|
  |                                |
  |-- turn/start { session_id } -->|
  |<-- session/event (notif) ------|
  |<-- result { text, usage } -----|
  |                                |
  |-- turn/interrupt { sid } ----->|
  |<-- result {} ------------------|
  |                                |
  |-- session/archive { sid } ---->|
  |<-- result {} ------------------|

Session methods

initialize

Handshake. Returns server capabilities.
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
The actual array contains every method compiled into the server. For the full documented list and parameter/result type names, use artifacts/schemas/rpc-methods.json.
server_info.name
string
Server name.
server_info.version
string
Server version.
contract_version
string
Protocol contract version.
methods
array
List of supported method names.

session/create

Create a new session and run the first turn. Set initial_turn to "deferred" to return a pending session_id without running the first turn; that returned session_id is valid for the first turn/start, including sessions created with inline external_tools.
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "session/create",
  "params": {
    "prompt": "What is Rust?"
  }
}
Only prompt is required. All other fields are optional and fall back to config defaults. During execution, session/event notifications are emitted (see Notifications).

Parameter reference

prompt
string
required
The user prompt to send to the agent.
model
string | null
default:"claude-sonnet-4-6"
Model name (e.g. "claude-opus-4-6", "gpt-5.5").
provider
string | null
default:"inferred from model"
Provider name: "anthropic", "openai", "gemini", "self_hosted", "other".
max_tokens
u32 | null
default:"config default"
Max tokens per turn.
system_prompt
string | null
default:"null"
Override system prompt.
output_schema
object | null
default:"null"
JSON schema for structured output extraction (wrapper or raw schema).
structured_output_retries
u32
default:"2"
Max retries for structured output validation.
hooks_override
HookRunOverrides | null
default:"null"
Run-scoped hook overrides (entries to add, hook IDs to disable).
enable_builtins
bool
default:"false"
Enable built-in tools (task management, etc.).
enable_shell
bool
default:"false"
Enable shell tool (requires enable_builtins).
enable_memory
bool
default:"false"
Enable semantic memory (memory_search tool + compaction indexing).
enable_schedule
bool | null
default:"null"
Override schedule tools for this session. null uses the surface default.
enable_workgraph
bool | null
default:"null"
Override WorkGraph tools for this session. null uses the surface default.
keep_alive
bool | null
default:"null"
Keep session alive after turn for comms. null = inherit persisted session intent, true = enable, false = disable. Requires comms_name when enabled.
comms_name
string | null
default:"null"
Agent name for inter-agent communication.
provider_params
object | null
default:"null"
Provider-specific parameters (e.g., thinking config, reasoning effort).

Response fields

session_id
string
UUID of the created session.
text
string
The agent’s response text.
turns
u32
Number of LLM calls made.
tool_calls
u32
Number of tool calls executed.
usage
WireUsage
Token usage breakdown.
structured_output
object | null
Parsed structured output.
schema_warnings
array | null
Schema compatibility warnings.

session/history

Read committed transcript history for an existing session.
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "session/history",
  "params": {
    "session_id": "01936f8a-7b2c-7000-8000-000000000001",
    "offset": 0,
    "limit": 50
  }
}
Returns oldest-to-newest committed messages plus pagination metadata. This method follows the same owner-resolution rules as session/read, including mob-owned session IDs when mob support is enabled.

session/fork_at

Create a new idle session whose transcript is the source session prefix ending before message_index. The source session is not mutated.
{
  "jsonrpc": "2.0",
  "id": 8,
  "method": "session/fork_at",
  "params": {
    "session_id": "01936f8a-7b2c-7000-8000-000000000001",
    "message_index": 2,
    "running_behavior": "reject"
  }
}
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "source_session_id": "01936f8a-7b2c-7000-8000-000000000001",
    "session_id": "01936f8a-7b2c-7000-8000-000000000009",
    "message_count": 2
  }
}
running_behavior currently supports "reject", which returns SESSION_BUSY if the source session has active work.

session/fork_replace

Create a new idle session from the source prefix through message_index, replacing the addressed message or block with a typed replacement. Later source messages are intentionally omitted so callers continue from the edited branch instead of replaying stale descendants.
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "session/fork_replace",
  "params": {
    "session_id": "01936f8a-7b2c-7000-8000-000000000001",
    "message_index": 2,
    "replacement": {
      "type": "message",
      "message": {
        "role": "user",
        "content": "Edited follow-up"
      }
    },
    "running_behavior": "reject"
  }
}
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "source_session_id": "01936f8a-7b2c-7000-8000-000000000001",
    "session_id": "01936f8a-7b2c-7000-8000-000000000010",
    "message_count": 3
  }
}
Supported replacement variants are message, user_content_block, assistant_block, and tool_result_content_block. Edits always create a new session identity.

session/list

List active sessions.
{"jsonrpc":"2.0","id":3,"method":"session/list"}

session/read

Get session state.
{"jsonrpc":"2.0","id":4,"method":"session/read","params":{"session_id":"01936f8a-..."}}
session_id
string
required
Session ID to read.

session/archive

Remove a session from the runtime.
{"jsonrpc":"2.0","id":5,"method":"session/archive","params":{"session_id":"01936f8a-..."}}
session_id
string
required
Session ID to archive.

Turn methods

turn/start

Start a new turn on an existing session.
{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "turn/start",
  "params": {
    "session_id": "01936f8a-...",
    "prompt": "Can you explain ownership?",
    "skill_refs": [
      {
        "kind": "structured",
        "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
        "skill_name": "rust-patterns-ownership"
      }
    ]
  }
}
Returns the same result shape as session/create. Fails with error code -32001 (SESSION_BUSY) if a turn is already in progress.
session_id
string
required
Session ID to continue.
prompt
string
required
The follow-up prompt.
model
string | null
default:"from session"
Model override for this turn. On pending (deferred) sessions this sets the model before materialization. On materialized sessions this hot-swaps the LLM client for the remainder of the session.
provider
string | null
default:"from session"
Provider override (e.g. "anthropic", "openai", "gemini"). Typically inferred from model.
provider_params
object | null
default:"from session"
Provider-specific parameters (e.g. {"thinking_budget": 10000}). Applied alongside model/provider override.
max_tokens
u32 | null
default:"from session"
Max tokens override.
skill_refs
object[] | null
Tagged structured skill references to resolve and inject for this turn. Each entry uses {"kind":"structured","source_uuid":"...","skill_name":"..."}.

turn/interrupt

Cancel an in-flight turn. No-op if the session is idle.
{"jsonrpc":"2.0","id":7,"method":"turn/interrupt","params":{"session_id":"01936f8a-..."}}
session_id
string
required
Session ID to interrupt.

Event methods

session/external_event

Queue a runtime-backed external event for an existing session.
{
  "jsonrpc": "2.0",
  "id": 8,
  "method": "session/external_event",
  "params": {
    "session_id": "01936f8a-...",
    "kind": "generic_json",
    "event_type": "ci-pipeline",
    "payload": {"alert": "build failed", "repo": "main"}
  }
}

session/peer_response_terminal

Admit a correlated terminal peer response through the typed runtime ingress.
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "session/peer_response_terminal",
  "params": {
    "session_id": "01936f8a-...",
    "peer_id": "00000000-0000-4000-8000-000000000161",
    "display_name": "analyst",
    "request_id": "00000000-0000-4000-8000-000000000162",
    "status": "completed",
    "result": {"token": "silver harbor"}
  }
}
session_id
string
required
Session ID to admit the peer response to.
peer_id
string
required
Canonical peer routing ID.
display_name
string
Optional presentation label. It is not used as routing identity.
request_id
string
required
Peer correlation ID for the request this terminal response completes.
status
string
required
Terminal response status: "completed", "failed", or "cancelled".
result
any JSON
required
Peer-returned terminal payload.
Error -32603 if runtime admission fails, -32602 if the session locator is invalid. This is a queue-only runtime admission path; it does not create a second direct execution loop.

comms/peers

List discoverable peers from configured TrustedPeers and active in-process registrations. Requires the comms feature.
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "comms/peers",
  "params": {
    "session_id": "01936f8a-..."
  }
}
session_id
string
required
Session ID to query peers for.

skills/list

List all skills with provenance information, including active and shadowed entries.
{"jsonrpc":"2.0","id":12,"method":"skills/list"}
skills
array
List of SkillEntry objects with key, name, description, scope, canonical source provenance, is_active, and optional canonical shadowed_by provenance.
Returns error -32603 if skills are not enabled. skills/inspect is not part of the advertised RPC catalog. Use skills/list for provenance, or the CLI/MCP skill inspection surfaces when full skill bodies are needed.

Live channel methods

Live channels provide low-latency audio and text streaming on sessions that use a realtime-capable model. Create a session with a model like gpt-realtime-2, then call live/open to start the channel explicitly. The --live-ws <addr> flag on rkat-rpc enables the WebSocket listener required for audio transport. See the Live Channels guide for the full flow.

Opening a live channel

Create a session on a realtime-capable model and call live/open:
{
  "jsonrpc": "2.0",
  "id": 19,
  "method": "session/create",
  "params": {
    "prompt": "Let's talk.",
    "model": "gpt-realtime-2",
    "provider": "openai"
  }
}
{
  "jsonrpc": "2.0",
  "id": 20,
  "method": "live/open",
  "params": {
    "session_id": "01936f8a-7b2c-7000-8000-000000000001"
  }
}
live/open returns a LiveOpenResult with transport bootstrap (e.g. WebSocket URL), WireLiveChannelCapabilities, and WireLiveContinuityMode.

live/status

Read the current state of a live channel.
{
  "jsonrpc": "2.0",
  "id": 22,
  "method": "live/status",
  "params": {
    "channel_id": "ch_01936f8a-..."
  }
}

Live channel lifecycle methods (live/*)

MethodPurpose
live/openOpen a live audio/text channel for a session
live/webrtc/answerAnswer a browser WebRTC offer for an already-open live channel
live/statusGet the status of a live channel
live/closeClose a live channel
live/send_inputSend an input chunk (audio/text) to a live channel
live/commit_inputCommit pending input on a live channel (turn boundary)
live/interruptInterrupt the assistant turn on a live channel (barge-in)
live/truncateTruncate assistant output at a client-tracked playback cursor
live/refreshApply mutable session config (instructions/tools/audio) to an open channel; config-only, does not replay history; identity swaps (model/provider) require close + reopen
These require rkat-rpc to be started with --live-ws <addr> for WebSocket transport.

MCP methods

mcp/add

Stage a live MCP server addition for a running session. The server is connected at the next turn boundary.
{
  "jsonrpc": "2.0",
  "id": 14,
  "method": "mcp/add",
  "params": {
    "session_id": "01936f8a-...",
    "server_config": {
      "name": "my-tools",
      "command": "npx",
      "args": ["-y", "@my/mcp-server"]
    },
    "persisted": false
  }
}
session_id
string
required
Session ID to add the server to.
server_config
object
required
Typed MCP server configuration. Include name with either stdio fields (command, optional args/env) or HTTP fields (url, optional headers/transport).
persisted
bool
default:"false"
Whether to also write the server to disk config.

mcp/remove

Stage removal of an MCP server from a running session. Active tool calls drain before the server disconnects at the next turn boundary.
{
  "jsonrpc": "2.0",
  "id": 15,
  "method": "mcp/remove",
  "params": {
    "session_id": "01936f8a-...",
    "server_name": "my-tools",
    "persisted": false
  }
}
session_id
string
required
Session ID to remove the server from.
server_name
string
required
Name of the MCP server to remove.
persisted
bool
default:"false"
Whether to also remove from disk config.

mcp/reload

Reload one or all MCP servers for a running session. Useful after config changes.
{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "mcp/reload",
  "params": {
    "session_id": "01936f8a-...",
    "server_name": "my-tools"
  }
}
session_id
string
required
Session ID to reload servers for.
server_name
string | null
default:"null"
Specific server to reload. If null, reloads all servers.

Models

models/catalog

Return the curated model catalog with provider profiles, capability metadata, and parameter schemas.
{"jsonrpc":"2.0","id":17,"method":"models/catalog"}
No parameters are required. The catalog is resolved from built-in model metadata plus config-backed provider/server entries; invalid provider config can yield INVALID_PARAMS.
contract_version
string
Contract version for the catalog response.
providers
array
List of provider entries, each containing provider, default_model_id, and models.
providers[].models[].profile
object
Model profile with capability flags (supports_temperature, supports_thinking, supports_reasoning) and params_schema.

Capabilities

capabilities/get

Return runtime capabilities with status resolved against config. This lists every capability known to Meerkat with its current status (available, disabled by policy, not compiled, etc.).
{"jsonrpc":"2.0","id":8,"method":"capabilities/get"}
Possible status values:
StatusShapeMeaning
Available"Available"Compiled in, config-enabled, protocol supports it
DisabledByPolicy{"DisabledByPolicy": {"description": "..."}}Compiled in but disabled by policy
NotCompiled{"NotCompiled": {"feature": "..."}}Feature flag absent at compile time
NotSupportedByProtocol{"NotSupportedByProtocol": {"reason": "..."}}This protocol surface does not support it

Config methods

config/get

Read current realm config envelope.
{"jsonrpc":"2.0","id":9,"method":"config/get"}

config/set

Replace config, optionally using generation CAS.
{
  "jsonrpc":"2.0",
  "id":10,
  "method":"config/set",
  "params":{
    "config": {"agent":{"model":"gpt-5.5"}},
    "expected_generation": 3
  }
}

config/patch

Merge-patch the config (RFC 7396).
{
  "jsonrpc":"2.0",
  "id":11,
  "method":"config/patch",
  "params":{
    "patch":{"agent":{"max_tokens_per_turn":8192}},
    "expected_generation": 4
  }
}
config/set also accepts a direct config object as params for compatibility. In that mode, no CAS check is applied.

Notifications

During turn execution, the server emits session/event notifications containing serialized AgentEvent payloads:
{
  "jsonrpc": "2.0",
  "method": "session/event",
  "params": {
    "session_id": "01936f8a-...",
    "event": {
      "type": "text_delta",
      "delta": "Rust is"
    }
  }
}
Event types match the AgentEvent enum in meerkat-core:
EventDescription
run_startedAgent execution began
run_completedAgent run finished
run_failedAgent run failed
turn_startedNew LLM call within the turn
text_deltaStreaming text chunk from LLM
text_completeFull text for this turn
tool_call_requestedLLM wants to call a tool
tool_result_receivedTool result processed
turn_completedLLM call finished
tool_execution_startedTool dispatch began
tool_execution_completedTool returned a result
tool_execution_timed_outTool exceeded timeout
compaction_startedContext compaction began
compaction_completedCompaction finished
compaction_failedCompaction failed
budget_warningApproaching resource limits
retryingRetrying after transient error
hook_startedHook execution began
hook_completedHook finished
hook_failedHook execution failed
hook_deniedHook blocked operation
skills_resolvedSkills loaded for turn
skill_resolution_failedSkill resolution failed
tool_config_changedTool visibility or MCP config changed
background_job_completedBackground shell job reached a typed terminal status; terminal_status is semantic and status is only an optional display mirror
interaction_completeInteraction-scoped stream completed
interaction_callback_pendingInteraction reached a callback boundary and is waiting for tool results
interaction_failedInteraction-scoped stream failed
stream_truncatedBackpressure dropped intermediate events

session/stream_event notifications

When a session event stream is open (via session/stream_open), the server emits session/stream_event notifications. The notification payload mirrors session/event, but is scoped to the explicit stream handle.
{
  "jsonrpc": "2.0",
  "method": "session/stream_event",
  "params": {
    "stream_id": "550e8400-e29b-41d4-a716-446655440000",
    "sequence": 1,
    "session_id": "sess_123",
    "event": { "...": "..." }
  }
}

mob/stream_event notifications

When a mob event stream is open (via mob/stream_open), the server emits mob/stream_event notifications. Requires the mob feature.
{
  "jsonrpc": "2.0",
  "method": "mob/stream_event",
  "params": {
    "stream_id": "550e8400-e29b-41d4-a716-446655440000",
    "sequence": 1,
    "event": { "...": "..." }
  }
}
For mob-wide streams the event is an AttributedEvent (source member identity + profile + envelope). For per-member streams the event is the raw EventEnvelope<AgentEvent>. Runtime incarnation ids and fence tokens are bridge-internal and are not part of public stream payloads.

Error codes

Standard JSON-RPC codes plus Meerkat-specific application codes:
CodeNameDescription
-32700Parse errorInvalid JSON
-32600Invalid requestNot a valid JSON-RPC request
-32601Method not foundUnknown method
-32602Invalid paramsMissing or invalid parameters
-32603Internal errorServer error
-32001Session not foundSession ID does not exist
-32002Session busyTurn already in progress
-32003Session not runningSession not in running state
-32010Provider errorLLM provider issue (missing key, auth)
-32011Budget exhaustedResource limits reached
-32012Hook deniedHook blocked the operation
-32013Agent errorInternal agent error
-32020Capability unavailableRequired capability not available
-32021Skill not foundRequested skill does not exist
-32022Skill resolution failedSkill resolution error

Architecture

The RPC server is stateful: agents stay alive between turns. This is the key difference from REST (stateless per-request) and MCP (callback pattern).
Client (IDE, app) <--stdio JSONL--> RpcServer
                                       |
                                  MethodRouter
                                       |
                                  SessionRuntime
                                   /    |    \
                            Session  Session  Session
                             Task    Task     Task
                              |       |        |
                            Agent   Agent    Agent
                         (exclusive ownership)
Each session gets a dedicated tokio task that exclusively owns the Agent. This solves the cancel(&mut self) requirement without mutex. Commands (StartTurn, Interrupt, Shutdown) are sent via channels.
Backpressure: The notification channel is bounded. When the client reads slowly, the agent naturally slows down.

Comparison with other surfaces

CLIRESTMCPRPC
StatefulNoNoNoYes
StreamingstderrSSEOptionalJSONL notifications
Multi-sessionNoNoNoYes
CancellationCtrl+CN/AN/Aturn/interrupt
BidirectionalNoNo (SSE one-way)PartialYes

See also