Skip to content

Kumiho graph memory

Wire agents into Kumiho's graph memory with the two-reflex engage/reflect pattern.

Revka delegates all persistent, cross-session memory to Kumiho, a graph-native cognitive memory backend reached over the Model Context Protocol. A stateless LLM call forgets everything the moment it returns a response; Kumiho gives every agent cross-session continuity, graph-structured recall over typed provenance edges, and a shared substrate that multiple agents can read and write. This guide shows you how to wire an agent into that backend using the canonical two-reflex pattern — engage memory before responding, reflect after — and how to route, link, and consolidate what you store.

Use this page once the Kumiho MCP sidecar is installed and you want an agent to actually use it. For installing the sidecar and configuring the [kumiho] block, start with Kumiho setup and Install the Python MCP sidecars. For the underlying data model, see Graph model: spaces, items & provenance.

  1. The Kumiho MCP sidecar is installed and running. Installation puts a Python venv at ~/.revka/kumiho/venv/ and a runner shim at ~/.revka/kumiho/run_kumiho_mcp.py. See Install the Python MCP sidecars.

  2. [kumiho] is configured in ~/.revka/config.toml with an api_url, an auth token, and a space_prefix.

    [kumiho]
    enabled = true
    mode = "cloud" # or "local_ce" for self-hosted Community Edition
    mcp_path = "~/.revka/kumiho/run_kumiho_mcp.py"
    api_url = "https://api.kumiho.cloud"
    space_prefix = "Revka"
    memory_project = "CognitiveMemory"
    harness_project = "Revka"
    memory_retrieval_limit = 3

    Auth is read from the environment: KUMIHO_AUTH_TOKEN (preferred, used by the local SDK bridge) takes precedence over KUMIHO_SERVICE_TOKEN (FastAPI header). revka onboard writes these to ~/.revka/.env.

  3. The MCP tools are visible. Confirm the agent actually has memory tools by checking the tool catalog at http://127.0.0.1:42617/tools (or GET /api/tools) — the kumiho_memory_* tools should appear. If they don’t, check ~/.revka/logs/ for the Kumiho MCP stderr trail; the usual cause is a missing token or an unreachable api_url. Run revka doctor for a structured check of the Kumiho sidecar and backend health.

Almost every agent loop follows the same shape: engage before responding, reflect after. This is the canonical integration pattern.

When the request touches anything that might have history, call kumiho_memory_engage exactly once. Derive the query from the user’s current message, not from what you remember searching earlier.

{
"tool": "kumiho_memory_engage",
"args": {
"query": "<query derived from the user's message>",
"graph_augmented": false,
"limit": 5,
"space_paths": ["Revka/AgentPool", "CognitiveMemory/Skills"]
}
}

The call returns:

  • context — a pre-built natural-language summary suitable for prompt injection.
  • results — the raw memories with metadata (titles, types, created_at).
  • source_krefs — opaque identifiers you pass to the matching reflect so new captures link back to what inspired them.

Skip engage when the answer is already visible in the conversation — engaging unnecessarily wastes tokens and pollutes the graph with low-signal queries.

After a substantive response, call kumiho_memory_reflect once with your response text and any structured captures you want preserved.

{
"tool": "kumiho_memory_reflect",
"args": {
"session_id": "<session id>",
"response": "<your response text>",
"captures": [
{
"type": "decision",
"title": "Chose gRPC over REST on Jun 18",
"content": "Picked gRPC for the operator <-> daemon channel for bidirectional streaming; REST was rejected as backpressure-blind.",
"space_hint": "Revka/Plans/gateway"
}
],
"source_krefs": ["<from engage results>"],
"discover_edges": true
}
}

A single reflect call does three things:

  1. Buffers the assistant response for session continuity, so the next engage in the same session sees it.
  2. Stores each capture as a graph memory with DERIVED_FROM edges to the supplied source_krefs.
  3. With discover_edges: true (the default), runs a server-side LLM pass to find non-obvious links to existing memories.

Reflect with captures: [] still buffers the response, so use it for trivial exchanges that need continuity but no durable memory.

Pick the type that matches what you’re storing. Type drives retrieval ranking and DreamState consolidation behavior.

TypeWhen to useExample title
decisionA choice with a rationale that should bind future agents.”Chose Axum over Actix on Mar 14”
preferenceStable user or operator preference.”User wants tests run before commits”
factVerified fact about the world or the system.”Daemon binds 0.0.0.0:42617 in network mode”
correctionOverrides a prior memory that proved wrong.”Operator does NOT auto-restart on panic (correction)“
architectureHigh-level structural choice or constraint.”Operator/Rust split per ADR-005 on Apr 18”
implementationConcrete how-it-works knowledge.”Skill kref resolution flow on Apr 20”
synthesisAggregated insight derived from multiple sources.”Q1 channel error patterns rolled up Apr 27”
reflectionPost-mortem or lesson learned.”Postmortem: stash overlap on Apr 27”
summaryCompacted session or thread summary.”Apr 27 docs-restructure session summary”
skillA reusable procedure to be discovered later.”creative-memory”

Provenance is what separates a graph memory from a flat note. Memories are stored as items in hierarchical spaces, each with immutable revisions, and revisions carry typed edges. Revka uses these edge types:

