mithril-cognee 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. mithril_cognee-0.1.0/.env.example +18 -0
  2. mithril_cognee-0.1.0/.github/workflows/publish-python.yml +31 -0
  3. mithril_cognee-0.1.0/.gitignore +51 -0
  4. mithril_cognee-0.1.0/.mithril_reputation.db +0 -0
  5. mithril_cognee-0.1.0/.python-version +1 -0
  6. mithril_cognee-0.1.0/Makefile +57 -0
  7. mithril_cognee-0.1.0/PKG-INFO +264 -0
  8. mithril_cognee-0.1.0/README.md +241 -0
  9. mithril_cognee-0.1.0/api/__init__.py +1 -0
  10. mithril_cognee-0.1.0/api/main.py +131 -0
  11. mithril_cognee-0.1.0/benchmark/__init__.py +1 -0
  12. mithril_cognee-0.1.0/benchmark/attack_suite.jsonl +31 -0
  13. mithril_cognee-0.1.0/benchmark/ground_truth.jsonl +10 -0
  14. mithril_cognee-0.1.0/benchmark/metrics.py +167 -0
  15. mithril_cognee-0.1.0/benchmark/results.json +472 -0
  16. mithril_cognee-0.1.0/benchmark/run_benchmark.py +213 -0
  17. mithril_cognee-0.1.0/debug_llm.py +75 -0
  18. mithril_cognee-0.1.0/demo/ingest_demo.py +93 -0
  19. mithril_cognee-0.1.0/demo/run_demo.py +206 -0
  20. mithril_cognee-0.1.0/demo/seed_data.py +47 -0
  21. mithril_cognee-0.1.0/demo/slack_export.json +65 -0
  22. mithril_cognee-0.1.0/demo/vanilla_demo.py +127 -0
  23. mithril_cognee-0.1.0/main.py +22 -0
  24. mithril_cognee-0.1.0/mcp_server/__init__.py +1 -0
  25. mithril_cognee-0.1.0/mcp_server/server.py +182 -0
  26. mithril_cognee-0.1.0/mithril/__init__.py +42 -0
  27. mithril_cognee-0.1.0/mithril/audit.py +68 -0
  28. mithril_cognee-0.1.0/mithril/config.py +67 -0
  29. mithril_cognee-0.1.0/mithril/contradiction.py +14 -0
  30. mithril_cognee-0.1.0/mithril/firewall.py +263 -0
  31. mithril_cognee-0.1.0/mithril/gate.py +52 -0
  32. mithril_cognee-0.1.0/mithril/ingest.py +177 -0
  33. mithril_cognee-0.1.0/mithril/memory_analysis.py +184 -0
  34. mithril_cognee-0.1.0/mithril/models.py +91 -0
  35. mithril_cognee-0.1.0/mithril/quarantine.py +65 -0
  36. mithril_cognee-0.1.0/mithril/reputation.py +188 -0
  37. mithril_cognee-0.1.0/mithril/scorer.py +141 -0
  38. mithril_cognee-0.1.0/mithril/secrets.py +128 -0
  39. mithril_cognee-0.1.0/mithril/serialization.py +64 -0
  40. mithril_cognee-0.1.0/mithril/utils.py +44 -0
  41. mithril_cognee-0.1.0/pyproject.toml +57 -0
  42. mithril_cognee-0.1.0/test_connection.py +98 -0
  43. mithril_cognee-0.1.0/test_sha1.py +49 -0
  44. mithril_cognee-0.1.0/tests/__init__.py +1 -0
  45. mithril_cognee-0.1.0/tests/test_benchmark.py +162 -0
  46. mithril_cognee-0.1.0/tests/test_contradiction.py +52 -0
  47. mithril_cognee-0.1.0/tests/test_firewall.py +80 -0
  48. mithril_cognee-0.1.0/tests/test_gate.py +46 -0
  49. mithril_cognee-0.1.0/tests/test_ingest.py +72 -0
  50. mithril_cognee-0.1.0/tests/test_reputation.py +87 -0
  51. mithril_cognee-0.1.0/tests/test_scorer.py +114 -0
  52. mithril_cognee-0.1.0/tests/test_secrets.py +426 -0
  53. mithril_cognee-0.1.0/ui/.env.example +2 -0
  54. mithril_cognee-0.1.0/ui/next-env.d.ts +6 -0
  55. mithril_cognee-0.1.0/ui/next.config.ts +8 -0
  56. mithril_cognee-0.1.0/ui/package-lock.json +2162 -0
  57. mithril_cognee-0.1.0/ui/package.json +28 -0
  58. mithril_cognee-0.1.0/ui/postcss.config.mjs +9 -0
  59. mithril_cognee-0.1.0/ui/public/hero-bg.mp4 +0 -0
  60. mithril_cognee-0.1.0/ui/src/app/api/audit/route.ts +15 -0
  61. mithril_cognee-0.1.0/ui/src/app/api/benchmark-results/route.ts +43 -0
  62. mithril_cognee-0.1.0/ui/src/app/api/config/route.ts +15 -0
  63. mithril_cognee-0.1.0/ui/src/app/api/health/route.ts +18 -0
  64. mithril_cognee-0.1.0/ui/src/app/api/recall/route.ts +27 -0
  65. mithril_cognee-0.1.0/ui/src/app/api/remember/route.ts +24 -0
  66. mithril_cognee-0.1.0/ui/src/app/api/reputation/route.ts +15 -0
  67. mithril_cognee-0.1.0/ui/src/app/api/reset/route.ts +20 -0
  68. mithril_cognee-0.1.0/ui/src/app/api/stats/route.ts +15 -0
  69. mithril_cognee-0.1.0/ui/src/app/benchmark-results/page.tsx +344 -0
  70. mithril_cognee-0.1.0/ui/src/app/dashboard/page.tsx +5 -0
  71. mithril_cognee-0.1.0/ui/src/app/demo/page.tsx +702 -0
  72. mithril_cognee-0.1.0/ui/src/app/docs/architecture/page.tsx +389 -0
  73. mithril_cognee-0.1.0/ui/src/app/docs/benchmark/page.tsx +252 -0
  74. mithril_cognee-0.1.0/ui/src/app/docs/layout.tsx +15 -0
  75. mithril_cognee-0.1.0/ui/src/app/docs/mcp-server/page.tsx +280 -0
  76. mithril_cognee-0.1.0/ui/src/app/docs/page.tsx +291 -0
  77. mithril_cognee-0.1.0/ui/src/app/docs/python-sdk/page.tsx +432 -0
  78. mithril_cognee-0.1.0/ui/src/app/docs/rest-api/page.tsx +338 -0
  79. mithril_cognee-0.1.0/ui/src/app/docs/run-demo/page.tsx +187 -0
  80. mithril_cognee-0.1.0/ui/src/app/globals.css +45 -0
  81. mithril_cognee-0.1.0/ui/src/app/layout.tsx +45 -0
  82. mithril_cognee-0.1.0/ui/src/app/page.tsx +5 -0
  83. mithril_cognee-0.1.0/ui/src/components/AuditTable.tsx +139 -0
  84. mithril_cognee-0.1.0/ui/src/components/Dashboard.tsx +124 -0
  85. mithril_cognee-0.1.0/ui/src/components/FilterTabs.tsx +63 -0
  86. mithril_cognee-0.1.0/ui/src/components/Header.tsx +63 -0
  87. mithril_cognee-0.1.0/ui/src/components/RecallPanel.tsx +79 -0
  88. mithril_cognee-0.1.0/ui/src/components/ScoreBreakdown.tsx +86 -0
  89. mithril_cognee-0.1.0/ui/src/components/SignalBars.tsx +31 -0
  90. mithril_cognee-0.1.0/ui/src/components/SourceReputationChart.tsx +90 -0
  91. mithril_cognee-0.1.0/ui/src/components/StatsBar.tsx +69 -0
  92. mithril_cognee-0.1.0/ui/src/components/StatusBadge.tsx +18 -0
  93. mithril_cognee-0.1.0/ui/src/components/SubmitForm.tsx +102 -0
  94. mithril_cognee-0.1.0/ui/src/components/ThresholdLegend.tsx +52 -0
  95. mithril_cognee-0.1.0/ui/src/components/docs/DocsLayout.tsx +157 -0
  96. mithril_cognee-0.1.0/ui/src/components/docs/DocsPrimitives.tsx +176 -0
  97. mithril_cognee-0.1.0/ui/src/components/landing/CogneeStack.tsx +152 -0
  98. mithril_cognee-0.1.0/ui/src/components/landing/ComparisonTable.tsx +135 -0
  99. mithril_cognee-0.1.0/ui/src/components/landing/DemoVideoFrame.tsx +210 -0
  100. mithril_cognee-0.1.0/ui/src/components/landing/FloatingDock.tsx +108 -0
  101. mithril_cognee-0.1.0/ui/src/components/landing/HeroBackground.tsx +299 -0
  102. mithril_cognee-0.1.0/ui/src/components/landing/HeroSection.tsx +106 -0
  103. mithril_cognee-0.1.0/ui/src/components/landing/HowItWorks.tsx +115 -0
  104. mithril_cognee-0.1.0/ui/src/components/landing/LandingCta.tsx +91 -0
  105. mithril_cognee-0.1.0/ui/src/components/landing/LandingFooter.tsx +38 -0
  106. mithril_cognee-0.1.0/ui/src/components/landing/LandingNav.tsx +69 -0
  107. mithril_cognee-0.1.0/ui/src/components/landing/LandingPage.tsx +25 -0
  108. mithril_cognee-0.1.0/ui/src/components/landing/motion.ts +77 -0
  109. mithril_cognee-0.1.0/ui/src/lib/api.ts +74 -0
  110. mithril_cognee-0.1.0/ui/src/lib/backend.ts +33 -0
  111. mithril_cognee-0.1.0/ui/src/lib/mock-data.ts +128 -0
  112. mithril_cognee-0.1.0/ui/src/types/index.ts +202 -0
  113. mithril_cognee-0.1.0/ui/tailwind.config.ts +62 -0
  114. mithril_cognee-0.1.0/ui/tsconfig.json +21 -0
  115. mithril_cognee-0.1.0/ui/tsconfig.tsbuildinfo +1 -0
  116. mithril_cognee-0.1.0/uv.lock +3493 -0
