One container.
One database.
Two pipelines.
System design, schema, API surface, and the decisions behind each constraint. Runs locally against any Postgres 14+.
Runtime, in three boxes.
A single borg-engine process talks MCP and REST on :8080. It reads from and writes to one Postgres, and calls out to OpenAI or Azure OpenAI only for extraction and embeddings.
borg-engine
- FastAPI + FastMCP 3
- MCP endpoint /mcp
- REST /api/{think,learn,recall}
- Background extraction worker
- 24 h snapshot loop
PostgreSQL 14+
- pgvector, pgAudit, uuid-ossp
- borg_* tables — 15 + 1 fn
- Managed · self-hosted · local
- Recursive CTE traversal
OpenAI · Azure OpenAI
- text-embedding-3-small — 1 536-dim
- gpt-5-mini / gpt-4o-mini
- BYO key. Off-loaded async — never blocks
borg_think
Fifteen tables.
One function.
Every table cleanly separates canonical data from derived serving state. Hot-path denormalization lives in *_state, the source of truth in the parent table.
borg_traverse() — recursive CTE function
Used by the graph_neighborhood retrieval strategy. 1–2 hop traversal, cycle-safe via path tracking, scoped to a single namespace.
-- 1-2 hop graph walk, cycle-safe, ns-scoped SELECT * FROM borg_traverse( p_entity_id := 'a1b2c3…', p_max_hops := 2, p_namespace := 'product-engineering' ); -- returns: entity_id, entity_name, entity_type, -- fact_id, predicate, evidence_status, -- hop_depth, path
Three MCP tools.
REST mirror. Admin.
OSS release runs locally with no authentication — single-user by design. Auth for shared deployments is on the roadmap; the schema already supports it.
| POST | /mcp |
| POST | /api/think |
| POST | /api/learn |
| POST | /api/recall |
| GET | /api/namespaces |
| GET | /api/namespaces/:ns |
| POST | /api/namespaces |
| PUT | /api/namespaces/:ns |
| DEL | /api/namespaces/:ns |
| GET | /api/admin/queue |
| GET | /api/admin/entities |
| GET | /api/admin/facts |
| GET | /api/admin/procedures |
| GET | /api/admin/conflicts |
| GET | /api/admin/predicates |
| POST | /admin/process-episode |
| POST | /admin/requeue-failed |
| POST | /admin/snapshot |
The constraints
are intentional.
Every choice below has a failure mode it prevents and a cost it accepts. If you disagree, file an issue.
borg_think. The alternative (embed-only) gives you similarity search but not a queryable graph.model parameter.