EdgeMeaningHow it’s created
DERIVED_FROMThe new capture was derived from each source.Implicit when you pass source_krefs to reflect.
DEPENDS_ONB cannot start until A completes (plan ordering).Set explicitly via kumiho_create_edge.
REFERENCEDSoft pointer; one memory mentions another.Discovered, or explicit.
CONTAINSBundle/membership; a session contains its captures.Discovered, or explicit.
CREATED_FROMOne item is a forked or transformed version of another.Explicit.
BELONGS_TOOwnership or scope; ties an artifact to a project, run, or agent.Explicit.
HANDED_OFF_TOHandoff between agents on the shared substrate.Explicit, for multi-agent flows.

When in doubt, let discover_edges: true on reflect infer the edges. Create edges manually only when you have semantic information the LLM can’t infer — DEPENDS_ON ordering is the typical case. Items are addressed by kref in the form kref://space/item?r=N.

Kumiho organizes memory into hierarchical spaces. Revka’s prefix is Revka/...; the CognitiveMemory/... tree is shared across Revka and its sibling agents. Route a read by passing space_paths to engage, and route a write by setting space_hint on the individual capture (per-capture targeting wins over any bulk default).

SpacePurpose
Revka/AgentPoolPer-agent state — identity, expertise, tone, allowed tools.
Revka/Plans/<project>Plans the Operator decomposed for a project.
Revka/SessionsActive and historical chat sessions.
Revka/GoalsLong-running goals an agent is working toward.
Revka/AgentTrustPer-agent trust scores and recent outcome buffer.
Revka/ClawHubMarketplace catalog state (skills, agents, workflows).
Revka/TeamsTeam composition and delegation topology.
Revka/WorkflowRunsOperator workflow run state and history.
Revka/OutcomesPer-run outcomes feeding the trust score calculation.
CognitiveMemory/SkillsShared skill library — cross-agent reusable procedures.

Skills are reusable procedures stored in CognitiveMemory/Skills. Before improvising an unfamiliar procedure, engage that space first:

{
"tool": "kumiho_memory_engage",
"args": {
"query": "creative output tracking",
"space_paths": ["CognitiveMemory/Skills"]
}
}

If a skill matches, follow it and cache it in working context for the rest of the session. If nothing matches and you improvised a procedure, capture it back as a skill-type memory with space_hint: "CognitiveMemory/Skills" so DreamState can refine it later.

After roughly 20 exchanges, or when a session ends, trigger consolidation:

{
"tool": "kumiho_memory_consolidate",
"args": { "session_id": "<session id>" }
}

This compacts session-buffered responses into durable summaries, runs edge discovery over the session’s new captures, and clears the session buffer. Revka’s daemon does this automatically on session end, but long-running agents should self-trigger periodically.

For a direct lookup outside the engage/reflect cycle, use kumiho_memory_recall:

{
"tool": "kumiho_memory_recall",
"args": { "query": "gRPC decision" }
}

DreamState is Kumiho’s overnight maintenance pass, run via the kumiho_memory_dream_state tool. It deprecates stale memories, enriches metadata, adds tags, and links related memories so the graph stays coherent as it grows.

revka onboard offers to install DreamState as a nightly cron job when you select a Kumiho memory backend. You can pick the run time (midnight, 2 AM, 3 AM by default, 4 AM, or 6 AM). Add or change it later with revka cron:

Terminal window
revka cron list
revka cron add "0 3 * * *" --tz UTC "revka agent -m 'run DreamState memory consolidation'"

See revka cron for scheduling syntax and the Onboarding wizard for the install-time prompt.

  • Silent degraded mode. If the control plane is unreachable, Kumiho MCP fails closed — engage and reflect return errors, and the agent should continue without persistence rather than block. Log the error to ~/.revka/logs/ for operator review.
  • Stale memories. A memory naming a file, function, or flag is a claim that the target existed when it was written. Verify the target still exists before acting on a recalled memory; if it’s gone, deprecate the item with kumiho_deprecate_item or update it.
  • Kumiho is canonical. Do not rely on in-process state for cross-session knowledge. If something needs to be remembered across sessions, it must reach Kumiho.
  • Transport fallback. Reads prefer a process-local SDK bridge over loopback for lower latency, falling back to hosted FastAPI automatically. Force the hosted path with REVKA_KUMIHO_SDK_BRIDGE=0.

The dashboard renders Kumiho memory as a force-directed graph at /memory — filter by kind or space and inspect individual nodes. The backing endpoint is GET /api/memory/graph, which returns nodes, edges, and spaces in one payload; a read-only proxy at GET /api/kumiho/{*path} forwards any Kumiho GET endpoint. Both require gateway bearer auth. See Assets & memory explorer and Memory graph & Asset Browser API.

From the CLI, revka memory inspects the Kumiho-backed Memory space directly:

Terminal window
revka memory stats
revka memory list --category core --limit 20
revka memory get my-decision-key

See revka memory & estop for the full command set.

A quick smoke test for any new Kumiho-aware agent path:

  1. Tools visible. GET /api/tools returns at least kumiho_memory_engage, kumiho_memory_reflect, kumiho_memory_recall, and kumiho_memory_consolidate.

  2. Engage round-trip. Call kumiho_memory_engage with a query that should hit something stored earlier; confirm results is non-empty.

  3. Reflect with captures. Call kumiho_memory_reflect with one capture; verify the kref returns and the capture appears at /memory.

  4. Edge formation. Confirm an engage → reflect pair produces a DERIVED_FROM edge from the new capture to the source krefs. Inspect with kumiho_get_edges or the /memory force-graph.

A failure here is almost always one of: missing auth token, unreachable control plane, the MCP sidecar not started, or the daemon’s [kumiho] config disagreeing with the running sidecar’s environment.