Skip to main content
Model Context Protocol (MCP) is the tool protocol Meerkat uses in two ways: as a client calling external MCP servers for tools, and as a server exposing itself as MCP tools for other clients.

Getting started as a client

1

Add an MCP server

2

Verify it's registered

3

Use it in a session

The agent will automatically discover and use tools from registered MCP servers.

Tool overview (server mode)

The meerkat-mcp-server crate exposes Meerkat as MCP tools that other clients can call. meerkat_run and meerkat_resume keep the same public MCP tool contract, but their execution path is runtime-backed: meerkat_run allocates a session through the shared session service and waits for that admitted turn to finish, and meerkat_resume re-enters the same session_id instead of starting a second surface-local execution loop. The base MCP tool surface below is declared and dispatched in the meerkat-mcp-server crate (crates/meerkat-mcp-server/src/lib.rs), which is the source of truth for tool names and availability.
Default rkat-mcp builds are driven by the crate feature set. The base/default tool surface includes core session/config/history/blob/skills tools and schedule and WorkGraph tools. Mob tools appear when the mob feature is compiled in. The WorkGraph Flow tools are advertised only by hosts that also configure a WorkGraph service. Their shared Mob runtime bridge owns reconciliation; MCP is only the transport adapter. Flow status carries a redacted reverse execution-binding reference when the run was launched by the bridge. Public binding views omit activation parameters, idempotency and correlation values, and execution principals.
When the mob feature is enabled, the public MCP host surface uses typed meerkat_mob_* control-plane tools. Inside running sessions, mob capability is still agent-side and comes from composing a mob tools factory into SessionBuildOptions.mob_tools, which provides mob_* tools to the model. Public host MCP surfaces should not re-export that raw dispatcher.
The multi-host console family adds the three observation tools only. Existing meerkat_mob_spawn and meerkat_mob_spawn_many mutations may carry placement for an already-bound host. Host admin (bind_host/revoke_host), grant admin (grant_scopes/revoke_scopes/grants), hard cancel, and member live-channel verbs remain deliberately absent — MCP servers are routinely wired into agent tool contexts, and an LLM-reachable admin mutation would be a privilege-escalation vector. Host/grant/live admin lives on JSON-RPC/SDK plus CLI; hard cancel is JSON-RPC/SDK-only. Unknown tool names fail closed.
resume_from_role is not accepted by meerkat_mob_spawn, spawn-many, helper, or profile tools. Durable member role migration is a one-request trusted-host operation available only to in-process SpawnMemberSpec and the private member-host materialization protocol. It is not an MCP permission or a standing profile setting.

Surface boundaries

The MCP server deliberately does not mirror every operator API: Session event streams are bounded live subscriptions. If a consumer falls behind, the stream yields the typed stream_truncated event with a StreamLagged dropped count and then continues with retained events. That is a live-delivery gap, not an EventStore projection result. Built-in realm-backed persistent sessions can feed a separate durable audit projector whose unbounded queue is independent of the UI ring. That projection is asynchronous derived state, so reconcile available replay/snapshot evidence with current session state when completeness matters.

Use MCP servers as tools (client)

Use the rkat mcp commands to manage MCP servers:

Config file format

MCP servers are stored in TOML in two scopes:
  • Project: .rkat/mcp.toml
  • User: ~/.rkat/mcp.toml
Project config wins on name collisions.
Supported transports: stdio, streamable HTTP (default for URLs), and SSE. Environment variables in config use ${VAR_NAME} syntax.
For OAuth-protected streamable HTTP servers, keep config simple. Add the URL with rkat mcp add, then run rkat mcp login <name> for an explicit browser login, or rkat run "..." --mcp-auth interactive to allow first-use browser auth during an interactive TTY run. Normal runs default to --mcp-auth stored.

Meerkat as an MCP server

Connecting other clients

You can connect any MCP-capable client to a Meerkat MCP server. Run a server process that exposes the meerkat_* tools (stdio or HTTP), then point the client at it.
Claude Code reads MCP servers from a .mcp.json file in your project root. Example stdio config:

Hosting the MCP server

meerkat-mcp-server is a library crate that provides tool schemas and handlers. For a full public MCP host, serve MeerkatMcpState::advertised_tools_list() from the same state used by the handle_tools_call* entrypoints, or run the bundled rkat-mcp binary. This instance-filtered catalog omits unavailable runtime tools, such as skills when no skill runtime is installed. meerkat_mcp_server::tools_list() is the static composable definition catalog, not the ready-to-serve instance catalog. For a mob-only MCP host, meerkat-mob-mcp exposes public_tools_list() and handle_public_tools_call() for the typed meerkat_mob_* control plane. meerkat-mob-mcp::tools_list() and handle_tools_call() remain the internal agent-side mob_* dispatcher helpers; they are not the public host contract. The bundled rkat-mcp binary supports the complete runtime scope flags:
If --realm is omitted, the server creates a new isolated realm by default. --realm-backend is a creation hint only; after the first open, the manifest-pinned backend is authoritative. The bundled binary is stdio-only. If an embedding host publishes these tools over HTTP, that host owns transport authentication, authorization, and encryption; provider auth bindings configure outbound model credentials and do not authenticate inbound MCP callers.

