Skip to main content
Glama
README.md
# cory-mem

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://github.com/anthropics/mcp)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.109+-009688.svg)](https://fastapi.tiangolo.com/)

A comprehensive memory system for Claude-based AI projects enabling learning, self-organization, and persistent context across sessions.

## Overview

cory-mem provides a personal memory layer for AI assistants, allowing them to remember context, learn from interactions, and maintain persistent knowledge across sessions. It combines short-term session memory with long-term semantic storage, enabling natural context retrieval through hybrid search.

## Features

- **Short-term (Session) Memory**: Captures conversation context with automatic promotion to long-term storage
- **Long-term (Persistent) Memory**: Durable storage with version history and conflict detection
- **Semantic Search with FAISS + Keyword Search**: Hybrid retrieval combining vector similarity and TF-IDF
- **Pluggable Embedding Providers**: Support for local (sentence-transformers), OpenAI, Claude, and Ollama
- **MCP Server Integration**: Native support for Claude Code and MCP-compatible clients
- **REST API with FastAPI**: Full CRUD operations, search endpoints, and analytics
- **Conflict Detection & Resolution**: Automatic detection of duplicates, contradictions, and merge candidates
- **Version History & Backup**: Complete audit trail with point-in-time restoration
- **Automated Maintenance Scheduling**: Background jobs for sync, pruning, and index optimization

## Architecture

```
+----------------------------------------------------------+
|                    Client Layer                          |
+----------------------------------------------------------+
|  Native Python  |   MCP Server    |     REST API         |
|    Library      |  (Claude Code)  |    (FastAPI)         |
+-----------------+-----------------+----------------------+
                           |
+----------------------------------------------------------+
|                   Core Services                          |
+----------------------------------------------------------+
|  Memory Manager | Search Engine | Scheduler | Conflict   |
|                 | (Hybrid)      |           | Resolver   |
+-----------------+---------------+-----------+------------+
                           |
+----------------------------------------------------------+
|                   Storage Layer                          |
+----------------------------------------------------------+
|  JSON Storage   |  FAISS Index  |  Version History       |
|  (Long-term)    |  (Vectors)    |  (Audit Trail)         |
+-----------------+---------------+------------------------+
```

### Component Diagram

```mermaid
graph TB
    subgraph "Client Interfaces"
        A[Python Library]
        B[MCP Server]
        C[REST API]
    end

    subgraph "Core Services"
        D[Memory Manager]
        E[Search Engine]
        F[Scheduler]
        G[Conflict Resolver]
        H[Lifecycle Tracker]
    end

    subgraph "Embedding Providers"
        I[Local<br/>sentence-transformers]
        J[OpenAI]
        K[Claude]
        L[Ollama]
    end

    subgraph "Storage"
        M[(JSON Files)]
        N[(FAISS Index)]
        O[(Version History)]
    end

    A --> D
    B --> D
    C --> D

    D --> E
    D --> F
    D --> G
    D --> H

    E --> I
    E --> J
    E --> K
    E --> L

    E --> N
    D --> M
    D --> O
```

## Installation

### Using uv (Recommended)

```bash
# Clone the repository
git clone https://github.com/yourusername/cory-mem.git
cd cory-mem

# Install with uv
uv pip install -e .

# Install with development dependencies
uv pip install -e ".[dev]"
```

### Using pip

```bash
pip install -e .
```

### Dependencies

Core dependencies:
- `pydantic>=2.0` - Data validation
- `fastapi>=0.109` - REST API
- `faiss-cpu` - Vector similarity search
- `sentence-transformers` - Local embeddings
- `mcp` - Model Context Protocol
- `apscheduler>=3.10` - Background scheduling

## Quick Start

### Using MCP Server with Claude Code

Add to your Claude Code MCP settings (`~/.claude/mcp.json`):

```json
{
  "mcpServers": {
    "cory-mem": {
      "command": "python",
      "args": ["-m", "cory_mem.mcp"],
      "env": {
        "CORY_MEM_EMBEDDING_PROVIDER": "local"
      }
    }
  }
}
```

Then in Claude Code, you can use memory tools:

