Clove Rust core

Knowledge Base & Kernel

How to run and call the Clove Rust core — clove-kb, the durable memory, and rust-kernel, the agent runtime. REST, MCP, and gRPC, the way you'd expect.

Feeding this to an LLM?or fetch/docs/llms.txt

Overview

The Clove Rust core is two single-binary services. The kernel runs governed agents; clove-kb is the durable memory those agents (and people) read and write. Each is independently useful; together they're the engine.

SVCclove-kb :9090*Memory — append-only log + FTS/vector/graph. REST · MCP · gRPC · web UI.
SVCclove-kernel :8080Agent runtime — jobs, sandbox policy, graph runtime, optimizer. HTTP + MCP.

* clove-kb's own default is :8080; run it on :9090 locally so it doesn't clash with the kernel. The kernel reaches memory by registering clove-kb as a native HTTP-MCP server — no bridge, no sidecar.

Quick start

One command per service. Start clove-kb first — the kernel connects to it at boot.

bash1 · memory (clove-kb) on :9090
cd rust-kb && cargo build --release -p kb-server
CLOVE_KB_HTTP_ADDR=127.0.0.1:9090 CLOVE_KB_ADDR=127.0.0.1:50051 \
./target/release/clove-kb
# REST /v1/* · MCP /mcp · web UI /ui — local embedder baked in, no key needed
curl localhost:9090/v1/health # {"log_head":0}
bash2 · kernel on :8080, pointed at the kb
cd rust-kernel && cp .env.example .env # set CLOVE_KB_URL=http://127.0.0.1:9090 + a model key
./start.sh # builds ck-server, boots, waits for /api/health
curl localhost:8080/api/mcp/servers # clove-kb registered over HTTP-MCP
bashDocker (clove-kb)
docker run -d -p 9090:8080 -e CLOVE_KB_API_KEY=secret clove-kb:dev

Auth & namespaces

