Persistent long-term memory for the Hermes AI agent ecosystem — turns Notion into a structured brain that never forgets.
[!TIP]
v1.0.0 released — 7 databases, heuristic auto-capture, 5 tool interfaces, secret redaction, background sync.
Follow @MNDL-27 on GitHub for more AI infrastructure tools. Join our GitHub Discussions for support and ideas.
Get your first memory into Notion in under 5 minutes. One command after install.
git clone https://github.com/MNDL-27/hermes-brain.git
cd hermes-brain
sudo pip install -e . --break-system-packagesexport NOTION_API_KEY=ntn_xxxxx_xxxxx
export HERMES_HOME=~/.hermesGet NOTION_API_KEY from My Integrations → New integration.
python examples/quickstart.pyThat's it. The script bootstraps the 7 databases, stores a sample memory, and searches for it. Open your Notion workspace — you'll see a "Hermes Brain" page with everything populated.
Want to see each step? — Detailed walkthrough below breaks it down.
Troubleshooting? — Common Pitfalls covers the 5 most frequent setup failures.
If you prefer to see each step individually:
python3 -c "import notion_brain; print(notion_brain.__file__)"Expected: prints the path to notion_brain/__init__.py.
hermes-brain url
# or equivalently: python -m notion_brain urlExpected: prints a notion.so/... URL. Open it — you should see an empty "Hermes Brain" page. If you don't, share the page with your integration.
from notion_brain import bootstrap
cache = bootstrap.ensure_brain("~/.hermes")
print(list(cache.keys()))Expected: ['parent_page_id', 'db_memory', 'db_tasks', 'db_projects', 'db_content', 'db_research', 'db_career', 'db_entities'].
Open the Notion page again — 7 databases now appear under it.
from notion_brain import remember, search
url = remember("Design review notes", "Team agreed on Material Design 3",
domain="projects", kind="decision", tags=["design"])
print("Saved:", url)
results = search("Material Design")
print(len(results), "result(s)")
for r in results:
print("-", r["title"])Expected: Saved: https://notion.so/... then 1 result(s) then - Design review notes.
| Symptom | Fix |
|---|---|
unauthorized from Notion |
Share the parent page with your integration |
pip install fails with PEP 668 |
Use sudo pip install -e . --break-system-packages |
ModuleNotFoundError: agent |
Install and run the Hermes agent host first |
| Bootstrap ok, no databases appear | Check integration capabilities |
| Search returns nothing | Wait 5s for Notion indexing, then retry |
Full troubleshooting guide: docs/troubleshooting.md.
hermes-brain gives the Hermes AI agent a persistent, structured memory by writing conversation highlights into a Notion workspace. Instead of an agent forgetting everything at the end of a session, it remembers:
| Database | Purpose | Example |
|---|---|---|
| Memory | General notes, lessons, decisions | "We decided to use PostgreSQL" |
| Tasks | To-dos, reminders, deadlines | "Ship auth refactor by Friday" |
| Projects | Project context, milestones, roadmap | "MVP launching October 2026" |
| Content | Social media drafts, content ideas | "Draft Twitter thread on agent memory" |
| Research | Sources, citations, analysis | "BERT outperforms RoBERTa on XNLI" |
| Career | Job search, interviews, salary talks | "Target: $180k base + equity" |
| Entities | People, companies, tools, preferences | "Sarah prefers async communication" |
Two ways to save:
- Automatic — heuristic classifier detects tasks, decisions, research, content ideas, preferences from conversation
- Manual — explicit "Remember this: ..." via tool calls
Two ways to recall:
- Prefetch — before each turn, relevant memories load into agent context
- Search — "What did we decide about the database?"
- 7 Structured Databases — Memory, Tasks, Projects, Content, Research, Career, Entities, each with domain-specific properties
- Heuristic Auto-Capture — Zero-LLM-cost extraction using keyword patterns (tasks, decisions, research, content, career, preferences)
- 5 Tool Interfaces —
search,remember,task,content,researchexposed to the agent - Background Sync — Non-blocking daemon thread writes to Notion; conversation never pauses
- Secret Redaction — Stripe, Notion, GitHub, Slack tokens auto-redacted before storage
- Prefetch Context — Smart recall loads relevant memories before each conversation turn
- Session Summaries — Automatic end-of-session summaries saved to Memory database
- Disk Import — Migrate existing
MEMORY.mdandUSER.mdinto Notion - Idempotent Bootstrap — Creates "Hermes Brain" page + 7 databases on first run
- Cross-Platform — Runs on Linux (Ubuntu, Debian, Fedora, RHEL families)
The Notion backend in this repository is the only backend today, and it is free to use. There is no paid package, no companion repo, and no upgrade tier.
If you want storage in Obsidian, SQLite, Logseq, or a local Markdown vault:
- Build one yourself — see
BACKEND_SWAP_GUIDE.md. - Sponsor the work — sponsor button above. Sponsorships fund additional backends, not a paid product.
See BACKENDS.md for the long-term plan.
Linux only. hermes-brain is tested on Ubuntu, Debian, Fedora, and RHEL families. macOS and Windows are not supported.
Designed for a dedicated agent host. Most users run this kind of AI-agent stack on a separate machine (or VM) with its own Python install. The instructions below assume that setup — no virtualenv, no per-user isolation beyond the host itself.
- Python 3.11–3.13
- Notion workspace with an internal integration
- Hermes agent framework (this is a plugin, not a standalone app)
One-line install (recommended):
curl -fsSL https://raw.githubusercontent.com/MNDL-27/hermes-brain/main/scripts/install.sh | bashThis script detects your distro, installs Python 3.11+ if missing, clones the repo, installs the package, prompts for your Notion API key, bootstraps the workspace, and verifies everything.
Manual install:
git clone https://github.com/MNDL-27/hermes-brain.git
cd hermes-brain
sudo pip install -e . --break-system-packages--break-system-packages is the standard PEP 668 override on externally-managed Python (Ubuntu 23.04+, Debian 12+, Fedora). On older systems or distros without PEP 668, plain sudo pip install -e . works.
If python3 --version shows something older than 3.11:
# Ubuntu / Debian
sudo apt update
sudo apt install python3.11 python3-pip
# Fedora
sudo dnf install python3.11
# RHEL / Rocky / Alma (via EPEL)
sudo dnf install epel-release
sudo dnf install python3.11Then verify:
python3.11 --version # should report 3.11.x or newerpython3 -c "import notion_brain; print(notion_brain.__file__)"This should print the path to the cloned repo's notion_brain/__init__.py — confirming the editable install is wired up to your source tree.
- Go to My Integrations → New integration
- Name it (e.g., "Hermes Brain")
- Enable capabilities: Search, Read content, Update content, Insert content
- Copy the Internal Integration Token (starts with
ntn_)
export NOTION_API_KEY=ntn_xxxxx_xxxxx
export HERMES_HOME=~/.hermes| Variable | Required | Description |
|---|---|---|
NOTION_API_KEY |
✅ | Your Notion internal integration token |
HERMES_HOME |
✅ | Directory for cache files (notion_brain.json) |
HERMES_NOTION_PARENT_PAGE |
Optional | Existing Notion page ID to use as parent (if no pages exist in workspace) |
On first run, the plugin creates a "Hermes Brain" parent page and 7 databases under it:
from notion_brain import bootstrap
cache = bootstrap.ensure_brain("~/.hermes")
print(cache["parent_page_id"]) # Notion page IDOr from the CLI (hermes-brain after install, python -m notion_brain from a checkout):
hermes-brain health # prints health report, auto-repairs schema mismatches
hermes-brain url # prints the Notion URL of the Hermes Brain page
hermes-brain reset # archive and recreate mismatched databasesThe plugin registers 5 tools with the Hermes agent:
More patterns: examples/README.md — runnable quickstart.py and migrate_memory.py.
# Search across all 7 databases
notion_brain_search(query="database migration plan")
# Search specific database
notion_brain_search(query="Sarah", database="entities", max_results=5)| Parameter | Type | Default | Description |
|---|---|---|---|
query |
string | required | Search query |
database |
string | "all" |
Filter: memory, tasks, projects, content, research, career, entities |
max_results |
integer | 8 |
Max results (1-20) |
notion_brain_remember(
title="Design review notes",
content="Team agreed on Material Design 3 for the new dashboard",
domain="projects",
kind="decision",
status="active",
tags=["design", "dashboard"],
entities=["Sarah", "Design Team"]
)| Parameter | Type | Description |
|---|---|---|
title |
string | Short title (max 120 chars) |
content |
string | Full content/description |
domain |
string | daily_work, projects, social_content, research, career, entities |
kind |
string | note, task, decision, preference, source_note, draft, lesson, reminder |
status |
string | active, done, needs_review |
tags |
array | Tags for filtering |
entities |
array | People/companies/projects mentioned |
# Create task
notion_brain_task(
action="create",
title="Fix auth bug",
priority="urgent",
due="2026-08-01",
project="Auth Refactor",
tags=["backend", "security"]
)
# List tasks
notion_brain_task(action="list", status="active")
# Complete task
notion_brain_task(action="complete", page_id="<notion_page_id>")
# Update task
notion_brain_task(action="update", page_id="<id>", status="needs_review", priority="high")# Create draft
notion_brain_content(
action="create",
title="Thread on AI Memory",
body="Thread draft text...",
platform="twitter",
tags=["AI", "memory"]
)
# List content
notion_brain_content(action="list")
# Publish
notion_brain_content(action="publish", page_id="<id>")
# Archive
notion_brain_content(action="archive", page_id="<id>")Platforms: twitter, linkedin, instagram, tiktok, facebook, youtube, bluesky
# Save research
notion_brain_research(
action="save",
title="LLM Benchmarks 2026",
content="Summary of findings...",
tags=["LLM", "benchmarks"]
)
# List research
notion_brain_research(action="list")The plugin watches every conversation turn in a background thread. It detects these patterns automatically:
| Pattern | Database | Trigger Keywords |
|---|---|---|
| Tasks | Tasks | remind me, todo, deadline, due, blocker, gotta, need to, will create, must fix |
| Decisions | Projects | decided, going with, moving forward, approved, greenlit, chosen, elect, cancelled, pivot |
| Research | Research | source, according to, findings, researched, cited, conclusion, analysis shows |
| Content | Content | draft, thread, tweet, publish, launch, campaign, hook, headline |
| Career | Career | interview, resume, salary, promotion, job, offer, negotiate, remote |
| Preferences | Entities | I prefer, I like, I hate, always, never, preferred, favorite, habit, routine |
Note: Classification is heuristic (regex-based), not semantic. It catches ~70% of actionable items. Missed entries are silent failures — use
notion_brain_rememberfor anything critical.
Every memory entry in Notion has these common properties:
| Property | Type | Description |
|---|---|---|
| Title | Title | Extracted from triggering sentence (max 120 chars) |
| Domain | Select | Daily Work, Projects, Social Content, Research, Career, Entities, Memory |
| Status | Status | active, done, needs_review |
| Tags | Multi-select | Keyword tags (up to 8, deduplicated) |
| Confidence | Select | high, medium, low |
| Kind | Select | note, task, decision, preference, source_note, draft, lesson, reminder |
| Source Session | Rich text | Hermes session ID |
| Last Seen | Date | When entry was last updated |
| Database | Extra Properties |
|---|---|
| Tasks | Priority (urgent, high, medium, low), Due (Date), Project (Rich text) |
| Content | Platform (Select) |
| Entities | Kind (Select: person, company, tool, project, topic, preference) |
| Memory | Kind (Select: note, preference, lesson, decision, reminder) |
Before any content is written to Notion, these patterns are automatically redacted:
| Pattern | Example | Replacement |
|---|---|---|
| Stripe keys | sk_live_xxxxx |
[REDACTED_SECRET] |
| Notion tokens | ntn_xxxxx |
[REDACTED_SECRET] |
| GitHub tokens | ghp_xxxxx, gho_xxxxx, ghu_xxxxx, ghs_xxxxx, ghr_xxxxx |
[REDACTED_SECRET] |
| Slack tokens | xoxb-xxxxx, xoxp-xxxxx, xoxr-xxxxx, xoxa-xxxxx, xoxs-xxxxx |
[REDACTED_SECRET] |
| Generic | api_key=..., secret=..., token=..., password=... |
[REDACTED_SECRET] |
Conversation Turn
│
▼
sanitize_context() ──► Strip PII, truncate
│
▼
extract.classify_turn() ──► Regex matching → BrainEntry list
│
▼
BrainEntry.normalized() ──► Domain normalize, secret redact, title clean, tag dedupe
│
▼
store.create_database_page() ──► Notion API /pages
│
▼
Notion Workspace (7 databases)
Key Design Decisions:
| Decision | Rationale | Upgrade Path |
|---|---|---|
| Heuristic-only (no LLM) | Zero token cost, zero latency | Swap regex for embedding classifier when coverage < 70% |
| Background thread sync | Non-blocking for agent loop | Replace with proper task queue if failure rate > 5% |
Flat JSON cache (notion_brain.json) |
Simple, no migration needed | Add versioning for multi-workspace support |
| 1900-char chunking | Notion's 2000-char block limit | Auto-upgrade when Notion increases limit |
requests over httpx |
Already in Hermes deps | Migrate to httpx when async needed |
Settings are stored in $HERMES_HOME/notion_brain.json (auto-generated):
{
"parent_page_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_memory": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_tasks": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_projects": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_content": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_research": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_career": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"db_entities": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}The cache maps database display names to Notion IDs. It's safe to delete — bootstrap will recreate it.
| Database | Notion Property Schema |
|---|---|
| Memory | Title, Domain, Kind, Status, Tags, Confidence, Source Session, Last Seen |
| Tasks | Title, Domain, Status, Priority, Tags, Due, Project, Confidence, Source Session, Last Seen |
| Projects | Title, Domain, Status, Tags, Confidence, Source Session, Last Seen |
| Content | Title, Domain, Status, Platform, Tags, Confidence, Source Session, Last Seen |
| Research | Title, Domain, Status, Tags, Confidence, Source Session, Last Seen |
| Career | Title, Domain, Status, Tags, Confidence, Source Session, Last Seen |
| Entities | Title, Kind, Tags, Confidence, Source Session, Last Seen |
hermes-brain/
├── notion_brain/
│ ├── __init__.py # Plugin entry point, tool schemas, provider
│ ├── schema.py # BrainEntry dataclass, constants, normalization
│ ├── extract.py # Heuristic classifier
│ ├── store.py # Notion REST API client
│ ├── bootstrap.py # Workspace setup, database creation, health, reset
│ └── __main__.py # CLI: health, reset, url
├── tests/
│ ├── test_provider.py # Provider interface and tool dispatch tests
│ ├── test_extract.py # Classifier tests
│ └── test_bootstrap_schema.py # Schema consistency tests
├── pyproject.toml
├── README.md
├── LICENSE
└── .github/
├── assets/
│ └── hero.png
└── workflows/
└── ci.yml
Contributions are welcome!
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
pytest(when test suite exists) - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
- Follow existing code style (type hints, docstrings, stdlib-first)
- Add tests for new functionality
- Update documentation as needed
- Keep commits focused and atomic
- Notion API — the persistent storage backend
- Requests — HTTP client
- All contributors and users
MIT License © MNDL-27
If you find this project useful, please consider starring it ⭐ or following for more AI infrastructure tools.