```
# Store a memory
Use memory_inject to save: "User prefers Python for backend development"

# Retrieve relevant context
Use memory_retrieve with query: "What programming languages does the user prefer?"
```

### Using REST API

Start the API server:

```bash
python -m cory_mem.api.main
```

Or with uvicorn:

```bash
uvicorn cory_mem.api.main:app --host 127.0.0.1 --port 8420
```

API endpoints:

```bash
# Create a memory
curl -X POST http://localhost:8420/api/v1/memories \
  -H "Content-Type: application/json" \
  -d '{
    "content": "User works at Anthropic as an engineer",
    "memory_type": "personal",
    "tags": ["employment", "career"]
  }'

# Search memories
curl -X POST http://localhost:8420/api/v1/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "where does the user work?",
    "limit": 5
  }'

# Health check
curl http://localhost:8420/health
```

### Using Python Library Directly

```python
from cory_mem.core.memory_manager import MemoryManager, MemoryContext
from cory_mem.models.base import MemoryType
from cory_mem.config import get_config

# Initialize
config = get_config()
manager = MemoryManager(config)

# Start a session
session = manager.start_session()

# Add to short-term memory
manager.add_to_session(
    session.session_id,
    content="User asked about Python async patterns",
    category="interaction"
)

# Inject to long-term memory
memory = manager.inject(
    content="User is an experienced Python developer specializing in async programming",
    memory_type=MemoryType.PERSONAL,
    context=MemoryContext(
        source="conversation",
        tags=["python", "skills", "async"],
        confidence=0.9
    )
)

# Search memories
results = manager.search(
    query="What are the user's programming skills?",
    memory_types=[MemoryType.PERSONAL, MemoryType.KNOWLEDGE],
    limit=10
)

# Get context for conversation
context = manager.get_context_for_conversation(
    query="Help me with async Python",
    session_id=session.session_id,
    max_memories=10
)
print(context.to_text())

# Sync session to long-term storage
sync_result = manager.sync_session_to_long_term(session.session_id)

# Get statistics
stats = manager.get_stats()
```

## Memory Types

### Personal Memories

Stores information about the user: preferences, relationships, employment history.

```python
from cory_mem.models.personal import PersonalMemory, PersonalCategory

memory = PersonalMemory(
    content="User prefers dark mode and vim keybindings",
    category=PersonalCategory.PREFERENCE,
)
```

Categories:
- `PREFERENCE` - User preferences and settings
- `EMPLOYMENT` - Work history and job information
- `RELATIONSHIP` - Family, friends, colleagues
- `BACKGROUND` - Education, hometown, biography
- `GENERAL` - Other personal information

### Knowledge Base

Facts, skills, and domain-specific knowledge.

```python
from cory_mem.models.knowledge import KnowledgeMemory, KnowledgeDomain

memory = KnowledgeMemory(
    content="FAISS uses product quantization for efficient similarity search",
    domain=KnowledgeDomain.TECHNOLOGY,
    knowledge_type="fact"
)
```

Domains:
- `TECHNOLOGY`, `SCIENCE`, `BUSINESS`, `ARTS`, `HEALTH`, `EDUCATION`, `GENERAL`

### Interactions

Conversation summaries and interaction patterns.

```python
from cory_mem.models.interaction import InteractionMemory, InteractionOutcome

memory = InteractionMemory(
    content="Helped user debug a race condition in their async code",
    outcome=InteractionOutcome.SUCCESSFUL,
    sentiment="positive"
)
```

### Projects

Goals, milestones, and progress tracking.

```python
from cory_mem.models.project import ProjectMemory, ProjectStatus, Milestone

memory = ProjectMemory(
    content="Build a personal memory system for AI",
    status=ProjectStatus.IN_PROGRESS,
    milestones=[
        Milestone(name="Design architecture", status="completed"),
        Milestone(name="Implement storage layer", status="completed"),
        Milestone(name="Add MCP integration", status="in_progress"),
    ]
)
```

## Configuration

Configuration via environment variables (prefix: `CORY_MEM_`):

