Agentic memory layer for LLM agents — filesystem MCP server with PARA+LYT vault conventions
Project description
hafiz
Agentic memory layer for LLM agents. A filesystem MCP server that gives agents structured read/write access to an Obsidian-style vault — projects, daily notes, tasks, MOCs, resources, and decisions — instead of ad-hoc file edits.
Uses PARA+LYT folder layout by default. All folder names are configurable. Part of the Personal AI OS stack (Hafiz + Kothar + Anzar).
Install
pip install hafiz
# or
uv add hafiz
MCP registration
claude mcp add -s user hafiz -- uv run --directory ~/projects/hafiz python -m hafiz.server
Do not edit mcpServers blocks in settings.json directly. The claude mcp add command writes to the correct registry; hand-edited mcpServers blocks spawn the process but the tools never appear in the session.
Verify registration:
claude mcp list
Allow tools without per-call approval
Add a permission rule to ~/.claude/settings.json (or ~/.claude-work/settings.json if CLAUDE_CONFIG_DIR is set):
{
"permissions": {
"allow": ["mcp__hafiz__*"]
}
}
Quick start
Zero configuration required. By default hafiz looks for your vault at ~/Documents/Obsidian Vault.
Point it at your vault:
export VAULT_PATH="/path/to/your/vault"
uv run python -m hafiz.server
Tools fail gracefully when optional folders are absent — you don't need the full PARA structure on day one. 10_Projects/ and 70_Tasks/ cover most workflows.
Configuration
Create ~/.hafiz/config.yaml to override folder names. All keys are optional — omitted keys stay at their defaults.
# ~/.hafiz/config.yaml
projects_dir: 10_Projects # default
tasks_dir: 70_Tasks # default
daily_dir: 50_Daily # default
mocs_dir: 60_MOCs # default
resources_dir: 30_Resources # default
areas_dir: 20_Areas # default
archive_dir: 40_Archive # default
meta_dir: 99_Meta # default
Example for a non-PARA vault with flat folder names:
projects_dir: Projects
tasks_dir: Tasks
daily_dir: Journal
mocs_dir: Maps
resources_dir: Resources
areas_dir: Areas
archive_dir: Archive
meta_dir: .meta
For per-project overrides, set HAFIZ_CONFIG to an absolute path:
export HAFIZ_CONFIG=/path/to/project-specific-config.yaml
Resolution order (later wins): dataclass defaults → ~/.hafiz/config.yaml → HAFIZ_CONFIG.
VAULT_PATH is separate and not handled by config.yaml.
Tool reference
| Tool | Purpose |
|---|---|
get_project |
Read CONTEXT.md + DECISIONS.md + NOTES.md for a project |
get_project_section |
Read a single file or one section from a project triplet; cheaper than get_project |
list_projects |
List all project slugs under the projects directory |
create_project |
Scaffold project triplet (CONTEXT/DECISIONS/NOTES) + MOC + seed task |
archive_project |
Move project to archive, close open tasks, rewrite MOC links |
add_observation |
Append an atomic structured observation to a project's Observations section |
update_project |
Append or prepend content under a section heading in CONTEXT.md or NOTES.md |
update_daily_note |
Append or prepend to a section in today's daily note; creates note from skeleton if missing |
list_tasks |
List tasks with optional filter by project slug and/or status |
close_task |
Mark a task done and move its file to the done/ subfolder |
create_task |
Create a new task file with correct frontmatter |
update_task |
Mutate frontmatter fields on an open task |
update_task_notes |
Append or prepend content into a section of a task file's body |
log_decision |
Append a dated ADR entry to a project's DECISIONS.md |
get_moc |
Read a MOC file from the MOCs directory |
update_moc |
Append or prepend content under a section heading in a MOC file |
get_area |
Bundle all .md files directly under an area folder |
get_profile |
Read 20_Areas/Career/professional-profile.md |
run_studyctl |
Bridge to the studyctl CLI for CKA/CKS study sessions |
search_vault |
Ranked search across vault .md files with a token budget |
rebuild_index |
Rebuild the SQLite FTS5 and vector index from vault files |
get_resource |
Read a resource note from the resources directory |
list_resources |
List all resource notes under the resources directory |
update_resource |
Append or prepend content under a section heading in a resource note |
vault_lint |
Run structural and provenance health checks; returns a grouped markdown report |
get_context_for_goal |
Assemble a token-budgeted context bundle for Anzar session bootstrapping |
add_fact_triple |
Store a (subject, predicate, object) fact triple with optional metadata |
query_fact_triples |
Filter stored fact triples by subject, predicate, and/or object |
Architecture
Markdown files are canonical and Obsidian-compatible — open them in any editor at any time. SQLite (.hafiz-index.db at the vault root) is a materialised query layer rebuilt on demand: it holds an FTS5 full-text index, optional sqlite-vec vector embeddings (bge-large-en-v1.5, enabled when hafiz[vector] is installed), and a fact-triple store. MCP tools are the write API for agents — they go through atomic file writes and frontmatter parsing so concurrent agent sessions don't corrupt each other. There is no cloud dependency and no background daemon.
Development
git clone https://github.com/yahiaklk/hafiz
cd hafiz
uv sync --all-extras
uv run pytest
uv run ruff check src/ tests/
uv run python -m hafiz.server # starts the MCP server on stdio
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 hafiz-1.0.0.tar.gz.
File metadata
- Download URL: hafiz-1.0.0.tar.gz
- Upload date:
- Size: 60.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Pop!_OS","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9991b8c1c0aa6511ebfb593cb88a6c20c38f3896c9a38aeca828e45f7e361019
|
|
| MD5 |
19ab1f9abdebfad41da91ee9e638dee3
|
|
| BLAKE2b-256 |
8989965ccdb8e14a34a832f49b3316a158a381e2e2f4e571a934133b2cb30cb2
|
File details
Details for the file hafiz-1.0.0-py3-none-any.whl.
File metadata
- Download URL: hafiz-1.0.0-py3-none-any.whl
- Upload date:
- Size: 77.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Pop!_OS","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fea567cf549c94129e07b57d77c9c52cdd949c0370f76d7f1ca1f1458f0be09f
|
|
| MD5 |
63019f883141ec1b200e50f3ba787278
|
|
| BLAKE2b-256 |
9ab766650653f4244413d13edf8773f12abfae3f27ac7efa26beb77f17325c57
|