Unified second brain for AI agents โ 5-tier memory, HRR reasoning, 10 MCP tools, conditional verify-on-stop
Project description
๐ง Eling
Unified second brain for AI agents โ 5-tier memory, HRR reasoning, 10 MCP tools, conditional verify-on-stop
"Eling" (Javanese): to remember, to be conscious, to be aware
โจ What is Eling?
Eling is a unified second brain for AI agents. It merges 5 memory tiers into one MCP server โ no external databases, no cloud services needed for local operation.
๐ง Tier 5: NOTION โ online brain, human-readable (optional)
๐ Tier 4: KB โ FTS5 knowledge corpus
๐ธ๏ธ Tier 3: CODE โ codegraph symbol intelligence
๐ Tier 2: FACTS โ SQLite + HRR + BM25 hybrid with trust scoring
๐ Tier 1: BUILTIN โ Hermes MEMORY.md / USER.md
All accessible via 9 MCP tools from a single stdio server:
| Tool | Purpose |
|---|---|
eling_remember |
Store content โ auto-routes to facts (short) or KB (long) |
eling_recall |
Cross-layer search with RRF fusion (BM25 + trigram + porter) |
eling_reason |
Compositional query tying multiple entities together |
eling_probe |
Get all facts about an entity |
eling_reflect |
Promote a high-trust fact to Notion as a permanent page |
eling_sync |
Bidirectional sync between memory layers |
eling_stats |
Show per-layer statistics |
eling_think |
Synthesis + gap analysis across layers |
eling_export |
Full brain export as JSON or Markdown |
eling_verify |
Query/record verification status (conditional) |
๐ Quick Start
pip install eling
# Run MCP server (stdio โ plug into any MCP host)
python3 -m eling.mcp_server
# Or use the CLI
python3 -m eling --help
๐ Hermes Integration
Eling plugs into Hermes Agent at 3 levels:
1. MCP Server โ add to ~/.hermes/config.yaml:
mcp_servers:
eling:
command: python3
args: ["-m", "eling.mcp_server"]
enabled: true
2. Memory Provider โ sets default brain for remember/recall:
memory:
provider: eling
3. Plugin โ registers eling_remember + eling_recall as quick tools:
plugins:
enabled:
- eling
eling:
home: /root/.eling
๐ CLI Commands
python3 -m eling remember "I learned that..."
python3 -m eling recall "what did I learn about X"
python3 -m eling probe "X"
python3 -m eling reason ["X", "Y"]
python3 -m eling reflect 1 # promote fact_id 1 to Notion
python3 -m eling stats
python3 -m eling export --format markdown
python3 -m eling sync --direction push # facts โ Notion
๐ Notion Setup (Tier 5)
Optional โ skip this if you only need local memory.
-
Create a Notion integration at https://www.notion.so/my-integrations
- Give it a name (e.g. "Eling Brain")
- Copy the Internal Integration Secret (starts with
ntn_)
-
Share a parent page with your integration
- Open the page you want as your second brain root
- Click Share โ Invite โ select your integration
- Copy the page URL and extract the page ID (the UUID in the URL, e.g.
38f7b66e-c7e0-813f-85b0-d37cef59c1f7)
-
Set environment variables:
export NOTION_API_KEY="ntn_..."
export NOTION_PARENT_PAGE_ID="38f7b66e-c7e0-813f-85b0-d37cef59c1f7"
Note-taking behavior
Once configured, eling auto-creates a ๐ Task Logs child page under your parent on first use:
๐ Hermes Vault (parent page โ your configured root)
โโโ ๐ Task Logs โ auto-created by eling
โ โโโ ๐ก Eling test โ child pages from eling_reflect / remember(layer="notion")
โ โโโ ๐ก Another note
โโโ ๐ API Keys...
โโโ ...
Two ways to add notes to Notion:
| Method | Usage | Route |
|---|---|---|
brain.reflect(fact_id) / eling_reflect |
Promote a high-trust fact to Notion | โ auto-routes by category |
brain.remember("text", layer="notion") / eling_remember with layer=notion |
Store content directly as a Notion page | โ auto-routes by category |
Auto-routing by category
Content is automatically detected and routed to the right child page:
| Category | Triggers | Child page |
|---|---|---|
project_summary |
"project done/complete/selesai", "deploy success", "summary completion" | ๐ฏ Project Summaries |
credential |
"api_key", "password", "secret", "token", "credential" | ๐ Credentials |
address |
"alamat", "address", "domicile", "tinggal di" | ๐ Addresses |
config |
"config", "setup", "setting", "environment" | โ๏ธ Configurations |
| (uncategorised) | Everything else | ๐ Task Logs |
Example:
# Auto-routes to ๐ฏ Project Summaries
b.remember("Project done, deployed to production", layer="notion")
# Auto-routes to ๐ Credentials
b.remember("DATABASE_URL = postgres://...", layer="notion")
# Auto-routes to ๐ Task Logs (no pattern match)
b.remember("General note", layer="notion")
All child pages under these category pages are full Notion pages โ you can edit, move, share, or reference them normally.
Or pass them explicitly in code:
from eling.brain import Brain
b = Brain(
notion_api_key="ntn_...",
notion_parent_id="38f7b66e-..."
)
result = b.reflect(fact_id=1)
print(result) # {"page_id": "...", "promoted": True}
# Or store directly as a note
result = b.remember("Quick note for Notion", layer="notion")
print(result) # {"layer": "notion", "page_id": "...", ...}
Note:
eling_reflectandremember(layer="notion")check availability at call time and return a clear error if any config is missing โ no silent failures.
๐ก๏ธ Verify-on-Stop (Conditional)
Eling provides verify-on-stop nudges for AI agents that lack built-in
verification (e.g., OpenCode, OpenClaw, Cursor, Windsurf). When running under
Hermes, this feature automatically skips โ because Hermes already has its
own agent/verification_stop.py.
How it works
- Auto-detection โ Eling detects the host agent from environment variables
(
HERMES_SESSION_SOURCEโ Hermes,OPENCODE_HOMEโ OpenCode, etc.) - File edit tracking โ When code files are edited via hooks or MCP tools, eling records them in a verification ledger
- Verification nudge โ If code was edited but no passing tests/verification
was recorded, eling produces a
[System: ...]nudge message - Recording โ Agents can call
eling_verifyMCP tool to record verification results (passed,failed,skipped)
Usage via MCP
// Query current status
{ "method": "tools/call", "params": { "name": "eling_verify", "arguments": {} } }
// Record a passing verification
{ "method": "tools/call", "params": {
"name": "eling_verify",
"arguments": { "status": "passed", "command": "pytest", "output": "364 passed" }
} }
Config
| Key | Default | Env | Description |
|---|---|---|---|
verify_on_stop |
true |
ELING_VERIFY_ON_STOP |
Enable nudges for non-Hermes agents |
verify_on_stop_max_attempts |
2 |
ELING_VERIFY_MAX_ATTEMPTS |
Max nudges per session |
adapter |
hermes |
ELING_ADAPTER |
Force adapter type |
plugins:
eling:
adapter: auto # auto-detect from env
verify_on_stop: true
๐๏ธ Architecture
eling/
โโโ mcp_server.py โ JSON-RPC stdio server (9 tools)
โโโ brain.py โ Orchestrator: routing + RRF fusion + sync
โโโ config.py โ Layered config: env โ json โ defaults
โโโ hooks.py โ 15 lifecycle hooks + HookRegistry
โโโ privacy.py โ PII/secret stripping (19 patterns)
โโโ compress.py โ SHA-256 dedup + length compression
โโโ cli.py โ CLI client for all 9 operations
โโโ layers/
โโโ builtin.py โ Tier 1: Hermes MEMORY.md / USER.md loader
โโโ facts.py โ Tier 2: SQLite + HRR + BM25 + trust scoring
โโโ hrr.py โ Holographic Reduced Representations (optional numpy)
โโโ code.py โ Tier 3: CodeLayer wrapper
โโโ code_index.py โ Pure-Python AST+regex code indexer
โโโ kb.py โ Tier 4: FTS5 + porter + trigram + RRF
โโโ notion.py โ Tier 5: httpx Notion API client (lazy import)
โก Performance
- Lazy imports โ numpy and httpx are imported only when their layer is first used, not at module load time
import elingtakes ~1.3s (was ~4.5s with module-level imports on Alpine)- Pure-Python fallback when numpy unavailable (BM25-only retrieval still works)
๐ Documentation
๐ค Credits
- HRR phase encoding + facts layer โ adapted from holographic plugin by dusterbloom (Hermes PR #2351, MIT)
๐ License
MIT ยฉ 2026 PatrickNoFilter
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eling-0.2.3.tar.gz.
File metadata
- Download URL: eling-0.2.3.tar.gz
- Upload date:
- Size: 98.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fdcae566be29ed0b4eb4c07682bf96461a7e746fc558a6ee6758607c8b7cc009
|
|
| MD5 |
cfabc351d85b8e30249a292c9f955217
|
|
| BLAKE2b-256 |
a13c1974cf64010c5b1139b32fef47f34b4f89a9f395df18a2f2b4c1ccc7217d
|
File details
Details for the file eling-0.2.3-py3-none-any.whl.
File metadata
- Download URL: eling-0.2.3-py3-none-any.whl
- Upload date:
- Size: 76.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1156ef9110fa6eff4d3979c7ee82607c7214201a0c4610c4b0c2ade974e164e
|
|
| MD5 |
d3291734f1438e2f2ac7f275de2cdec9
|
|
| BLAKE2b-256 |
432c551b0dac6ee7af4a69add5b45a9b2bb71156c554beb25a2fac1b15106a74
|