Architecture Overview
Sci is built in three packages:
@sci/core — storage adapters, embeddings, anonymizer, consolidation
@sci/mcp — MCP server, tool implementations, auth middleware
@sci/cli — sci CLI (status, import, connect, backup, etc.)System topology
┌─────────────────────────────────────────────┐
│ AI Clients (Claude Code, Cursor, Copilot) │
│ ↕ MCP stdio transport │
├─────────────────────────────────────────────┤
│ @sci/mcp — MCP Server │
│ ┌──────────────────────────────────────┐ │
│ │ Auth middleware (tier enforcement) │ │
│ │ 8 tools: memory_*, message_*, ... │ │
│ └────────────────┬─────────────────────┘ │
├───────────────────┼─────────────────────────┤
│ @sci/core │ │
│ ┌────────────────▼─────────────────────┐ │
│ │ StorageAdapter (abstract interface) │ │
│ │ LocalAdapter → Postgres+pgvector │ │
│ │ DropboxAdapter→ SQLite+hnswlib │ │
│ │ S3Adapter → SQLite+hnswlib │ │
│ │ iCloudAdapter → SQLite+hnswlib │ │
│ └──────────────────────────────────────┘ │
│ BGE-base-en embeddings (local, no API) │
│ Anonymizer (NER + token substitution) │
└─────────────────────────────────────────────┘Data flow on a memory_recall call
- Agent calls
memory_recallvia MCP stdio - Auth middleware validates token, resolves profile scope
embed(query)runs locally — BGE-base-en, no external call- Dense search + tsvector full-text search fire in parallel against the storage backend
- RRF (Reciprocal Rank Fusion, k=60) merges ranked lists
- Top-N results returned
Data flow on message_anonymize
- Agent calls
message_anonymizewith user message - NER pipeline runs (4 layers: regex → compromise NLP → identity_facts custom entities → CamelCase)
- Token map built in process memory only
- Anonymized text returned with session_id
- Agent sends anonymized text to AI provider
- Agent calls
message_deanonymizewith response + session_id - Token map applied to response, then discarded
The token map is never written to disk, DB, or network.
Write safety
The Augmentor / StorageAdapter.storeEpisodic() is the only write path. Two Postgres roles:
db_reader— SELECT only, used for all readsdb_writer— INSERT/UPDATE on specific tables, used for all writes
No DELETE is granted to either role in the default schema.
Nightly consolidation flow
See Nightly Consolidation guide for the user-facing view.
Technical sequence:
runPromotionPass()— LLM batches over episodic memories →adapter.storeSemantic()oradapter.reinforceSemantic()runDecayPass()— Ebbinghaus formula →adapter.updateDecayScore()runGraphPass()— LLM finds relationships →adapter.insertSemanticEdge()runDigestPass()— LLM summarizes day →adapter.storeEpisodic()+ vault exportadapter.recordConsolidationRun()— audit trail
All four jobs use StorageAdapter — they work with any backend, not just Postgres.