Self-hosted knowledge state memory server for AI agents — types, client, SQLite backend, REST API, MCP
openeruka provides 8 tools with complete input schemas and descriptions. Naming follows verb_noun convention (get_*, write_*, search_). However, descriptions are verbose and technical (200-400+ chars), mixing API details with functional intent. Parameter descriptions are present but inconsistent in clarity. Output schemas are not documented. Error handling is mentioned in descriptions but not formalized. The write_context tool lacks clear guidance on knowledge state invariants and conflict resolution. No tool annotations (readOnlyHint/destructiveHint) despite clear risk stratification.
GET /api/v1/context?workspace_id=&path= — Read a single field by path or all fields matching a path prefix. BUG-1 fix: bare category paths (identity, products, etc.) now route to prefix scan instead of exact match, so 'path=identity' returns identity/* fields.
GET /api/v1/edges?workspace_id= — Get edges in the knowledge graph for a workspace.
GET /api/v1/entities?workspace_id= — Get entities in the knowledge graph for a workspace.
GET /api/v1/gaps?workspace_id= — Gap tracking is not implemented in openeruka local mode. Returns an empty list with a note.
GET /api/v1/tier — Returns workspace tier for eruka-mcp compatibility. openeruka (local, single-tenant) always returns tier: 'local'.
Check if the Eruka instance is healthy
Output schemas not documented. LLMs cannot infer what fields to expect from responses (e.g., get_entities returns what structure? entity_id, name, type, metadata?). This forces agents to guess and risks downstream tool call failures.
Descriptions are verbose (200-400+ chars) and mix API implementation details (HTTP verbs, query params, BUG-1 fix notes) with functional intent. Simplify to: WHAT does it do, WHEN to use it, WHAT does it return.
write_context lacks clear error guidance. Description mentions 'Err(ClientError::Conflict) if a Confirmed field is written with a lower knowledge state' but does not explain what the LLM should do next (retry with higher state? ask user? abort?). Per pattern:recovery-guide, errors must tell the agent what to do.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
GET /api/v1/search?workspace_id=&query=&limit= — Simple text-match search over all workspace fields. No vector similarity (local mode — managed eruka has pgvector for semantic search).
POST /api/v1/context — Write a context field. Returns Err(ClientError::Conflict) if a Confirmed field is written with a lower knowledge state — the server enforces the knowledge state invariant.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Risk field is present in metadata but not exposed to LLM. write_context is destructive (WRITE risk) and should carry destructiveHint=true; all read tools should carry readOnlyHint=true. This is a current MCP spec pattern (2026-07-28).
Parameter descriptions lack format/constraint details. E.g., 'knowledge_state' accepts 'confirmed, inferred, uncertain, unknown' but description does not state this as an enum or constraint.