Neuro-Cognitive Engine
NCE — Neuro-Cognitive Engine
A cognitive memory and reasoning substrate for autonomous agents. Persistent, multi-tenant, time-travelling memory across a four-database stack — with a brain on top.
NCE began life as TriMCP — a Model Context Protocol server backed by a tri-database stack. It has since grown into a full Neuro-Cognitive Engine: MCP is now just one of several front doors onto a system that consolidates memories while agents sleep, models how knowledge decays and is reinforced, maintains logical consistency across competing beliefs, reasons about cause and effect, and federates memory securely between independent agent networks.
The engine is provider-agnostic (BYO LLM — local, OpenAI, Anthropic, Gemini, and more), multi-tenant by construction (database-enforced Row-Level Security), and auditable by design (an append-only, hash-chained event log that makes every state reconstructable and every memory's causal provenance traceable).
Table of Contents
Why NCE
Most "agent memory" is a vector index with a search() call bolted on. That works until an agent runs for weeks, serves multiple tenants, accumulates contradictory facts, and someone asks "what did the agent believe last Tuesday, and why?"
NCE is built for that second world:
Concern | Naïve approach | NCE |
Recall | Flat vector search | Semantic search + GraphRAG traversal + spiking spreading activation |
Isolation | App-layer | PostgreSQL Row-Level Security, forced on every table |
History | Last-write-wins | Append-only WORM event log; |
Knowledge quality | Store everything forever | Consolidation (sleep cycle), salience decay, contradiction detection |
Truth | Trust the latest write | ATMS belief revision with justification graphs |
Sharing | Copy data between agents | A2A cryptographic, scope-bound, RLS-enforced federation |
Auditability | Logs, maybe | Hash-chained provenance; deterministic replay & fork of any namespace |
The Cognitive Model
NCE treats memory the way a mind does — as a lifecycle, not a bucket.
ingest ──▶ EPISODIC ──▶ consolidate ──▶ SEMANTIC ──▶ knowledge graph
(raw) memories (sleep cycle) abstractions (entities + relations)
│ │
salience decay spreading activation
(Ebbinghaus curve) (neuromorphic recall)
│ │
reinforced ◀──────────── retrieval ───────────────────┘Episodic → Semantic consolidation. A background "sleep cycle" runs HDBSCAN density clustering over episodic embeddings, distils each cluster into a Semantic Abstraction via an LLM (output strictly validated by Pydantic V2), and upserts the result into both the memory store and the knowledge graph.
Salience & forgetting. Every memory carries a salience score that decays exponentially per the Ebbinghaus forgetting curve,
s(t) = s₀·e^(−λΔt), and is reinforced on retrieval,s ← min(1.0, s + δ). Important things stay sharp; noise fades.Contradiction detection. New facts are checked against existing knowledge via semantic match → KG conflict → a cross-encoder NLI model (
nli-deberta-v3-small) → an LLM tiebreaker. Unresolved conflicts are surfaced for the agent to settle.Belief revision (ATMS). An Assumption-Based Truth Maintenance System tracks
ASSUMPTION/PREMISE/DERIVEDnodes and their justifications, propagating deprecation through the justification graph (cycle-safe) when an assumption is retracted.Causal reasoning. A do-calculus causal engine and counterfactual chrono-branching let agents ask "what if" — overlaying hypothetical mutations on an isolated timeline without ever touching production rows.
See docs/cognitive_layer.md and docs/netbox_and_cognitive_extensions.md.
System Architecture
flowchart TB
subgraph Clients [Clients]
IDE[MCP clients · Claude Desktop · Cursor]
PEER[Peer agent networks]
OPS[Operators / Admins]
end
subgraph Surfaces [Surfaces]
STDIO[server.py · MCP stdio]
A2A[a2a_server.py · A2A federation]
ADM[admin_server.py · REST + Admin UI]
WH[webhook_receiver · document bridges]
end
subgraph Background [Background processing]
RQ[start_worker.py · RQ worker]
CRON[nce.cron · schedulers]
end
subgraph Engine [NCEEngine — orchestration]
ORCH[Saga write path]
COG[Cognitive workers]
TMP[Temporal / replay]
end
subgraph Data [Quad-Database Stack]
PG[(PostgreSQL + pgvector)]
MG[(MongoDB)]
RD[(Redis)]
S3[(MinIO)]
end
IDE --> STDIO
PEER --> A2A
OPS --> ADM
STDIO --> ORCH
A2A --> ORCH
ADM --> ORCH
WH --> RQ
RQ --> ORCH
CRON --> COG
ORCH --> PG & MG & RD & S3
COG --> PG & MG
TMP --> PG & S3Every standard write travels a transaction-scoped Saga path with automatic compensating rollbacks, so a partial failure across the four stores never leaves orphaned state. Detailed sequence diagrams live in docs/architecture-v1.md and docs/database_architecture.md.
The Quad-Database Stack
Duties are split across four engines so each does only what it is best at:
Store | Role | Holds |
PostgreSQL + pgvector | Relational core & vector index | Semantic embeddings (HNSW), knowledge-graph triplets ( |
MongoDB | Episodic payload archive | Heavy unstructured content — transcripts, code, document pages — referenced by ObjectID |
Redis | Transient & coordination | TTL context caches, rate limits, distributed locks, single-use HMAC nonces, RQ job queues |
MinIO | Object storage (S3 API) | Binary artifacts (image/audio/video) and the deterministic LLM response cache used by replay |
Capabilities
Hybrid recall —
semantic_search(pgvector cosine) with MongoDB hydration,graph_searchGraphRAG BFS traversal, and neuromorphic spiking spreading activation with LTP/LTD weight adaptation.Time travel — pass an
as_ofISO-8601 timestamp to any read and see memory exactly as it stood:valid_from <= as_of AND (valid_to IS NULL OR valid_to > as_of). Applies symmetrically to vector search and graph traversal.Snapshots & state diffing — name a point in time (
create_snapshot) and diff two instants withcompare_states.Replay engine —
replay_observestreams the event log read-only;replay_forkrebuilds a namespace into an isolated target, either deterministically (LLM responses served from the MinIO cache, byte-identical) or re-executed (call the LLM fresh for A/B "what-if" divergence);replay_reconstructfor exact rebuilds.Code intelligence —
index_code_fileAST-parses source (Tree-sitter; Python, JS, TS, Go, Rust) into per-symbol chunks;search_codebasereturns matching functions/classes with line ranges.Document bridges — OAuth + webhook sync from SharePoint/OneDrive, Google Drive, and Dropbox, with subscription renewal, retry, and a dead-letter queue.
Rich ingestion — extractors for PDF, Office (Word/Excel/PowerPoint), email, CAD, diagrams, project files, plaintext, with OCR and LibreOffice fallbacks.
Provider-agnostic cognition —
local-cognitive-model,openai,azure_openai,anthropic,google_gemini,deepseek,moonshot_kimi, and anyopenai_compatibleendpoint.Edge & air-gapped — local inference stack with optional OpenVINO NPU acceleration; see docs/airgapped_deployment.md.
Observability — OpenTelemetry → OTLP/Jaeger tracing and a Prometheus metrics endpoint, on by default.
Surfaces & Entrypoints
NCE is no longer "just an MCP server." It exposes several coordinated surfaces:
Entrypoint | Transport | Purpose |
| MCP stdio (JSON-RPC 2.0) | Tool surface for LLM clients (Claude Desktop, Cursor, …) |
| HTTP (Starlette REST + Admin UI) | Operations, namespace/quota management, runtime tool toggles |
| HTTP (A2A RPC) | Federated, scope-bound memory sharing between agent networks |
| HTTP | Inbound document-bridge change notifications |
| RQ worker | Async jobs — code indexing, bridge sync, re-embedding |
| Scheduler | Consolidation cycles, bridge renewal, GC |
A Dynamic Tools Console in the Admin UI can enable/disable individual stdio tools or A2A skills at runtime (persisted to a Redis hash); disabled calls are rejected by the dispatch interceptor. If Redis is unreachable the interceptor fails open to avoid cascading outages.
Quickstart
Prerequisites: Docker Desktop and Python 3.10+.
1. Configure
cp .env.example .envGenerate real secrets in .env (never commit it):
NCE_MASTER_KEY— ≥32 random bytes; AES-256-GCM key for PII/credential encryption.openssl rand -base64 32NCE_API_KEY/NCE_ADMIN_API_KEY/NCE_MCP_API_KEY— long random tokensNCE_MCP_NAMESPACE_ID— a UUID pinning the stdio connection to one tenant, e.g.00000000-0000-4000-8000-000000000001
2. Bring up the full stack
make up # bootstraps compose secrets, then `docker compose up -d --build`
make status # container healthThis launches the Quad-Stack (nce-postgres, nce-mongo, nce-redis, nce-minio), the cognitive model, and the application services (worker, cron, admin, a2a, webhook-receiver) behind Caddy, plus Jaeger.
Databases only (when you want to run the app from your host):
make local-up # docker-compose.local.yml — just Postgres, Mongo, Redis, MinIO3. Run from the host (optional)
python -m venv .venv
.venv\Scripts\activate # Windows · source .venv/bin/activate on macOS/Linux
pip install -r requirements.txt
python server.py # MCP stdio server (listens on stdin for JSON-RPC)
python start_worker.py # background RQ worker (separate shell)
python -m nce.cron # schedulers (separate shell)4. Verify
make verify # runs verify_v1_launch.py end-to-endConnecting an MCP Client
Claude Desktop
Edit %APPDATA%\Claude\claude_desktop_config.json (Windows) or
~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"nce-memory": {
"command": "python",
"args": ["/absolute/path/to/NCE/server.py"],
"env": {
"MONGO_URI": "mongodb://127.0.0.1:27017",
"PG_DSN": "postgresql://mcp_user:mcp_password@127.0.0.1:5432/memory_meta",
"REDIS_URL": "redis://127.0.0.1:6379/0",
"MINIO_ENDPOINT": "127.0.0.1:9002",
"MINIO_ACCESS_KEY": "mcp_admin",
"MINIO_SECRET_KEY": "super_secure_minio_password",
"NCE_MASTER_KEY": "your-32-byte-master-key",
"NCE_MCP_API_KEY": "your-client-api-key",
"NCE_MCP_NAMESPACE_ID": "00000000-0000-4000-8000-000000000001"
}
}
}
}Cursor — Settings → MCP → Add New Tool, command python, args ["/absolute/path/to/NCE/server.py"], same env block. A ready-to-edit template ships as mcp_config.json.example.
MCP Tool Surface
Tools are dispatched through nce/mcp_stdio_dispatch.py, which enforces auth, quotas, and runtime enable/disable state. Highlights ([ADMIN] tools require admin_api_key):
Tool | What it does |
| Persist a memory; extract entities; build KG edges (Saga write) |
| Ingest media/PDF/logs into MinIO + index metadata |
| Vector cosine search + Mongo hydration; optional |
| GraphRAG: anchor by similarity, BFS the KG, return a subgraph; optional |
| List live entity types & edge predicates (avoid hallucinated graph constraints) |
| Discover and run pre-optimised query templates |
| Async AST code indexing & semantic code search |
| Reinforce or zero a memory's salience |
| Surface and settle logical conflicts |
| Point-in-time references & state diffing |
| Deterministic & forked replay |
| Integrity check & causal-chain trace |
| Cross-agent federated sharing |
| Document-bridge lifecycle |
|
|
Migration tools (start_migration, validate_migration, commit_migration, …) are included unless disabled, and vertical-engine tool families (product_*, procurement_*, vendors_*, sales_*, system_design_*, project_*, d365_*, diag_*, …) register when their engine is enabled. The authoritative registry is nce/tool_registry.py — 109 tools as of the current main.
Security Model
Multi-tenant by construction. Every application checkout passes through
scoped_pg_session, which setsSET LOCAL nce.namespace_id = '<tenant-uuid>'. All relational tables have RLS enabled and forced; policies validate viaget_nce_namespace(). Privileged GC runs under a separateBYPASSRLSrole, out of band.Encryption at rest. PII, credentials, and biometric tensors are AES-256-GCM encrypted under
NCE_MASTER_KEY. An automated PII pipeline (Presidio/regex) supports redaction and reversible pseudonymisation — see docs/pii.md.Integrity & non-repudiation. The
event_logis append-only (aprevent_mutationtrigger blocks edits) and hash-chained; entries are HMAC-SHA256 signed over RFC 8785 (JCS) canonical JSON, with rotatable signing keys. See docs/signing.md.AuthN/Z. HMAC-authenticated admin HTTP with optional Redis-backed replay protection; JWT (HS256 secret or RS256 public key) for A2A and protected routes; optional mTLS behind your edge proxy.
A2A federation. Sharing tokens are stored only as SHA-256 hashes mapped to expirations and JSONB scopes; inbound queries are scope-checked then executed bound to the owner's RLS namespace.
Full guide: docs/enterprise_security.md · docs/multi_tenancy.md.
Vertical Modules
NCE ships domain verticals that turn the cognitive core into an operational tool.
Shared-Core Foundation
All business engines sit on a common cross-engine foundation (C1–C9): entity resolution with a merge-review queue and survivorship rules, autonomy governance (@governed confirm-first gates, value/volume ceilings, allowlists, kill switch), external-principal RLS scoping for partner/customer access, allow-list field redaction, a per-function d365 | both | nce source-mode switch with divergence logging, deterministic pricing resolution, a cryptographic signing ceremony for documents that leave the system, and structural grounding guards (citation-required answers, no-ranked-people rule). Guide: docs/shared-core/overview.md.
Engines
Per-namespace opt-in; documented under docs/engines/ (see the docs index):
Product — catalog search & on-demand enrichment, related-product/BOM matching, golden-record survivorship, EOL watchers.
Procurement — TCO calculation, supplier ranking, three-way match, and PO generation/submission behind confirm-first autonomy ceilings (real money never moves without a human).
Agreements — OCR → structured agreement extraction with a human review queue (money/legal terms never auto-promote), kickback reconciliation, coverage analysis.
Vendors & Contractors — vendor registry with scorecards (sparse data scores neutral, not bad), contractor matching & dispatch, partner-scoped views.
Sales — D365-mirrored lead → opportunity → quote read model, dealroom pricing via the shared pricing resolver, a single immutable signed-baseline freeze per quote (append-only at the database grant level), public customer quote links (HMAC-tokenised, redacted), and source-mode divergence tracking.
System Design — propose-only design generation with a human validation gate, device/topology capability checks, SoW generation with freeze-on-issue (design ↔ quote round-trip planned).
Project — G0–G6 phase gates with config-as-IP criteria, signed-quote conversion (reads the Sales baseline), event-driven BOM→task sync, My-Day/capacity/scope-creep insights (partial — some surfaces REST-only or not yet wired).
NetBox — GraphQL topology activation (sites/racks/devices/cables → adjacency graph), unregistered-asset discovery against live telemetry, a do-calculus circuit-provider escalator, longitudinal operator stress tracking with on-call weight redistribution, and an active-learning queue (low-confidence memories quarantined for gamified operator review). There is also a NetBox Cognitive Dashboard Django plugin under
src/nce-netbox-plugin/.Dynamics 365 — case enrichment with graph context, entity sync to
kg_edges, empathic-tensor frustration/burnout reports, SLA-breach records from the WORM log, and a D365 ↔ NetBox cross-reference mapper.Diagnostics — log-bundle digestion pipeline (streaming ingest, digest writer, enrichment, source profiles) surfaced through
diag_*tools.
Details: docs/netbox_and_cognitive_extensions.md · docs/d365_integration_reference.md.
Terminology: "kickback"
This codebase uses the word kickback in its Norwegian commercial sense, where kickback is the ordinary term for a volume-based supplier rebate — a discount a supplier pays back once agreed purchase thresholds are met. It is a standard, openly negotiated clause in Nordic framework agreements and it appears on invoices, in contracts and in accounting records.
It does not mean a bribe, a secret commission, or any improper payment.
The distinction is enforced in the code, not just asserted here. In
nce/vertical_modules/agreements/compliance.py, the clause matcher scans supplier agreements for a set
of flags in which kickback_prohibited and anti_bribery are separate entries — a rebate clause and
a bribery clause are different things, detected independently.
Where the word appears, it is one of three things:
appearance | why it stays |
Clause keywords in | These are search terms for text in third-party contracts. A contract that literally says "no kickback" must still match. Renaming them would silently break detection. |
| A database table this project does not own. It is queried defensively and degrades to empty when absent; renaming it would break the lookup against the table's real name. |
| The domain itself: reconciling accrued supplier rebates against general-ledger spend. |
One thing was deliberately renamed. The supplier-scoring weight kickback_proximity is now
rebate_proximity, because that name described our own ranking behaviour rather than a term in
someone else's contract — "rank suppliers by kickback proximity" reads as scoring suppliers by bribe, and
the project's own spec review had already flagged it as the single biggest reputational risk in the
suite. The legacy key is still honoured so existing configurations keep working.
The rule applied: rename what describes our behaviour; keep and document what describes the documents we read.
A false friend, for the amused
Norwegian and English part ways on this word. In Norwegian, a kickback is something you negotiate in the open, write into the contract, and reconcile against the general ledger at year end. In English, it is something you get arrested for. Same eight letters, meaningfully different consequences.
It survives in this codebase for the least glamorous reason imaginable: the contracts are written in
Norwegian, and a clause matcher has to look for the word the vendor actually typed. So we renamed the one
place where we used it to describe our own behaviour, and left the rest as the false friend it is —
with anti_bribery sitting two lines below it in the same list, quietly doing the job everyone assumes
kickback is doing.
If you are reading this because you grepped the repository for something alarming: this was the alarming thing, and it is a discount.
Tech Stack
Runtime — Python 3.10+
Protocol — MCP over JSON-RPC 2.0 (stdio); HTTP for admin/A2A/webhooks
Relational + vector — PostgreSQL 16 with
pgvectorandpgcryptoEpisodic store — MongoDB 7.0
Cache / queues — Redis 7.4 (+
rq)Object storage — MinIO (S3-compatible)
NLP / graph — spaCy (entities), NetworkX, HDBSCAN, cross-encoder NLI
Code parsing — Tree-sitter
Validation — Pydantic V2
Observability — OpenTelemetry, Prometheus, Jaeger
Transitive dependencies are pinned in requirements.lock; regenerate with make lockfile.
Testing & Quality Gates
pytest tests/ # full suite (RLS scoping, Saga rollbacks, temporal reads, tools)
pytest -m integration # integration tests (require running backing services)
make lint # ruff check + ruff format --check (the CI gate)
make typecheck # mypy (strict)
make fmt # apply the formatterDocumentation
The docs/ tree is the source of truth. Start here:
Area | Document |
Get running fast | |
How it talks | |
Architecture | |
Configuration | |
Security | |
Cognition | |
Time & simulation | |
Integrations | |
Edge | |
Business engines | |
Design decisions |
Production Checklist
Set
NCE_ENV=production; supply strong randomNCE_API_KEY,NCE_ADMIN_API_KEY,NCE_MASTER_KEY(≥32 bytes).NCE_ADMIN_PASSWORDmust be a$pbkdf2$…hash; setNCE_LOAD_DOTENV=false,NCE_ALLOW_ADMIN_DOTENV_PERSIST=false.Keep guardrails on:
NCE_ADMIN_OVERRIDE=false,NCE_BYPASS_WORM=false,NCE_BYPASS_RLS=false.Enforce TLS everywhere (
?sslmode=requirefor Postgres); preferNCE_ADMIN_MTLS_ENABLED=truebehind your edge proxy.Leave the
prevent_mutationtrigger onevent_login place — never disable WORM.Migration MCP tools stay disabled in prod (
NCE_DISABLE_MIGRATION_MCP=true) outside controlled windows.Rotate HMAC keys and JWT certificates on a schedule.
NCE — Neuro-Cognitive Engine · v3.0.0 · © Sindre Løvlie Haugen · AGPL-3.0. Formerly TriMCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sindrehaugen/neuro-cognitive-engine'
If you have feedback or need assistance with the MCP directory API, please join our Discord server