Logging

rkat-mcp writes trace events to stderr only; stdout carries nothing but the MCP JSON channel. The default filter is info, which is what makes the verbose parameter of meerkat_run and meerkat_resume produce output. RUST_LOG replaces the default (RUST_LOG=warn keeps only warnings and errors; a blank value is treated as unset), and a value that does not parse is reported on stderr before the default applies, so an operator’s typo is never swallowed. Clients that capture stderr see these lines; nothing changes on stdout.

Request cancellation

The bundled server accepts MCP’s notifications/cancelled notification. While a tools/call request with JSON-RPC ID 2 is in flight, send:
Client -> server notification
requestId must be the original request’s exact ID, preserving its number/string type, not a session ID. This notification has no id and receives no response. It can cancel an uncommitted meerkat_run request before creation has returned a session identity. For example, cancellation before response publication can resolve that original request as:
Server -> client response to the original request
Cancellation does not roll back committed work: committed success is not rewritten to cancellation. This request lifecycle operation is distinct from meerkat_interrupt, which targets an existing session’s turn. Raw Meerkat JSON-RPC instead uses cancel with request_id; do not interchange those transport spellings.

Event streaming

Push notifications

Set stream: true on meerkat_run or meerkat_resume:
tools/call request
The bundled server emits MCP notifications/message messages while the request runs:
Push notification
The agent event is a full EventEnvelope<AgentEvent>; inspect params.data.event.payload, not params.data.event.type. Notifications have no request ID and do not replace the final tools/call response. A failure to serialize an event instead emits level: "error" with data.error: "event_serialization_failed" and data.message.

Pull streams: open, read, close

Pull streams are independent tool handles, not push notifications. Invoke these names via tools/call: The three mob tools require the mob feature. Each pull-tool result wraps its payload as JSON text in result.content[0].text; parse that string once. For example:
Read with flat timeout fields (there is no nested timeout object):
Read session stream
timeout_ms is an optional non-negative millisecond count. Omission/null uses the production default of 5000 ms; no_timeout defaults to false. no_timeout: true waits indefinitely and takes precedence even if timeout_ms is also supplied. Mob reads use the same flat fields with meerkat_mob_event_stream_read and the mob stream’s returned ID. The decoded read payload has one of three statuses:
A timeout leaves the handle open for the next read. Exhaustion returns closed and removes the handle; another read then fails as not found. Session and per-member reads carry an EventEnvelope<AgentEvent> directly under event. Omit member_id to open a mob-wide stream: its events are AttributedEvent values with member attribution and a nested envelope, so the agent payload is at event.envelope.payload instead of event.payload. Close a handle when finished:
For a mob handle, use meerkat_mob_event_stream_close with its stream_id. closed: true means this call removed the handle; false means it was already absent. Close results use a boolean, unlike a read’s status: "closed".

Tool reference

meerkat_run

Start a new Meerkat agent session with the given prompt.

Parameter reference

string
required
User prompt for the agent.
string | null
default:"null"
Override system prompt.
string | null
default:"config default"
Model name (e.g. "claude-opus-4-8", "gpt-5.5").
u32 | null
default:"config default"
Max tokens per turn.
string | null
default:"inferred"
Explicit MCP override vocabulary: "anthropic", "openai", "gemini", or "other". "self_hosted" is not an accepted explicit token here. Omission/null still permits configured model/binding resolution, including configured self-hosted routes; accepting "other" does not guarantee an operational custom provider.
WireAuthBindingRef | null
default:"null"
Optional structural credential selector, for example {"realm":"prod","binding":"anthropic","profile":"claude_oauth"}. realm and binding are required when supplied; profile is optional. Configure the referenced realm, binding, and auth profile first. Omission/null lets the create resolver select credentials. This is not a colon-delimited CLI string and does not accept server-owned provenance. It is a meerkat_run selector, not a new meerkat_resume field.
object | null
default:"null"
JSON schema for structured output (wrapper or raw schema).
u32 | null
default:"null"
Max retries for structured output validation. Omit / null to use the product default on run or inherit the persisted session value on resume.
bool
default:"false"
Stream agent events via notifications/message; see event streaming for the envelope and pull-stream tools.
bool
default:"false"
Enable verbose event logging (server-side).
array
default:"[]"
Tool definitions for the agent (see McpToolDef schema below).
bool | null
default:"null"
Builtins override. Omit / null to use the default on run or inherit the persisted session value on resume.
object | null
default:"null"
Config for builtins (only used when enable_builtins is true).
bool | null
default:"null"
Shell-tools override. Omit / null to use the default on run or inherit the persisted session value on resume.
u64 | null
default:"30"
Default shell command timeout.
bool | null
default:"null"
Keep session alive after turn for comms. On meerkat_run, null/omitted uses the run default (false), true enables, and false explicitly disables. Requires comms_name when enabled.
string | null
default:"null"
Agent name for comms.
HookRunOverrides | null
default:"null"
Run-scoped hook overrides.

McpToolDef schema

