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’s tool system is trait-based. You implement AgentToolDispatcher, and the engine handles dispatch, parallel execution, and result injection. MCP servers are first-class — register them and their tools appear alongside your custom tools with no code changes.
Mental model
At the concept level, tools answer one question: how does the agent act on the world?
The important conceptual layers are:
- custom tools you own
- built-in tools Meerkat can compose
- MCP-provided external tools
- runtime visibility/scoping rules
The Rust trait example below is an implementation detail of that model, not the model itself.
Implement the AgentToolDispatcher trait:
struct MathTools;
#[async_trait]
impl AgentToolDispatcher for MathTools {
fn tools(&self) -> Arc<[Arc<ToolDef>]> {
vec![Arc::new(ToolDef::new(
"add",
"Add two numbers",
json!({
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
}),
))].into()
}
async fn dispatch(&self, call: ToolCallView<'_>) -> Result<ToolDispatchOutcome, ToolError> {
match call.name {
"add" => {
let args: AddArgs = call.parse_args()
.map_err(|e| ToolError::invalid_arguments(call.name, e.to_string()))?;
Ok(ToolResult::new(call.id.to_string(), format!("{}", args.a + args.b), false).into())
}
_ => Err(ToolError::not_found(call.name)),
}
}
}
ToolCallView is a zero-allocation borrowed view ({ id: &str, name: &str, args: &RawValue }). When the model requests multiple tool calls, Meerkat dispatches them in parallel.
MCP servers
Register any MCP server and its tools automatically appear in the agent’s tool set:
rkat mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /tmp
rkat mcp add api --transport http --url https://mcp.example.com/api
Config is stored in .rkat/mcp.toml (project) or ~/.rkat/mcp.toml (user). Supports stdio, streamable HTTP, and SSE transports. See the MCP reference for full details.
Meerkat ships with tool categories you enable per-agent. Nothing is on by default — you choose what your agent can do.
| Category | Tools | Enable with |
|---|
| Builtins | task_create, task_list, task_get, task_update, datetime, apply_patch, view_image, generate_image, blob_save_file, blob_load_file, blob_inspect | enable_builtins |
| Shell | shell, shell_jobs, shell_job_status, shell_job_cancel | enable_shell |
| Memory | memory_search | enable_memory |
| Scheduler | meerkat_schedule_* | enable_schedule |
| WorkGraph | workgraph_* | enable_workgraph |
| Comms | send_message, send_request, send_response, peers | enable_comms |
| Mob orchestration | mob_*, meerkat_* | enable_mob |
Shell tools support allow/deny list security policies. Runtime tool visibility can also be shaped with mob overlays and turn-boundary tool-scope updates. See the built-in tools reference for parameter details.
For nontrivial Meerkat-owned tool families, companion skills provide the agent
instruction manual. Tool descriptions stay short and schema-oriented; skills
such as workgraph-workflow, schedule-workflow, task-workflow, and
shell-patterns explain the operating posture for the tool family.
Tool visibility can change during a session without restarting the agent. Changes are staged then atomically applied at the turn boundary — the LLM never sees a tool list change mid-stream.
External filters. Callers can stage an allow-list or deny-list filter programmatically through ToolScopeHandle. This is distinct from MCP server lifecycle management.
Per-turn overlays. Mob flow steps can restrict tools for a single turn via TurnToolOverlay (allow + deny). The overlay is ephemeral — it’s cleared after the turn completes.
Live MCP mutation. MCP servers can be added or removed from a running session. Additions connect the server and register its tools; removals drain in-flight calls before finalizing. Both are staged and applied at the next turn boundary.
Composition rule: Most-restrictive wins. Multiple allow-lists intersect, multiple deny-lists union, and deny always beats allow. The conversation records a typed tool_config system notice when the tool set changes, and a tool_config_changed event is emitted to the event stream.
Live MCP controls
MCP servers can be added, removed, or reloaded on a running session via JSON-RPC, REST, MCP-server tools, or SDK helpers:
{"jsonrpc":"2.0","id":1,"method":"mcp/add","params":{
"session_id":"...",
"server_config":{"name":"my-tools","command":"npx","args":["-y","@my/server"]},
"persisted":false
}}
| RPC Method | Effect |
|---|
mcp/add | Connect a new MCP server, register its tools |
mcp/remove | Drain in-flight calls, disconnect server, remove tools |
mcp/reload | Reconnect one or all servers (picks up config changes) |
All mutations are staged and applied at the next turn boundary. Set persisted: true to write the change to disk config so it survives restart. See the RPC reference for full parameter details.
Surface availability
| Surface | Live MCP | External tool filter |
|---|
| JSON-RPC | mcp/add, mcp/remove, mcp/reload | Via in-process ToolScopeHandle on the session runtime |
| CLI | rkat mcp add/remove/list/get edits project/user config; start or resume a session to load it | No standalone public CLI filter surface today |
| REST | POST /sessions/{id}/mcp/add, remove, reload | No standalone public REST filter surface today |
| MCP server | meerkat_mcp_add, meerkat_mcp_remove, meerkat_mcp_reload | No standalone public MCP filter surface today |
See the built-in tools reference for the mechanical details of factory flags and per-build overrides.
Tools can return rich content beyond plain text. The injected runtime shape is ToolResult.content: Vec<ContentBlock>, with helper constructors for text-only or multimodal output.
ToolResult::new(...) — the standard text-only path. The string becomes a single text content block.
ToolResult::with_blocks(...) — returns one or more content blocks directly, including images and video.
- Built-in tools that expose richer output may internally use
ToolOutput::Blocks(...), but the persisted/runtime-facing result shape is still ToolResult.content.
ContentBlock currently has three variants:
ContentBlock::Text { text } — plain text content.
ContentBlock::Image { media_type, ... } — inline or blob-backed image content.
ContentBlock::Video { media_type, duration_ms, ... } — inline video content.
The built-in view_image tool reads an image file from disk and returns a result containing image content blocks. It supports PNG, JPEG, GIF, WebP, and SVG formats up to 5 MB. The tool is automatically hidden from models that lack vision support via capability-aware tool visibility.
The built-in generate_image tool is session-owned runtime dispatch. It lets a model request generated or edited images through universal fields plus provider-owned provider_params. Generated image bytes are stored as blobs and committed as AssistantBlock::Image transcript blocks, so every surface reads the same image_id/blob_ref history and fetches bytes through blob/get or model-facing blob_save_file.
The blob file bridge tools are registered only when the session has a blob store. blob_save_file writes decoded blob bytes to a file inside the project root, blob_load_file reads a project file into the blob store, and blob_inspect returns blob metadata without raw payload bytes. They do not expose blob listing or deletion.
Custom tools can return multimodal content by returning ToolResult::with_blocks(...) with the appropriate content blocks.
Image generation
generate_image is a session-owned builtin for creating or editing assistant images. It is registered when builtins are enabled and the runtime-backed surface supplies the image-generation machine, provider executor, planner, and blob store. CLI sessions wire this automatically; the default --tools safe preset includes builtins.
The tool accepts a typed request under request, routes it to OpenAI or Gemini image backends, stores generated image bytes in the realm blob store, and returns structured ImageGenerationToolResult JSON with durable images[].blob_ref values. A model can then call blob_save_file to materialize that blob as a project file, for example top-news-infographic.png.
For setup, provider parameters, result fields, and troubleshooting, see Image generation.
Composition
Tools from different sources (custom, MCP, built-in) are composed into a single dispatcher. The agent sees one flat tool list regardless of where each tool comes from. Hooks can observe tool calls before and after execution, and guardrails can deny unsafe calls before dispatch.
Mob tools (mob_*) are provided by the meerkat-mob-mcp dispatcher and composed
through the late-bound SessionBuildOptions.mob_tools factory slot.
- CLI
run composes this dispatcher when the full tool preset is selected (--tools full or --yolo).
rkat mob ... remains the explicit direct lifecycle surface.
- Other session-driven surfaces can grant the same agent-side
mob_* capability
by installing AgentMobToolSurfaceFactory into their session build path.
- Public host APIs should not re-export that raw dispatcher. They use typed
control planes instead:
mob/* on RPC/SDK surfaces and meerkat_mob_* on
public MCP surfaces.