Persistent, queryable memory for AI coding agents
Project description
Enyal
Persistent, queryable memory for AI coding agents.
Enyal gives AI agents like Claude Code durable context that survives session restarts. Every conversation becomes accumulated institutional knowledge—facts, preferences, decisions, and conventions that persist and grow.
Features
- Persistent Memory: Context survives restarts, crashes, and process termination
- Semantic Search: Find relevant context using natural language queries
- Hierarchical Scoping: Global → workspace → project → file context inheritance
- Fully Offline: Zero network calls during operation
- Cross-Platform: macOS (Intel + Apple Silicon) and Windows 10/11
- MCP Compatible: Works with any MCP client (Claude Desktop, Claude Code, etc.)
Installation
# Using uv (recommended)
uv add enyal
# Using pip
pip install enyal
Quick Start
As an MCP Server
Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"enyal": {
"command": "python",
"args": ["-m", "enyal.mcp"],
"env": {
"ENYAL_DB_PATH": "~/.enyal/context.db"
}
}
}
}
Available Tools
- enyal_remember: Store new context with metadata
- enyal_recall: Semantic search for relevant context
- enyal_forget: Remove or deprecate context
- enyal_stats: Usage and health metrics
As a Python Library
from enyal import ContextStore, ContextType, ScopeLevel
# Initialize store
store = ContextStore("~/.enyal/context.db")
# Remember something
entry_id = store.remember(
content="Always use pytest for testing in this project",
content_type=ContextType.CONVENTION,
scope_level=ScopeLevel.PROJECT,
scope_path="/Users/dev/myproject",
tags=["testing", "pytest"]
)
# Recall relevant context
results = store.recall(
query="how should I write tests?",
limit=5,
min_confidence=0.5
)
for result in results:
print(f"{result.score:.2f}: {result.entry.content}")
Architecture
Enyal uses a unified SQLite database with:
- Relational storage for metadata and attributes
- sqlite-vec for vector similarity search
- FTS5 for keyword search
- WAL mode for concurrent access
See docs/ARCHITECTURE.md for detailed design decisions.
Configuration
Environment variables:
| Variable | Default | Description |
|---|---|---|
ENYAL_DB_PATH |
~/.enyal/context.db |
Database file location |
ENYAL_PRELOAD_MODEL |
false |
Pre-load embedding model at startup |
ENYAL_LOG_LEVEL |
INFO |
Logging level |
Development
# Clone repository
git clone https://github.com/seancorkum/enyal.git
cd enyal
# Install with dev dependencies
uv sync --all-extras
# Run tests
uv run pytest
# Type checking
uv run mypy src/enyal
# Linting
uv run ruff check src/enyal
Performance
Benchmarked on Intel Mac with Python 3.12:
| Metric | Target (p95) | Measured (p95) | Status |
|---|---|---|---|
| Cold start (model load + first query) | <2000ms | ~1500ms | ✓ |
| Warm query latency | <50ms | ~34ms | ✓ |
| Write latency | <50ms | ~34ms | ✓ |
| Concurrent reads (4 threads) | <150ms | ~85ms | ✓ |
| Memory (100k entries estimated) | <500MB | ~35MB | ✓ |
Run benchmarks:
uv run python benchmarks/benchmark_performance.py
License
MIT
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 enyal-0.1.0.tar.gz.
File metadata
- Download URL: enyal-0.1.0.tar.gz
- Upload date:
- Size: 179.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a731874ddbc5c474000c99e4cd1588cf8214e317b652706addd1843657f0ebc1
|
|
| MD5 |
44d02c66901c489b91d34451b0a87138
|
|
| BLAKE2b-256 |
b3a82e2689c0999e14df79da5bd498eb854fadd7b39518d5c7bf5121ff7bcafa
|
Provenance
The following attestation bundles were made for enyal-0.1.0.tar.gz:
Publisher:
publish.yml on S-Corkum/enyal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
enyal-0.1.0.tar.gz -
Subject digest:
a731874ddbc5c474000c99e4cd1588cf8214e317b652706addd1843657f0ebc1 - Sigstore transparency entry: 748361330
- Sigstore integration time:
-
Permalink:
S-Corkum/enyal@6e764d75d9c5206a3bdeb142f764603871c26b04 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/S-Corkum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6e764d75d9c5206a3bdeb142f764603871c26b04 -
Trigger Event:
release
-
Statement type:
File details
Details for the file enyal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: enyal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12966931fdd565d1b9ed9f0cb7f937dfcd799e98c281e9c89a145b3d3cd23a66
|
|
| MD5 |
96dc5bb5646a5a4eb2b0665161a94101
|
|
| BLAKE2b-256 |
8142b874b5a3b3f4700021f9f341c16d7e77eeff57da11563ec8ddd7ce68bb08
|
Provenance
The following attestation bundles were made for enyal-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on S-Corkum/enyal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
enyal-0.1.0-py3-none-any.whl -
Subject digest:
12966931fdd565d1b9ed9f0cb7f937dfcd799e98c281e9c89a145b3d3cd23a66 - Sigstore transparency entry: 748361342
- Sigstore integration time:
-
Permalink:
S-Corkum/enyal@6e764d75d9c5206a3bdeb142f764603871c26b04 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/S-Corkum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6e764d75d9c5206a3bdeb142f764603871c26b04 -
Trigger Event:
release
-
Statement type: