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.

For the full guide, see Hooks.
Start here after you understand the normal session/tool flow. If you are new to Meerkat overall, read Examples: Sessions first.

Observer hook (background)

A post_tool_execution background hook that logs every tool call to a file. Background hooks run asynchronously and never block the agent loop.
Run-scoped hook override flags are not currently exposed on the normal rkat run surface. Use the JSON-RPC, REST, MCP, or SDK examples below for per-run hook override testing.

Guardrail hook (foreground)

A pre_tool_execution foreground hook that must approve each tool call before it runs. If the hook returns deny, the tool call is skipped.
Run-scoped hook override flags are not currently exposed on the normal rkat run surface. Use the JSON-RPC, REST, MCP, or SDK examples below for per-run hook override testing.

In-process hook (Rust only)

Register a Rust closure directly — no subprocess, no serialization overhead. Only available in the Rust SDK.
let engine = DefaultHookEngine::new(hooks_config)
    .with_in_process_handler(
        "pii-guard",
        Arc::new(|invocation| Box::pin(async move {
            let text = invocation.tool_call.as_ref()
                .map(|call| call.args.as_value().to_string()).unwrap_or_default();
            let decision = if contains_pii(&text) {
                Some(HookDecision::deny(
                    HookId::new("pii-guard"),
                    HookReasonCode::PolicyViolation,
                    "tool arguments contain PII",
                    None,
                ))
            } else {
                None
            };
            Ok(RuntimeHookResponse {
                decision,
                ..Default::default()
            })
        })),
    );
Hooks receive typed projections of the request, response, tool call, and tool result. They can allow, deny, or observe those facts; they cannot rewrite canonical LLM, tool, or run output.
let engine = DefaultHookEngine::new(hooks_config)
    .with_in_process_handler(
        "tool-audit",
        Arc::new(|invocation| Box::pin(async move {
            let content = invocation.tool_result.as_ref()
                .map(|r| r.content.as_str()).unwrap_or("");
            audit_tool_result(content).await;
            Ok(RuntimeHookResponse {
                ..Default::default()
            })
        })),
    );

HTTP hook

A hook that POSTs the invocation payload to a remote URL. Useful for centralized policy servers.
Run-scoped hook override flags are not currently exposed on the normal rkat run surface. Use the JSON-RPC, REST, MCP, or SDK examples below for per-run hook override testing.

All 8 hook points

Hook pointClassificationWhen it fires
run_startedpreStart of Agent::run(), before any LLM call
pre_llm_requestpreBefore each LLM streaming call
pre_tool_executionpreBefore each individual tool call is dispatched
turn_boundarypreBetween turns, after all tool results are collected
post_llm_responsepostAfter the LLM response is received
post_tool_executionpostAfter each tool execution completes
run_completedpostAfter a successful run completes
run_failedpostAfter a run fails with an error
Pre-point hooks in foreground mode halt the agent loop until they return. Pre-point hooks in background mode are limited to observe-only capability.

Disable a hook

Use the disable list to turn off hooks defined in the realm config without removing them.
Run-scoped hook override flags are not currently exposed on the normal rkat run surface. Use JSON-RPC, REST, MCP, or SDK/embedded surfaces for per-run hook override testing.

Hook events

Hooks emit events into the session event stream. Subscribe to these to build dashboards, alerting, or audit trails.
// HookStarted -- emitted when a hook begins execution
{"type": "hook_started", "hook_id": "safety-gate", "point": "pre_tool_execution"}

// HookCompleted -- emitted when a hook finishes successfully
{"type": "hook_completed", "hook_id": "safety-gate", "point": "pre_tool_execution", "duration_ms": 42}

// HookDenied -- emitted when a hook blocks execution
{"type": "hook_denied", "hook_id": "safety-gate", "point": "pre_tool_execution", "reason_code": "policy_violation", "message": "rm -rf not allowed"}

// HookFailed -- emitted when a hook errors or times out
{"type": "hook_failed", "hook_id": "audit-log", "point": "post_tool_execution", "error": "process exited with code 1"}

Next step