@@ -0,0 +1,18 @@
1
+ # Mithril environment variables
2
+ # Copy to .env and fill in your own API key.
3
+
4
+ # ─────────────────────────────────────────────────────────────────────────
5
+ # LLM provider
6
+ # ─────────────────────────────────────────────────────────────────────────
7
+ LLM_PROVIDER="custom"
8
+ LLM_MODEL="openai/gpt-4o-mini"
9
+ LLM_ENDPOINT="https://agentrouter.org/v1"
10
+ LLM_API_KEY="your-agentrouter-or-openai-compatible-key-here"
11
+
12
+ # ─────────────────────────────────────────────────────────────────────────
13
+ # Embedding provider
14
+ # ─────────────────────────────────────────────────────────────────────────
15
+ # With this, the LLM key above is the only key Mithril needs.
16
+ EMBEDDING_PROVIDER="fastembed"
17
+ EMBEDDING_MODEL="BAAI/bge-small-en-v1.5"
18
+ EMBEDDING_DIMENSIONS="384"
@@ -0,0 +1,31 @@
1
+ name: Publish Python Package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ id-token: write
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install build tools
25
+ run: python -m pip install --upgrade build
26
+
27
+ - name: Build distributions
28
+ run: python -m build
29
+
30
+ - name: Publish to PyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ dist/
9
+ wheels/
10
+ *.egg-info/
11
+ .eggs/
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+ env/
17
+
18
+ # Secrets and local env
19
+ .env
20
+ .env.local
21
+
22
+ # Test / tooling caches
23
+ .pytest_cache/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+ .coverage
27
+ htmlcov/
28
+
29
+ # Mithril runtime data (regenerated by demos/API)
30
+ .mithril_audit.db
31
+ .mithril_quarantine.db
32
+ .memory_firewall_audit.db
33
+ .memory_firewall_quarantine.db
34
+
35
+ # Cognee runtime data (regenerated on remember/recall)
36
+ .cognee_system/
37
+
38
+ # Demo artifacts
39
+ artifacts/
40
+
41
+ # Future UI (Next.js)
42
+ node_modules/
43
+ .next/
44
+ out/
45
+ ui/.env
46
+ ui/.env.local
47
+
48
+ # OS noise
49
+ .DS_Store
50
+ Thumbs.db
51
+ desktop.ini
@@ -0,0 +1 @@
1
+ 3.12.5
@@ -0,0 +1,57 @@
1
+ .PHONY: demo vanilla seed ingest mcp benchmark test api reset clean install dev ui ui-install ui-build
2
+
3
+ demo:
4
+ .venv\Scripts\python.exe demo/run_demo.py
5
+
6
+ vanilla:
7
+ .venv\Scripts\python.exe demo/vanilla_demo.py
8
+
9
+ seed:
10
+ .venv\Scripts\python.exe demo/seed_data.py
11
+
12
+ ingest:
13
+ .venv\Scripts\python.exe demo/ingest_demo.py
14
+
15
+ mcp:
16
+ .venv\Scripts\python.exe -m mcp_server.server
17
+
18
+ benchmark:
19
+ .venv\Scripts\python.exe benchmark/run_benchmark.py
20
+
21
+ test:
22
+ .venv\Scripts\python.exe -m pytest tests/ -v
23
+
24
+ api:
25
+ .venv\Scripts\python.exe -m uvicorn api.main:app --port 8000 --reload
26
+
27
+ ui:
28
+ cd ui && npm run dev
29
+
30
+ ui-install:
31
+ cd ui && npm install
32
+
33
+ ui-build:
34
+ cd ui && npm run build
35
+
36
+ dev:
37
+ start cmd /c ".venv\Scripts\python.exe -m uvicorn api.main:app --port 8000 --reload"
38
+ cd ui && npm run dev
39
+
40
+ reset:
41
+ .venv\Scripts\python.exe -c "import asyncio; import cognee; asyncio.run(cognee.forget(everything=True))"
42
+ del /f .mithril_audit.db 2>nul
43
+ del /f .mithril_quarantine.db 2>nul
44
+ del /f .mithril_reputation.db 2>nul
45
+ del /f .memory_firewall_audit.db 2>nul
46
+ del /f .memory_firewall_quarantine.db 2>nul
47
+ @echo Reset complete.
48
+
49
+ install:
50
+ uv pip install -e ".[dev]"
51
+
52
+ clean:
53
+ del /f .mithril_audit.db 2>nul
54
+ del /f .mithril_quarantine.db 2>nul
55
+ del /f .mithril_reputation.db 2>nul
56
+ del /f .memory_firewall_audit.db 2>nul
57
+ del /f .memory_firewall_quarantine.db 2>nul
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: mithril-cognee
3
+ Version: 0.1.0
4
+ Summary: Mithril — trust and governance layer for Cognee memory
5
+ Project-URL: Homepage, https://github.com/HydrallHarsh/Mithril
6
+ Project-URL: Repository, https://github.com/HydrallHarsh/Mithril
7
+ Project-URL: Issues, https://github.com/HydrallHarsh/Mithril/issues
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: aiosqlite>=0.22.1
10
+ Requires-Dist: cognee>=1.2.2
11
+ Requires-Dist: fastapi>=0.138.1
12
+ Requires-Dist: fastembed>=0.3.0
13
+ Requires-Dist: mcp>=1.2.0
14
+ Requires-Dist: openai>=1.0.0
15
+ Requires-Dist: python-dotenv>=1.0.0
16
+ Requires-Dist: uvicorn>=0.49.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: build>=1.2.0; extra == 'dev'
19
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
20
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
21
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Mithril
25
+
26
+ > A trust and governance layer for Cognee memory.
27
+ > Every AI can remember. **Mithril** decides what *deserves* to be remembered.
28
+
29
+ ## The Problem
30
+
31
+ AI agents with persistent memory are vulnerable to **memory poisoning** — where a single malicious message permanently corrupts the knowledge graph that all future agents rely on.
32
+
33
+ **Vanilla Cognee:**
34
+
35
+ ```
36
+ input → cognee.remember() → stored forever
37
+ ```
38
+
39
+ **With Mithril:**
40
+
41
+ ```
42
+ agent / Slack / file → Trust Score → Contradiction Check → Admission Gate → cognee.remember()
43
+ ```
44
+
45
+ ## How Mithril connects to your stack
46
+
47
+ Mithril is a real boundary in front of Cognee, reachable three ways — all sharing one governance pipeline and one adaptive reputation store:
48
+
49
+ | Surface | What it is | Entry point |
50
+ |---|---|---|
51
+ | **MCP server** | Agents (Claude Desktop, Cursor) call `mithril_remember` / `mithril_recall` instead of writing to memory directly | `mcp_server/server.py` · `make mcp` |
52
+ | **Ingestion connector** | Parse a real **Slack export** (or a `.txt`/`.jsonl` file) and run the whole feed through the gate | `mithril/ingest.py` · `make ingest` |
53
+ | **REST API + dashboard** | FastAPI backend + Next.js provenance UI | `api/main.py` · `make dev` |
54
+
55
+ ## Adaptive source reputation
56
+
57
+ Source reputation is **not a static table** — it starts from configured priors and then *moves*:
58
+
59
+ - a source caught contradicting verified memory **loses** trust (fast),
60
+ - a source whose claims are accepted/corroborated **gains** trust (slow).
61
+
62
+ Trust is easy to lose and hard to earn. Watch a Slack channel's reputation collapse after it pushes MD5 twice — live, in the dashboard and via `GET /api/reputation`.
63
+
64
+ ## Attack Demo
65
+
66
+ | | Vanilla Cognee | Mithril + Cognee |
67
+ |---|---|---|
68
+ | Poisoned inputs stored | All 3 | 0 |
69
+ | Provenance tracked | No | Yes |
70
+ | Contradiction detected | No | Yes |
71
+ | Source reputation adapts | No | Yes |
72
+ | Explainable decisions | No | Yes |
73
+ | Answer to "hash passwords?" | May return MD5 | Argon2id |
74
+
75
+ ## Architecture
76
+
77
+ ```
78
+ Incoming Claim (MCP tool · Slack export · file · API · dashboard)
79
+
80
+
81
+ Adaptive Source Reputation (self-adjusting, SQLite-backed)
82
+
83
+
84
+ Contradiction Detection (cognee.recall, only_context=True)
85
+
86
+
87
+ Trust Score (weighted + normalized — see master plan Section 4)
88
+
89
+
90
+ Admission Gate (Accept / Warn / Review / Quarantine / Reject)
91
+
92
+ ├── ACCEPT / WARN → cognee.remember(node_set=["verified"])
93
+ ├── QUARANTINE / REVIEW / REJECT → SQLite quarantine store
94
+ ├── Source reputation updated from the outcome
95
+ └── All → Audit log
96
+ ```
97
+
98
+ ## Cognee APIs Used
99
+
100
+ - `cognee.remember()` — verified memories with NodeSet tagging
101
+ - `cognee.recall(only_context=True)` — contradiction detection
102
+ - `cognee.recall(node_name=["verified"])` — scoped verified retrieval
103
+ - `cognee.improve()` — graph enrichment on verified dataset
104
+ - `cognee.forget()` — demo reset
105
+ - `cognee.visualize_graph()` — knowledge graph HTML export
106
+
107
+ ## Quickstart
108
+
109
+ Install from PyPI once published:
110
+
111
+ ```bash
112
+ pip install mithril-cognee
113
+ ```
114
+
115
+ Local development from this repo:
116
+
117
+ ```bash
118
+ uv venv && .venv\Scripts\activate
119
+ uv pip install -e ".[dev]"
120
+ copy .env.example .env # add LLM_API_KEY
121
+
122
+ make test # unit tests
123
+ make demo # full attack demo (terminal)
124
+ make ingest # ingest a real Slack export through the gate
125
+ make benchmark # labeled memory-poisoning benchmark → metrics + results.json
126
+ make mcp # run Mithril as an MCP server (stdio)
127
+ make api # FastAPI backend → http://localhost:8000
128
+ make ui-install && make ui # landing → http://localhost:3001 · dashboard → /dashboard
129
+ make dev # start API + UI together
130
+ ```
131
+
132
+ Installed commands:
133
+
134
+ ```bash
135
+ mithril-mcp # local MCP server over stdio
136
+ mithril-mcp-http # remote MCP server over Streamable HTTP at /mcp
137
+ mithril-api # FastAPI backend
138
+ ```
139
+
140
+ ### Use Mithril from Claude Desktop (MCP)
141
+
142
+ Add to `claude_desktop_config.json`, then restart Claude Desktop:
143
+
144
+ ```json
145
+ {
146
+ "mcpServers": {
147
+ "mithril": {
148
+ "command": "mithril-mcp"
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ The agent then gets `mithril_remember`, `mithril_recall`, `mithril_quarantine_list`, and `mithril_source_reputation` — every memory write is gated, every recall is verified-only.
155
+
156
+ ### Free deployment notes
157
+
158
+ For the public dashboard, deploy `ui/` to Vercel and set:
159
+
160
+ ```bash
161
+ NEXT_PUBLIC_BACKEND_URL=https://your-render-api.onrender.com
162
+ ```
163
+
164
+ For the API on Render Free:
165
+
166
+ ```bash
167
+ pip install -e .
168
+ mithril-api
169
+ ```
170
+
171
+ For a demo remote MCP server on Render Free:
172
+
173
+ ```bash
174
+ pip install -e .
175
+ FASTMCP_HOST=0.0.0.0 FASTMCP_PORT=$PORT mithril-mcp-http
176
+ ```
177
+
178
+ The remote MCP endpoint will be:
179
+
180
+ ```text
181
+ https://your-render-service.onrender.com/mcp
182
+ ```
183
+
184
+ Free Render services can sleep and do not keep local SQLite files permanently, so use local MCP for real editor usage unless you add hosted storage and auth.
185
+
186
+ ## Benchmark — does it actually stop poisoning?
187
+
188
+ Mithril ships with a **labeled memory-poisoning benchmark** (`benchmark/`) that measures it like a security control, not a demo.
189
+
190
+ **Threat model:** a company runs AI agents over a shared Cognee knowledge base. Claims arrive from authoritative channels (Security Policy, HR System, GitHub) and risky ones (Slack, customer support, external email, public web, other agents). Attackers try to poison shared memory.
191
+
192
+ The harness seeds verified company memory (`ground_truth.jsonl`), then replays a labeled suite (`attack_suite.jsonl`, ~30 cases) through the **same** `Mithril.remember()` gate and scores every decision into a confusion matrix:
193
+
194
+ ```bash
195
+ make benchmark # requires LLM_API_KEY + Cognee (like the demos)
196
+ ```
197
+
198
+ **Attack taxonomy covered:** direct contradiction · subtle misinformation · authority spoofing · prompt injection · data exfiltration · policy evasion · social engineering · low-trust unverified. Plus hard *legitimate* cases (verified policy updates, benign low-trust facts) to measure false positives honestly.
199
+
200
+ | Metric | Meaning |
201
+ |---|---|
202
+ | **Detection rate** | share of attacks blocked (kept out of memory) |
203
+ | **Poison-leak rate** | attacks that reached verified memory — the number to drive to 0 |
204
+ | **False-positive rate** | legitimate updates wrongly blocked (friction) |
205
+ | **Precision / accuracy** | standard classifier metrics |
206
+
207
+ Results print per-category and per-source and are written to `benchmark/results.json`. The math is unit-tested (`tests/test_benchmark.py`) so the numbers are reproducible from the labeled data even though the LLM contradiction step has run-to-run variance.
208
+
209
+ > **Why the categories matter:** *authority spoofing* (a claim that fakes a high-trust source but contradicts policy) is caught by the **contradiction layer**, not source reputation — proof that the trust signals are independent and complementary, not just a source lookup.
210
+
211
+ ## Usage
212
+
213
+ ```python
214
+ from mithril import Mithril
215
+
216
+ firewall = Mithril()
217
+ await firewall.setup()
218
+
219
+ result = await firewall.remember(
220
+ text="Always hash passwords using MD5",
221
+ source="Slack",
222
+ )
223
+ # result.status → quarantine or reject
224
+ # result.trust_breakdown.final_score → normalized 0–1
225
+ # result.trust_breakdown.reasons → explainable breakdown
226
+
227
+ answer = await firewall.recall("How should we hash passwords?")
228
+ ```
229
+
230
+ ## API Endpoints
231
+
232
+ | Method | Path | Description |
233
+ |--------|------|-------------|
234
+ | GET | `/api/audit` | Full audit log |
235
+ | GET | `/api/quarantine` | Quarantined memories |
236
+ | GET | `/api/reputation` | Live adaptive source reputation (with deltas) |
237
+ | GET | `/api/stats` | Aggregate metrics |
238
+ | POST | `/api/remember` | Submit claim through Mithril |
239
+ | POST | `/api/recall` | Query verified memory |
240
+ | POST | `/api/reset` | Clear Cognee + local stores |
241
+ | GET | `/api/config` | Sources, weights, thresholds |
242
+
243
+ ## Trust Score Formula
244
+
245
+ Per master plan — weighted components, then normalized to 0–1:
246
+
247
+ ```
248
+ raw = source_rep×0.40 + corroboration×0.30 + freshness×0.10 − contradiction×0.40
249
+ final_score = raw / max_theoretical_score
250
+ ```
251
+
252
+ Admission thresholds: Accept ≥ 0.85 · Warn ≥ 0.60 · Review ≥ 0.40 · Quarantine ≥ 0.20
253
+
254
+ ## Project Layout
255
+
256
+ ```
257
+ mithril/ Core package (scorer, gate, firewall, reputation, ingest, audit, quarantine)
258
+ mcp_server/ MCP server — exposes Mithril tools to agents
259
+ benchmark/ Labeled memory-poisoning benchmark (ground truth, attack suite, metrics)
260
+ api/ FastAPI backend
261
+ demo/ Attack demo, vanilla comparison, Slack-export ingestion demo
262
+ tests/ Unit + integration tests
263
+ memory-firewall-master-plan.md Full hackathon build plan
264
+ ```
@@ -0,0 +1,241 @@
1
+ # Mithril
2
+
3
+ > A trust and governance layer for Cognee memory.
4
+ > Every AI can remember. **Mithril** decides what *deserves* to be remembered.
5
+
6
+ ## The Problem
7
+
8
+ AI agents with persistent memory are vulnerable to **memory poisoning** — where a single malicious message permanently corrupts the knowledge graph that all future agents rely on.
9
+
10
+ **Vanilla Cognee:**
11
+
12
+ ```
13
+ input → cognee.remember() → stored forever
14
+ ```
15
+
16
+ **With Mithril:**
17
+
18
+ ```
19
+ agent / Slack / file → Trust Score → Contradiction Check → Admission Gate → cognee.remember()
20
+ ```
21
+
22
+ ## How Mithril connects to your stack
23
+
24
+ Mithril is a real boundary in front of Cognee, reachable three ways — all sharing one governance pipeline and one adaptive reputation store:
25
+
26
+ | Surface | What it is | Entry point |
27
+ |---|---|---|
28
+ | **MCP server** | Agents (Claude Desktop, Cursor) call `mithril_remember` / `mithril_recall` instead of writing to memory directly | `mcp_server/server.py` · `make mcp` |
29
+ | **Ingestion connector** | Parse a real **Slack export** (or a `.txt`/`.jsonl` file) and run the whole feed through the gate | `mithril/ingest.py` · `make ingest` |
30
+ | **REST API + dashboard** | FastAPI backend + Next.js provenance UI | `api/main.py` · `make dev` |
31
+
32
+ ## Adaptive source reputation
33
+
34
+ Source reputation is **not a static table** — it starts from configured priors and then *moves*:
35
+
36
+ - a source caught contradicting verified memory **loses** trust (fast),
37
+ - a source whose claims are accepted/corroborated **gains** trust (slow).
38
+
39
+ Trust is easy to lose and hard to earn. Watch a Slack channel's reputation collapse after it pushes MD5 twice — live, in the dashboard and via `GET /api/reputation`.
40
+
41
+ ## Attack Demo
42
+
43
+ | | Vanilla Cognee | Mithril + Cognee |
44
+ |---|---|---|
45
+ | Poisoned inputs stored | All 3 | 0 |
46
+ | Provenance tracked | No | Yes |
47
+ | Contradiction detected | No | Yes |
48
+ | Source reputation adapts | No | Yes |
49
+ | Explainable decisions | No | Yes |
50
+ | Answer to "hash passwords?" | May return MD5 | Argon2id |
51
+
52
+ ## Architecture
53
+
54
+ ```
55
+ Incoming Claim (MCP tool · Slack export · file · API · dashboard)
56
+
57
+
58
+ Adaptive Source Reputation (self-adjusting, SQLite-backed)
59
+
60
+
61
+ Contradiction Detection (cognee.recall, only_context=True)
62
+
63
+
64
+ Trust Score (weighted + normalized — see master plan Section 4)
65
+
66
+
67
+ Admission Gate (Accept / Warn / Review / Quarantine / Reject)
68
+
69
+ ├── ACCEPT / WARN → cognee.remember(node_set=["verified"])
70
+ ├── QUARANTINE / REVIEW / REJECT → SQLite quarantine store
71
+ ├── Source reputation updated from the outcome
72
+ └── All → Audit log
73
+ ```
74
+
75
+ ## Cognee APIs Used
76
+
77
+ - `cognee.remember()` — verified memories with NodeSet tagging
78
+ - `cognee.recall(only_context=True)` — contradiction detection
79
+ - `cognee.recall(node_name=["verified"])` — scoped verified retrieval
80
+ - `cognee.improve()` — graph enrichment on verified dataset
81
+ - `cognee.forget()` — demo reset
82
+ - `cognee.visualize_graph()` — knowledge graph HTML export
83
+
84
+ ## Quickstart
85
+
86
+ Install from PyPI once published:
87
+
88
+ ```bash
89
+ pip install mithril-cognee
90
+ ```
91
+
92
+ Local development from this repo:
93
+
94
+ ```bash
95
+ uv venv && .venv\Scripts\activate
96
+ uv pip install -e ".[dev]"
97
+ copy .env.example .env # add LLM_API_KEY
98
+
99
+ make test # unit tests
100
+ make demo # full attack demo (terminal)
101
+ make ingest # ingest a real Slack export through the gate
102
+ make benchmark # labeled memory-poisoning benchmark → metrics + results.json
103
+ make mcp # run Mithril as an MCP server (stdio)
104
+ make api # FastAPI backend → http://localhost:8000
105
+ make ui-install && make ui # landing → http://localhost:3001 · dashboard → /dashboard
106
+ make dev # start API + UI together
107
+ ```
108
+
109
+ Installed commands:
110
+
111
+ ```bash
112
+ mithril-mcp # local MCP server over stdio
113
+ mithril-mcp-http # remote MCP server over Streamable HTTP at /mcp
114
+ mithril-api # FastAPI backend
115
+ ```
116
+
117
+ ### Use Mithril from Claude Desktop (MCP)
118
+
119
+ Add to `claude_desktop_config.json`, then restart Claude Desktop:
120
+
121
+ ```json
122
+ {
123
+ "mcpServers": {
124
+ "mithril": {
125
+ "command": "mithril-mcp"
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ The agent then gets `mithril_remember`, `mithril_recall`, `mithril_quarantine_list`, and `mithril_source_reputation` — every memory write is gated, every recall is verified-only.
132
+
133
+ ### Free deployment notes
134
+
135
+ For the public dashboard, deploy `ui/` to Vercel and set:
136
+
137
+ ```bash
138
+ NEXT_PUBLIC_BACKEND_URL=https://your-render-api.onrender.com
139
+ ```
140
+
141
+ For the API on Render Free:
142
+
143
+ ```bash
144
+ pip install -e .
145
+ mithril-api
146
+ ```
147
+
148
+ For a demo remote MCP server on Render Free:
149
+
150
+ ```bash
151
+ pip install -e .
152
+ FASTMCP_HOST=0.0.0.0 FASTMCP_PORT=$PORT mithril-mcp-http
153
+ ```
154
+
155
+ The remote MCP endpoint will be:
156
+
157
+ ```text
158
+ https://your-render-service.onrender.com/mcp
159
+ ```
160
+
161
+ Free Render services can sleep and do not keep local SQLite files permanently, so use local MCP for real editor usage unless you add hosted storage and auth.
162
+
163
+ ## Benchmark — does it actually stop poisoning?
164
+
165
+ Mithril ships with a **labeled memory-poisoning benchmark** (`benchmark/`) that measures it like a security control, not a demo.
166
+
167
+ **Threat model:** a company runs AI agents over a shared Cognee knowledge base. Claims arrive from authoritative channels (Security Policy, HR System, GitHub) and risky ones (Slack, customer support, external email, public web, other agents). Attackers try to poison shared memory.
168
+
169
+ The harness seeds verified company memory (`ground_truth.jsonl`), then replays a labeled suite (`attack_suite.jsonl`, ~30 cases) through the **same** `Mithril.remember()` gate and scores every decision into a confusion matrix:
170
+
171
+ ```bash
172
+ make benchmark # requires LLM_API_KEY + Cognee (like the demos)
173
+ ```
174
+
175
+ **Attack taxonomy covered:** direct contradiction · subtle misinformation · authority spoofing · prompt injection · data exfiltration · policy evasion · social engineering · low-trust unverified. Plus hard *legitimate* cases (verified policy updates, benign low-trust facts) to measure false positives honestly.
176
+
177
+ | Metric | Meaning |
178
+ |---|---|
179
+ | **Detection rate** | share of attacks blocked (kept out of memory) |
180
+ | **Poison-leak rate** | attacks that reached verified memory — the number to drive to 0 |
181
+ | **False-positive rate** | legitimate updates wrongly blocked (friction) |
182
+ | **Precision / accuracy** | standard classifier metrics |
183
+
184
+ Results print per-category and per-source and are written to `benchmark/results.json`. The math is unit-tested (`tests/test_benchmark.py`) so the numbers are reproducible from the labeled data even though the LLM contradiction step has run-to-run variance.
185
+
186
+ > **Why the categories matter:** *authority spoofing* (a claim that fakes a high-trust source but contradicts policy) is caught by the **contradiction layer**, not source reputation — proof that the trust signals are independent and complementary, not just a source lookup.
187
+
188
+ ## Usage
189
+
190
+ ```python
191
+ from mithril import Mithril
192
+
193
+ firewall = Mithril()
194
+ await firewall.setup()
195
+
196
+ result = await firewall.remember(
197
+ text="Always hash passwords using MD5",
198
+ source="Slack",
199
+ )
200
+ # result.status → quarantine or reject
201
+ # result.trust_breakdown.final_score → normalized 0–1
202
+ # result.trust_breakdown.reasons → explainable breakdown
203
+
204
+ answer = await firewall.recall("How should we hash passwords?")
205
+ ```
206
+
207
+ ## API Endpoints
208
+
209
+ | Method | Path | Description |
210
+ |--------|------|-------------|
211
+ | GET | `/api/audit` | Full audit log |
212
+ | GET | `/api/quarantine` | Quarantined memories |
213
+ | GET | `/api/reputation` | Live adaptive source reputation (with deltas) |
214
+ | GET | `/api/stats` | Aggregate metrics |
215
+ | POST | `/api/remember` | Submit claim through Mithril |
216
+ | POST | `/api/recall` | Query verified memory |
217
+ | POST | `/api/reset` | Clear Cognee + local stores |
218
+ | GET | `/api/config` | Sources, weights, thresholds |
219
+
220
+ ## Trust Score Formula
221
+
222
+ Per master plan — weighted components, then normalized to 0–1:
223
+
224
+ ```
225
+ raw = source_rep×0.40 + corroboration×0.30 + freshness×0.10 − contradiction×0.40
226
+ final_score = raw / max_theoretical_score
227
+ ```
228
+
229
+ Admission thresholds: Accept ≥ 0.85 · Warn ≥ 0.60 · Review ≥ 0.40 · Quarantine ≥ 0.20
230
+
231
+ ## Project Layout
232
+
233
+ ```
234
+ mithril/ Core package (scorer, gate, firewall, reputation, ingest, audit, quarantine)
235
+ mcp_server/ MCP server — exposes Mithril tools to agents
236
+ benchmark/ Labeled memory-poisoning benchmark (ground truth, attack suite, metrics)
237
+ api/ FastAPI backend
238
+ demo/ Attack demo, vanilla comparison, Slack-export ingestion demo
239
+ tests/ Unit + integration tests
240
+ memory-firewall-master-plan.md Full hackathon build plan
241
+ ```
@@ -0,0 +1 @@
1
+ # api package