Both services use bearer-token auth. clove-kb: CLOVE_KB_API_KEY (Authorization: Bearer …) on all /v1/* except GET /v1/health and GET /ui. kernel: CLOVE_API_KEY on /api/* except /api/health. Omit the key for open dev mode.

Everything in clove-kb lives under a namespace (a path, e.g. workspace:acme/notes). Reads are scoped self (just that namespace) or descendants (the subtree). Hard isolation between orgs = one clove-kb instance per org.

REST API

JSON in, JSON out; timestamps are integer epoch-ms. Base URL = your instance.

GET/v1/healthLiveness → {log_head}. No auth (probe-friendly).
GET/v1/statsCounts (documents/episodes/entities/communities/edges), projector lag, embedder/LLM flags.
POST/v1/notesRemember — add a memory. Body {namespace,actor,text,importance,keywords,tags} → {seq,ref_id}.
POST/v1/appendLow-level event append.
POST/v1/recallHybrid recall (FTS+vector+graph). Body {q,ns,scope,limit,token_budget} → {segments,…}.
GET/v1/recallSame, via query params (?q=&ns=&scope=&limit=).
GET/v1/notes/searchKeyword (BM25) search. ?ns=&q=&limit=
GET/v1/notes/listList recent notes. ?ns=&limit=&offset=
GET/v1/graphRecall a connected subgraph → {nodes,edges}. ?ns=&scope=&q=
GET/v1/episodesRecent sessions. ?ns=&limit=
GET/v1/episodes/:idMembers of one episode.
GET/v1/communitiesClusters + AI summaries.
POST/v1/communities/rebuildRecompute communities. ?ns=&scope=
POST/v1/forgetSoft-delete (appends Evicted). ?ref_id= one, or ?ns= a whole namespace.
GET/v1/state/:ns/:keyRead working-memory value.
POST/v1/state/:ns/:keySet working-memory value. Body {value, ttl_epoch_ms}.
GET/uiWeb console (observe · put · retrieve). No auth.
bashRemember
curl -X POST localhost:9090/v1/notes -H "Authorization: Bearer secret" \
-H 'Content-Type: application/json' -d '{
"namespace": "workspace:acme/notes",
"actor": "alice",
"text": "Alice is allergic to peanuts",
"importance": 0.6, "tags": ["health"]
}'
# {"seq":1,"ref_id":"01K…"}
bashRecall
curl -X POST localhost:9090/v1/recall -H "Authorization: Bearer secret" \
-H 'Content-Type: application/json' -d '{
"q": "what can alice not eat?",
"ns": "workspace:acme", "scope": "descendants",
"limit": 8, "token_budget": 4000
}'
# {"segments":[{"ref_id":"01K…","text":"Alice is allergic to peanuts",
# "score":0.85,"components":{"cosine":…,"keyword":…,"graph":…,
# "recency":…,"importance":…},"cache_tier":"semi_stable"}],
# "embedder":"hybrid","total_tokens":7}

Recall embeds the query with the local bge-small model and runs FTS + vector + graph in parallel — no LLM key needed. The LLM "smart layer" (entity/community extraction) is opt-in and lives on the build path, not recall.

MCP

clove-kb serves MCP itself — JSON-RPC 2.0 at POST /mcp (and POST / for clients that post to the base URL). No Node bridge, no sidecar. Same bearer auth.

kb_recall(q, namespace?, scope?, limit?)Hybrid recall → ranked context.
kb_graph(q?, namespace?, scope?)Recall a connected subgraph (multi-hop / how-related).
kb_add_note(text, namespace?, tags?)Save a memory.
kb_search_notes(q, namespace?, limit?)Keyword (BM25) search.
kb_list_notes(namespace?, limit?, offset?)List recent notes.
kb_episodes(namespace?, limit?)List recent sessions.
kb_forget(ref_id? | namespace?)Soft-delete a note or namespace.
kb_state_set(namespace, key, value, ttl_epoch_ms?)Store a working-memory value.
kb_state_get(namespace, key)Read a working-memory value.
kb_statsCounts + projector lag.
kb_healthLiveness (log head).
bashPair Claude Code (or any MCP client)
claude mcp add --transport http clove-kb https://kb-acme.example.com/mcp \
--header "Authorization: Bearer <token>"
# or: ./scripts/setup-mcp.sh https://kb-acme.example.com <token>
bashVerify (tools/list)
curl -s -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
https://kb-acme.example.com/mcp
# {"result":{"tools":[ …11 tools… ]}}

Pairing the kernel needs no bridge: set CLOVE_KB_URL (+ CLOVE_KB_KEY) in the kernel env and it registers clove-kb over HTTP-MCP at boot.

gRPC

The same core is also a gRPC service KnowledgeBrain (proto/kb.proto): Append, Recall, StateGet, StateSet, Subscribe (live event stream), Health. Same bearer auth (Health exempt).

REST API

All routes under /api, bearer auth (CLOVE_API_KEY) except /api/health. SSE for live job events.

GET/api/healthVersion, queue depth, registered MCP servers, status. No auth.
POST/api/jobsSubmit an agent job {agent_name,workspace_id,goal,model,budget_usd,max_steps,allowed_tools,sandbox_id}.
GET/api/jobs/:idJob state + result.
DELETE/api/jobs/:idCancel a job.
GET/api/jobs/:id/eventsSSE stream of RunEvents (live progress).
GET/api/jobs/:id/event-logDurable cursor-based event replay.
GET/api/jobs/:id/graph-runAssociated multi-agent graph run.
GET/api/workspacesList / create workspaces (tenant roots).
POST/api/workspacesCreate a workspace.
GET/api/projectsProject-facing alias over workspaces.
POST/api/projects/:id/sandboxesCreate a sandbox in a project.
GET/api/sandboxesList sandboxes (policy: allowed_wikis, network, daily cap, kill switch).
POST/api/sandboxesCreate a sandbox / policy.
POST/api/sandboxes/:id/agentsBind an agent to a sandbox.
GET/api/agentsList agent definitions.
POST/api/agentsCreate / upsert an agent definition.
GET/api/runsAgent run records.
GET/api/run-outcomes/:job_idOutcome + attribution (cost, tokens, tools, memory refs).
POST/api/run-outcomes/:job_id/feedbackHuman quality feedback.
GET/api/costCost breakdown by agent/model/workspace/day.
GET/api/audit-eventsStructured audit feed (policy, budget, approvals).
GET/api/watchersList / create external-signal watchers (poll/webhook/MCP).
POST/api/watchers/:id/webhookInbound webhook from an external system.
GET/api/watcher-triggersObservation → job trigger rules.
GET/api/healer-actionsAuto-proposed fixes (retry, more-steps, …).
POST/api/healer-actions/:id/approveApprove / reject a healer action.
GET/api/optimizer-proposalsData-driven agent/policy change proposals.
POST/api/optimizer-proposals/:id/promoteapprove · promote · reject · rollback.
GET/api/skillsSkill registry (procedural memory).
POST/api/skills/mineMine successful runs → forge candidate skills.
GET/api/mcp/serversRegistered MCP servers (incl. clove-kb).
GET/api/mcp/servers/:name/toolsTools exposed by a given MCP server.
bashSubmit a job + stream it
curl -X POST localhost:8080/api/jobs -H 'Content-Type: application/json' -d '{
"agent_name": "BISMO", "workspace_id": "grova", "sandbox_id": "grova-ops",
"goal": "Use kb_retrieve to find when the launch is, then answer.",
"model": "claude-haiku-4-5", "budget_usd": 0.10, "max_steps": 4,
"allowed_tools": ["kb_retrieve"] }'
# {"id":"50e2…"}
curl -N localhost:8080/api/jobs/50e2…/events # live SSE

MCP

The kernel is an MCP consumer: it registers external MCP servers at boot and exposes their tools to agents (policy-scoped). clove-kb is one such server.

Point the kernel at clove-kb with CLOVE_KB_URL (+ CLOVE_KB_KEY). At boot it posts initialize / tools/list to clove-kb's /mcp over HTTP and registers it — transport="http", no Node bridge. The legacy stdio bridge is an escape hatch behind CLOVE_KB_MCP_BIN.

bashConfirm the pairing
curl localhost:8080/api/mcp/servers
# {"servers":["filesystem","clove-kb"]}
curl localhost:8080/api/mcp/servers/clove-kb/tools
# kb_recall, kb_graph, kb_add_note, … (11 tools)

Agents reach memory through the kb_retrieve tool — a façade over clove-kb's kb_search_notes / kb_recall. Every call is scoped to the running sandbox's allowed_wikis, so an agent can't read outside its wiki allow-list. Successful runs are mirrored back to clove-kb as notes (kb_add_note) for prior-art recall.

bashOther MCP servers auto-register when their token is set
GITHUB_TOKEN / SLACK_BOT_TOKEN / LINEAR_API_KEY → that server registers at boot
# inspect: GET /api/mcp/servers