Skip to main content
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.

Custom tools

Implement the AgentToolDispatcher trait:
struct MathTools;

#[async_trait]
impl AgentToolDispatcher for MathTools {
    fn tools(&self) -> Arc<[Arc<ToolDef>]> {
        vec![Arc::new(ToolDef {
            name: "add".to_string(),
            description: "Add two numbers".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "a": {"type": "number"},
                    "b": {"type": "number"}
                },
                "required": ["a", "b"]
            }),
        })].into()
    }

    async fn dispatch(&self, call: ToolCallView<'_>) -> Result<ToolResult, 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))
            }
            _ => 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 @anthropic/mcp-server-filesystem /tmp
rkat mcp add api --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.

Built-in tools

Meerkat ships with tool categories you enable per-agent. Nothing is on by default — you choose what your agent can do.
CategoryToolsEnable with
Builtinstask_create, task_list, task_get, task_update, wait, datetime, apply_patch, view_imageenable_builtins
Shellshell, shell_jobs, shell_job_status, shell_job_cancelenable_shell
Memorymemory_searchenable_memory
Commssend, peersenable_comms
Mob orchestrationmob_*, 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.

Tool scoping

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 via the session API (RPC mcp/add, mcp/remove, REST endpoints, or programmatically through ToolScopeHandle). The filter is persisted in session metadata and survives resume. 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 agent receives a [SYSTEM NOTICE] in the conversation when its 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 the RPC surface:
{"jsonrpc":"2.0","id":1,"method":"mcp/add","params":{
  "session_id":"...","server_name":"my-tools",
  "server_config":{"transport":"stdio","command":"npx","args":["-y","@my/server"]},
  "persisted":false
}}
RPC MethodEffect
mcp/addConnect a new MCP server, register its tools
mcp/removeDrain in-flight calls, disconnect server, remove tools
mcp/reloadReconnect 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

SurfaceLive MCPExternal tool filter
JSON-RPCmcp/add, mcp/remove, mcp/reloadVia ToolScopeHandle on session runtime
CLIrkat mcp add --session --live-server-urlDelegates to REST
RESTRoute stubs registered
See the built-in tools reference for the mechanical details of factory flags and per-build overrides.

Multimodal tool results

Tools can return rich content beyond plain text. The ToolOutput enum controls what gets injected into the conversation as a tool result:
  • ToolOutput::Json(Value) — the standard path. The JSON value is serialized to a text ContentBlock in the tool result.
  • ToolOutput::Blocks(Vec<ContentBlock>) — returns one or more content blocks directly, including images. Used by tools like view_image to pass image data to vision-capable models.
ContentBlock has two variants:
  • ContentBlock::Text { text } — plain text content.
  • ContentBlock::Image { media_type, data, source_path } — base64-encoded image with MIME type. The source_path field is domain-only metadata (stripped from wire types).
The built-in view_image tool reads an image file from disk and returns a ToolOutput::Blocks containing a single ContentBlock::Image. 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 ToolScope capability gating based on ModelProfile.vision and ModelProfile.image_tool_results. Custom tools can return multimodal content by implementing BuiltinTool::call() and returning ToolOutput::Blocks(...) with the appropriate content blocks.

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 intercept tool calls before and after execution for guardrails, audit, or argument rewriting.

Mob tools (meerkat-mob-mcp)

Mob tools (mob_*) are provided by the meerkat-mob-mcp dispatcher and composed through SessionBuildOptions.external_tools.
  • CLI run composes this dispatcher when --enable-mob (-M) is passed (opt-in, disabled by default).
  • rkat mob ... remains the explicit direct lifecycle surface.
  • Other session-driven surfaces (RPC/REST/MCP/SDK hosts) can expose the same mob_* capability by composing MobMcpDispatcher into their session build path.