| Variable | Default | Description |
|----------|---------|-------------|
| `CORY_MEM_MEMORY_BASE_PATH` | `~/.cory-mem/memory` | Base directory for storage |
| `CORY_MEM_EMBEDDING_PROVIDER` | `local` | Embedding provider: `local`, `openai`, `claude`, `ollama` |
| `CORY_MEM_EMBEDDING_MODEL` | `all-MiniLM-L6-v2` | Model name for embeddings |
| `CORY_MEM_EMBEDDING_DIMENSION` | `384` | Vector dimension size |
| `CORY_MEM_OPENAI_API_KEY` | - | OpenAI API key (if using OpenAI provider) |
| `CORY_MEM_ANTHROPIC_API_KEY` | - | Anthropic API key (if using Claude provider) |
| `CORY_MEM_OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama server URL |
| `CORY_MEM_SESSION_TTL_HOURS` | `24` | Session expiration time |
| `CORY_MEM_MAX_SESSION_ENTRIES` | `1000` | Max entries per session |
| `CORY_MEM_SEARCH_DEFAULT_LIMIT` | `10` | Default search result count |
| `CORY_MEM_SEARCH_SIMILARITY_THRESHOLD` | `0.5` | Minimum similarity score |
| `CORY_MEM_SYNC_INTERVAL_MINUTES` | `60` | Sync job interval |
| `CORY_MEM_PRUNE_INTERVAL_HOURS` | `24` | Prune job interval |
| `CORY_MEM_MAINTENANCE_DAY` | `sunday` | Weekly maintenance day |
| `CORY_MEM_API_HOST` | `127.0.0.1` | API server host |
| `CORY_MEM_API_PORT` | `8420` | API server port |

Or use a `.env` file:

```env
CORY_MEM_EMBEDDING_PROVIDER=openai
CORY_MEM_OPENAI_API_KEY=sk-...
CORY_MEM_API_PORT=9000
```

## API Reference

### Memories API (`/api/v1/memories`)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/memories` | Create a new memory |
| `GET` | `/memories/{id}` | Get memory by ID |
| `PUT` | `/memories/{id}` | Update a memory |
| `DELETE` | `/memories/{id}` | Delete a memory |
| `GET` | `/memories` | List memories with filtering |

### Search API (`/api/v1/search`)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/search` | Hybrid search (semantic + keyword) |
| `POST` | `/search/semantic` | Semantic-only search |
| `POST` | `/search/keyword` | Keyword-only search |
| `POST` | `/search/tags` | Search by tags |

### Scheduler API (`/api/v1/scheduler`)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/scheduler/jobs` | List scheduled jobs |
| `POST` | `/scheduler/jobs/{type}/run` | Trigger job manually |
| `GET` | `/scheduler/history` | Get job execution history |

### Versioning API (`/api/v1/versioning`)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/versioning/{id}/history` | Get version history |
| `POST` | `/versioning/{id}/restore/{version}` | Restore to version |
| `POST` | `/versioning/backup` | Create backup |

### Analytics API (`/api/v1/analytics`)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/analytics/stats` | Get memory statistics |
| `GET` | `/analytics/lifecycle` | Get lifecycle metrics |

Interactive documentation available at `/docs` (Swagger UI) and `/redoc`.

## MCP Tools

Available tools when using the MCP server:

| Tool | Description |
|------|-------------|
| `memory_inject` | Add new information to long-term memory |
| `memory_retrieve` | Get relevant context for a query |
| `memory_update` | Modify an existing memory |
| `memory_search` | Search with full options (semantic + keyword) |
| `memory_delete` | Remove a memory (soft or hard delete) |

### MCP Resources

| Resource URI | Description |
|--------------|-------------|
| `memory://stats` | Memory system statistics |
| `memory://recent` | Recently accessed memories |
| `memory://type/{type}` | Memories by type |

### MCP Prompts

| Prompt | Description |
|--------|-------------|
| `memory-context` | Get relevant memory context for a topic |
| `memory-summary` | Get a summary of stored memories |

## Internal Operations

### Memory Lifecycle

```mermaid
sequenceDiagram
    participant C as Client
    participant M as MemoryManager
    participant S as SearchEngine
    participant ST as Storage
    participant I as FAISS Index

    C->>M: inject(content, type)
    M->>M: Validate & create Memory
    M->>ST: Store JSON
    M->>S: Generate embedding
    S->>I: Add to index
    M-->>C: Return memory

    C->>M: search(query)
    M->>S: hybrid_search(query)
    S->>S: Generate query embedding
    S->>I: Vector similarity search
    S->>S: Keyword TF-IDF search
    S->>S: Merge & rank results
    S-->>M: Return results
    M-->>C: Return memories
```