string
required
Tool name.
string
required
Tool description.
object
required
JSON Schema for tool input.
string | null
default:"callback"
Handler type ("callback" = result provided via meerkat_resume).
When tools with handler: "callback" are provided and the agent requests a tool call, the response includes pending_tool_calls. The MCP client must execute the tool and provide results via meerkat_resume.

meerkat_resume

Resume an existing runtime-backed session or provide tool results for pending tool calls. The call waits for the resumed turn to complete and returns the same session_id that meerkat_run originally materialized.
Decode the pending payload from content[0].text. It is a control result with status: "pending_tool_call", session_id, resumable: true, pending_tool_calls, and human-readable content, not a completed-run payload. A session_ref may be present when assigned by the surface; session_created: true, when present, says that the suspended request created the session (false is omitted). Do not infer successful-run counters from a pending result. Echo each provider-issued tool_use_id exactly in tool_results, as tc_abc123 is echoed above. Never correlate by tool name or array position, even when several pending calls invoke the same tool.

Parameter reference

string
required
Session ID to resume.
string
required
Follow-up prompt (can be empty when providing tool results).
bool
default:"false"
Stream agent events via notifications/message; see event streaming.
bool
default:"false"
Enable verbose event logging.
array
default:"[]"
Tool definitions (should match the original run).
array
default:"[]"
Tool results for pending tool calls.
string
required
Exact provider-issued tool_use_id from the matching pending call.
string
required
Result content (or error message).
bool
default:"false"
Whether this is an error result.
bool | null
default:"null"
Builtins override. Omit / null to inherit the persisted session value.
object | null
default:"null"
Builtin tool config.
bool | null
default:"null"
Shell-tools override. Omit / null to inherit the persisted session value.
bool | null
default:"null"
Keep-alive override for this resume. null = inherit persisted session intent, true = enable, false = disable.
meerkat_run and meerkat_resume follow the same commit/cancel rule as the other interactive surfaces: committed success is not rewritten to cancellation, and post-commit create failure returns session identity so the session can be resumed.
string | null
default:"from session"
Agent name for comms.
string | null
default:"from session"
Model override. On materialized sessions this hot-swaps the LLM client for the remainder of the session.
u32 | null
default:"from session"
Max tokens override.
string | null
default:"from session"
Provider override for mid-session switching with model: "anthropic", "openai", "gemini", or "other", as on meerkat_run. Omission/null permits normal model/binding resolution; "self_hosted" is not an accepted explicit token.
HookRunOverrides | null
default:"null"
Run-scoped hook overrides.

Response format

Both meerkat_run and meerkat_resume return MCP-standard tool results. Parse the JSON-encoded content[0].text payload. Completed runs contain the fields below; callback-pending control results use the distinct shape above.
array
MCP content blocks with the agent’s text.
string
Session ID (save for meerkat_resume).
u32
Number of LLM calls made.
u32
Number of tool calls executed.
JSON | null
Parsed structured output when extraction succeeds, or explicit null.
ExtractionError | null
Post-turn extraction failure details, or explicit null. The object has last_output (the committed main-turn assistant text extraction tried to transform), attempts (number of extraction attempts), and reason (human-readable failure description).
array | null
Schema compatibility warnings.
The main turn can successfully return committed text in content even if post-turn extraction fails. Inspect both structured_output and extraction_error; missing structured output does not prove extraction was never requested. Unlike REST/RPC WireRunResult, the MCP completed-run inner payload includes explicit null values for these absent optional fields; the outer MCP text wrapper remains unchanged.

meerkat_config

Get or update realm config for this MCP server instance.
string
required
One of "get", "set", "patch".
object | null
Full config to replace (for set action).
object | null
RFC 7396 merge-patch delta (for patch action).
u64 | null
Optional optimistic concurrency check for set and patch.
Response includes config envelope fields:
  • config
  • generation
  • realm_id
  • instance_id
  • backend
  • resolved_paths (only when the server runs with --expose-paths)
The MCP surface returns only the ConfigEnvelope shown above. It does not carry the live_propagation field: that is part of the richer JSON-RPC ConfigWriteResult contract, which reports the per-channel hot-swap / refresh / close outcome (swapped, skipped, swap_failed, refreshed, closed, refresh_failed, close_failed) when a set/patch write fans out to live channels. Use the JSON-RPC config/set / config/patch methods when you need the typed live-propagation report.

meerkat_capabilities

Returns the runtime capability set with status resolved against config.
Possible status values:

meerkat_models_catalog

Return the curated model catalog with provider profiles, capability metadata, and parameter schemas.
No parameters required. The catalog is resolved from built-in model metadata plus config-backed provider/server entries.

meerkat_skills

List available skills with provenance information, or inspect one skill’s full body by typed SkillKey.
string
required
"list" to list all skills, or "inspect" to load one skill’s full body.
object
Required for inspect. The typed skill identity with source_uuid and skill_name fields.
string
Optional source UUID selector for inspect; omit it to load the canonical source for skill_key.
The list response includes both active and shadowed skills. Shadowed skills have is_active: false and a shadowed_by field indicating which source has precedence. Inspect canonicalizes skill_key through the identity registry before loading the body.