Meerkat provides a shared agent runtime, not a fixed agent user experience. Its Rust crates own agent execution, typed events, providers, tools, persistence, runtime control, and multi-agent orchestration. The CLI, REST, JSON-RPC, MCP, Python, TypeScript, and browser/WASM surfaces use those same contracts.
Quick Start
brew install lukacf/meerkat/rkat
export RKAT_OPENAI_API_KEY="sk-..."
rkat run "What is the capital of France? Answer in one sentence."
The Homebrew tap supports macOS and Linux. Other installation paths:
cargo install rkat
pip install meerkat-sdk
npm install @rkat/sdk
npm install @rkat/web
Release archives contain rkat, rkat-rpc, rkat-rest, and
rkat-mcp. The Python and TypeScript SDKs resolve and can download a
compatible rkat-rpc automatically.
| Provider | Resolution order |
|---|---|
| Anthropic | RKAT_ANTHROPIC_API_KEY, ANTHROPIC_API_KEY |
| Public OpenAI | RKAT_OPENAI_API_KEY, OPENAI_API_KEY |
| Gemini | RKAT_GEMINI_API_KEY, GEMINI_API_KEY, RKAT_GOOGLE_API_KEY, GOOGLE_API_KEY |
| Azure OpenAI | Prefixed key + endpoint pair, then AZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT |
If both public OpenAI and only unprefixed Azure variables are present, public OpenAI wins. Setting either prefixed Azure selector makes a complete prefixed or fallback Azure key/endpoint pair the OpenAI environment default.
Meerkat's OpenAI/global catalog default is gpt-6-astra. Explicit model and
binding defaults are preserved. Catalog support does not guarantee access for
an API organization or support through Azure, Copilot, or custom backends.
Select an available model explicitly when needed:
rkat run --model gpt-5.5 "Explain async/await"
Use another provider by selecting a matching catalog model:
rkat run --model claude-sonnet-4-6 "Explain async/await"
rkat run --model gemini-3.8-flash "Explain async/await"
rkat models
Render a requested HTML artifact in the browser:
rkat run --browser \
"Create a one-page comparison of the REST, JSON-RPC, and MCP surfaces"
Share State Across Processes
The CLI derives a stable workspace realm by default. Bare server/SDK launches use fresh isolated realms. Pass one explicit ID when several surfaces should share sessions and config:
rkat --state-root /srv/meerkat/realms --realm team-alpha run "Draft a release note"
rkat-rpc --state-root /srv/meerkat/realms --realm team-alpha
The processes must also resolve the same physical storage provider/root. Realm identity alone does not make two unrelated host filesystems shared.
Use Persisted Credentials
rkat auth login openai
rkat auth profiles
rkat run --model gpt-5.6-sol \
--auth-binding global:openai_oauth \
"Summarize this pull request"
rkat auth login provisions the home-rooted global realm, which
workspace realms inherit. Interactive OpenAI login uses the ChatGPT OAuth
backend; openai_api API keys and ChatGPT/Codex subscription credentials are
separate account surfaces and can expose different model sets.
rkat auth login copilot uses GitHub device authorization and creates
OpenAI-, Anthropic-, and Gemini-family Copilot routes backed by one shared
github_copilot credential account. Account model availability is discovered
dynamically; the Meerkat catalog remains provider/model authority.
See the quickstart, auth guide, and realm guide for the full setup path.
What Meerkat Provides
Agent Execution
The core loop handles streaming model calls, parallel tool batches, structured output, retries, budgets, compaction, interrupts, and typed terminal outcomes. Persistent sessions expose committed history separately from in-flight events, and one session runs at most one turn at a time.
Key lifecycle models are checked with TLC against declared invariants and connected to generated runtime authority. Schema/runtime parity gates and integration tests complement those bounded checks, whose scope is the declared models rather than arbitrary Rust composition.
Realms, Config, And Storage
A realm scopes sessions, config, auth bindings, runtime state, schedules, WorkGraph, jobs, blobs, artifacts, and mob state. Built-in SQLite persists all seven realm storage domains. JSONL persists sessions plus SQLite-backed runtime, WorkGraph, and job state and filesystem blobs/artifacts, but deliberately disables scheduling. Memory is explicitly ephemeral. External storage providers must declare durability for every required domain and fail closed on an undeclared non-persistent durable slot.
Config composes root-first through an optional parent chain and a configured
global tail. State never inherits. Generation CAS prevents lost config
updates across clients.
Providers And Model Catalog
Anthropic, OpenAI, Gemini, Azure/cloud variants, and configured OpenAI-compatible self-hosted models use one model registry and provider runtime. Exact catalog ownership selects the provider; model-name prefixes are never guessed. Capability profiles govern context/output limits, reasoning, multimodal input, provider-native tools, realtime, and tool visibility.
Current catalog defaults:
| Provider | Default |
|---|---|
| Anthropic | claude-opus-5 |
| OpenAI | gpt-6-astra |
| Gemini | gemini-3.8-flash |
Runtime model fallback is bounded and capability-aware. An accepted fallback re-resolves credentials and makes the new model/provider identity sticky for later turns and recovery.
Auth And Bindings
Backend profiles describe where requests go. Auth profiles describe how credentials are obtained. A binding joins a compatible backend/auth pair and can carry model and policy defaults. Sessions persist only the structural binding reference, never API keys or access tokens.
Credential sources include environment variables, managed-store OAuth, platform defaults, host resolvers, commands, file descriptors, and inline secrets for local development. Binding reads inherit through realm config; credential writes remain strict to the realm that owns the binding.
Tools, MCP, Hooks, And Skills
Applications compose custom dispatchers with builtins, shell policy, MCP servers, skills, semantic memory, schedules, WorkGraph, comms, and mob tools. Tools can be discovered lazily, filtered by model capability, scoped by session/turn/profile, and updated through runtime-owned live surfaces.
Eight typed hook points cover run, model, tool, and turn boundaries with foreground/background and observe/guardrail semantics.
Scheduling, WorkGraph, Jobs, And Approvals
Durable schedules target sessions, identities, mobs, or trusted host runnables from once, interval, or calendar triggers. Occurrences retain overlap, misfire, and missing-target policy.
WorkGraph is a realm-scoped commitment graph for goals, work items, claims, links, evidence, terminal status, and attention control.
Durable jobs detach accepted work from one client connection. JSON-RPC and the
SDKs expose job observation, cancellation, retry, subscriptions, and the
high-trust monitors/start submission path. Other jobs enter through
background shell/callback composition, Schedule, or host embedding. Job
outputs can be stored as blobs and delivered back into sessions.
The JSON-RPC approval/* family maintains request and decision audit records.
They persist to a one-host file sidecar when the RPC persistence bundle exposes
a store path; an ad hoc bundle without one keeps them process-local. The
methods do not automatically gate tool execution. A trusted host or
authenticated proxy must authorize decision actors and connect an approval
record to any effect policy it wants to enforce.
Multi-Agent Mobs And Comms
Mobs are reusable teams of session-backed members with stable identity, role profiles, budgets, tool/auth scope, signed peer communication, topology, and flows. The controlling host owns roster, placement, grants, and teardown. Bound member hosts can materialize members remotely through explicit placement; browser/WASM mobs remain single-host.
Agents use ordinary messages or typed request/response workflows, with queue or steer handling modes and host-visible delivery receipts.
Live Channels
gpt-realtime-2 sessions can open low-latency audio/text channels with
model-gated still-image context. The JSON-RPC family includes live/open,
live/status, live/send_input, live/commit_input, live/interrupt,
live/truncate, live/refresh, live/close, and WebRTC signaling through
live/webrtc/answer.
Enable at least one transport:
rkat-rpc --live-ws <addr>exposes/live/ws; a WebSocketlive/openreturns the connection bootstrap.- A build with
live-webrtcplusrkat-rpc --live-webrtcmints a WebRTC token throughlive/open; the client sends its SDP offer tolive/webrtc/answerand receives the SDP answer.
Image Generation, Blobs, And Artifacts
generate_image routes independently of the active chat model through
OpenAI or Gemini image profiles. Generated bytes live in realm blob storage
and can be fetched through every host surface that exposes blobs. Stable
artifact records add typed metadata and download identity above raw blobs.
Web/WASM And Mobpacks
@rkat/web wraps the browser MeerkatRuntime, sessions, mobs, event
subscriptions, JavaScript tools, provider proxies, and host-page auth
resolvers.
Mobpack packages definitions and assets into portable artifacts with optional Ed25519 signing:
rkat mob pack ./mobs/release-triage -o dist/release-triage.mobpack
rkat mob inspect dist/release-triage.mobpack
rkat mob validate dist/release-triage.mobpack --trust-policy permissive
rkat mob run dist/release-triage.mobpack --flow main --trust-policy permissive
npm --prefix sdks/web run build:wasm
rkat mob web build dist/release-triage.mobpack -o dist/web \
--wasm sdks/web/wasm --trust-policy permissive
Self-Hosted Models
Register an OpenAI-compatible server and one or more model aliases:
[self_hosted]
default_model = "gemma-4-31b"
[self_hosted.servers.local]
transport = "openai_compatible"
base_url = "http://127.0.0.1:11434"
api_style = "chat_completions"
[self_hosted.models.gemma-4-31b]
server = "local"
remote_model = "gemma4:31b"
display_name = "Gemma 4 31B"
family = "gemma-4"
tier = "supported"
context_window = 256000
max_output_tokens = 8192
vision = true
image_tool_results = false
inline_video = false
supports_temperature = true
supports_thinking = true
supports_reasoning = true
supports_web_search = false
call_timeout_secs = 600
Server entries contain connection facts only. Configure a realm binding for
provider = "self_hosted" and identify the server on its backend profile.
Credential fields such as legacy bearer_token_env are rejected on server
entries. See Self-hosting
models for authless, API-key,
and bearer examples.
Surfaces
| Surface | Use case | Documentation |
|---|---|---|
| Rust facade | Embed agents and runtime services | Rust SDK |
| Python SDK | Drive rkat-rpc from Python |
Python SDK |
| TypeScript SDK | Drive rkat-rpc from Node.js |
TypeScript SDK |
| Web SDK | Browser/WASM sessions, mobs, JS tools, provider proxy | Web/WASM |
rkat |
Terminal, CI, and shell automation | CLI |
rkat-rest |
HTTP integration and streams | REST |
rkat-rpc |
Stateful stdio/TCP, SDK backend, live signaling | JSON-RPC |
rkat-mcp |
Expose Meerkat capabilities to MCP clients | MCP |
Architecture
flowchart TD
SF["Rust, CLI, REST, RPC, MCP, SDKs, Web/WASM"] --> F["Facade and Session Services"]
F --> C["Agent Core and Provider Runtime"]
F --> M["Runtime Control Plane and Generated Authority"]
F --> R["Realm Identity and Effective Config"]
R --> ST["Sessions, Runtime, Schedules, WorkGraph, Jobs, Blobs, Artifacts"]
C --> CAP["Models, Tools, MCP, Hooks, Skills, Memory"]
M --> ORCH["Mobs, Comms, Scheduling, Jobs, Live Channels"]
meerkat-core owns the agent and public lifecycle contracts.
meerkat/ AgentFactory compose product capabilities.
meerkat-runtime owns the control plane and machine integration.
meerkat-session implements service profiles, and store crates own physical
persistence. Surface crates are skins over this composition rather than
separate agent engines.
For detailed crate ownership, construction paths, and failure domains, read the architecture reference.
Embedded Rust
The public meerkat::AgentBuilder routes through AgentFactory while allowing
explicit client, tool, and store overrides. It defaults to the
StandaloneEphemeral runtime mode, which is useful for a single embedded
component:
let mut agent = AgentBuilder::new()
.model("claude-opus-5")
.system_prompt("You are an incident triage component.")
.output_schema(OutputSchema::new(triage_schema)?)
.budget(BudgetLimits::default().with_max_tokens(2_000))
.build(llm, tools, store)
.await?;
let result = agent.run(raw_alert_text.into()).await?;
let triage: TriageReport =
serde_json::from_value(result.structured_output.ok_or("missing output")?)?;
For durable products, use a runtime-backed SessionService and
FactoryAgentBuilder. A default standalone builder does not acquire recovery,
auth-lease, scheduling, wake, or multi-agent runtime capabilities
automatically. The lower-level meerkat_core::AgentBuilder is an internal/test
escape hatch, not the public facade construction path.
Development
The repository uses Make as its command surface:
make install-build-deps
make build
make check
make lint
make test
make agent-gate
Use the repository wrapper for targeted Cargo work:
./scripts/repo-cargo test -p meerkat-core session
Documentation and generated contract gates:
make docs-check
make verify-version-parity
make verify-schema-freshness
make verify-sdk-codegen-freshness
make machine-check-drift
Deterministic end-to-end lanes:
make e2e-fast
make e2e-system
Live-provider lanes are opt-in:
make e2e-live
make e2e-smoke
New contributors should start with ONBOARDING.md and AGENTS.md.
Rust Features
The meerkat facade enables Anthropic, OpenAI, and Gemini by default.
Embedded consumers can disable defaults and select provider, store, MCP,
comms, skills, live, memory, ATIF, and session capabilities individually.
Schedule, WorkGraph, and durable-job substrates are always linked; hosts still
choose whether to compose and expose their runtime services and tools. The
empty schedule and workgraph features remain compatibility aliases, not
compile-time selectors.
Meerkat is pre-1.0 and patch releases can contain declared public API breaks. Exactly pin the Meerkat crate family and bump deliberately:
meerkat = { version = "=0.8.33", features = ["sqlite-store", "session-store"] }
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
No comments yet
Be the first to share your take.