### Conflict Resolution Flow

```mermaid
flowchart TD
    A[New Memory] --> B{Compute Similarity}
    B --> C{Similarity >= 0.95?}
    C -->|Yes| D[DUPLICATE]
    C -->|No| E{Similarity >= 0.85?}
    E -->|Yes| F{Same Category?}
    F -->|Yes| G[CONTRADICTION]
    F -->|No| H{Time Diff > 24h?}
    H -->|Yes| I[OUTDATED]
    H -->|No| J{Similarity >= 0.75?}
    E -->|No| J
    J -->|Yes| K[MERGE_CANDIDATE]
    J -->|No| L[No Conflict]

    D --> M{Confidence >= 0.8?}
    I --> M
    G --> N[Manual Review]
    K --> O{Confidence >= 0.9?}

    M -->|Yes| P[Auto: Keep Newer]
    M -->|No| N
    O -->|Yes| Q[Auto: Merge]
    O -->|No| N
```

### Scheduler Job Flow

```mermaid
sequenceDiagram
    participant S as Scheduler
    participant J as JobRunner
    participant M as MemoryManager
    participant H as JobHistory

    S->>S: Check job schedule
    S->>J: Execute job

    alt SYNC_SHORT_TO_LONG
        J->>M: sync_session_to_long_term()
        M-->>J: SyncResult
    else PRUNE_EXPIRED
        J->>M: cleanup()
        M-->>J: Cleanup stats
    else MAINTENANCE
        J->>M: Merge duplicates
        J->>M: Optimize indexes
    else BACKUP
        J->>M: Create backup
    end

    J->>H: Record result
    H-->>S: Job complete
```

## Development

### Running Tests

```bash
# Run all tests with coverage
pytest

# Run specific test categories
pytest tests/unit/
pytest tests/integration/
pytest tests/e2e/

# Run with verbose output
pytest -v --cov=src/cory_mem --cov-report=term-missing
```

### Code Quality

```bash
# Lint with ruff
ruff check src/ tests/

# Format with ruff
ruff format src/ tests/

# Type checking with mypy
mypy src/cory_mem/
```

### Project Structure

```
cory-mem/
├── src/cory_mem/
│   ├── api/              # FastAPI REST endpoints
│   │   ├── routers/      # Route handlers
│   │   └── schemas/      # Pydantic request/response models
│   ├── core/             # Core business logic
│   │   ├── memory_manager.py
│   │   ├── short_term.py
│   │   ├── long_term.py
│   │   ├── conflict_resolver.py
│   │   └── lifecycle_tracker.py
│   ├── embeddings/       # Embedding providers
│   │   ├── base.py
│   │   ├── local.py
│   │   ├── openai.py
│   │   └── claude.py
│   ├── mcp/              # MCP server integration
│   │   ├── server.py
│   │   ├── tools.py
│   │   └── resources.py
│   ├── models/           # Data models
│   │   ├── base.py
│   │   ├── personal.py
│   │   ├── knowledge.py
│   │   ├── interaction.py
│   │   └── project.py
│   ├── scheduler/        # Background job scheduling
│   │   ├── jobs.py
│   │   └── runner.py
│   ├── search/           # Hybrid search engine
│   │   ├── engine.py
│   │   └── keyword.py
│   ├── storage/          # Persistence layer
│   │   ├── json_storage.py
│   │   └── faiss_index.py
│   ├── versioning/       # Version control & backup
│   │   ├── history.py
│   │   ├── diff.py
│   │   └── backup.py
│   └── config.py         # Configuration management
├── tests/
│   ├── unit/
│   ├── integration/
│   └── e2e/
├── scripts/
│   └── hooks/            # Claude Code hooks
├── pyproject.toml
└── README.md
```

## License

MIT License - see [LICENSE](LICENSE) for details.

---

Built for seamless integration with Claude and the Model Context Protocol ecosystem.