# MCAL: Memory-Context Alignment Layer

> **Intent-Preserving Memory for Goal-Coherent AI Agents**

[![PyPI](https://img.shields.io/pypi/v/mcal-ai.svg)](https://pypi.org/project/mcal-ai/)
[![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)

## Why MCAL?

Current AI memory systems store **facts** but lose **meaning**:

| What's Stored | What's Lost |
|---------------|-------------|
| "User chose PostgreSQL" | **WHY** they chose it over MongoDB |
| "User wants to visit Japan" | **HOW** this fits their overall travel goals |

MCAL preserves the **reasoning behind decisions**, not just the conclusions.

## Installation

```bash
pip install mcal-ai
```

**Framework integrations:**
```bash
pip install mcal-ai-langgraph  # LangGraph integration
pip install mcal-ai-crewai     # CrewAI integration  
pip install mcal-ai-autogen    # AutoGen integration
```

## Quick Start

```python
import asyncio
from mcal import MCAL

async def main():
    mcal = MCAL(llm_provider="anthropic")  # or "openai", "bedrock"
    
    messages = [
        {"role": "user", "content": "I'm building a fraud detection pipeline"},
        {"role": "assistant", "content": "Let's start with data ingestion..."},
        {"role": "user", "content": "I chose PostgreSQL over MongoDB for storage"},
    ]
    
    # Extract goals, decisions, and reasoning
    result = await mcal.add(messages, user_id="user_123")
    print(f"Extracted {result.unified_graph.node_count} nodes")
    
    # Search with goal-aware retrieval
    results = await mcal.search("What database?", user_id="user_123")
    
    # Get context for LLM prompts
    context = await mcal.get_context("What's next?", user_id="user_123")

asyncio.run(main())
```

## Key Features

- **Intent Graph** — Hierarchical goal structures (Mission → Goal → Task)
- **Reasoning Chains** — Store WHY decisions were made, not just conclusions
- **Goal-Aware Retrieval** — Retrieve based on objective alignment, not just similarity
- **Multi-Provider** — Works with Anthropic, OpenAI, and AWS Bedrock
- **Standalone Storage** — Built-in JSON file persistence, no external memory service required
- **Thread-Safe** — Safe for concurrent multi-user access
- **Tiered Models** — Optional fast/smart model routing (Bedrock)

## Configuration

```python
mcal = MCAL(
    llm_provider="anthropic",         # "openai", "anthropic", or "bedrock"
    anthropic_api_key="sk-ant-...",    # Or set ANTHROPIC_API_KEY env var
    openai_api_key="sk-...",           # Or set OPENAI_API_KEY env var
    storage_path="~/.mcal",            # Persistent storage location
    enable_persistence=True,           # Cross-session persistence (default)
    max_graph_nodes=500,               # Max nodes per user graph
    # Bedrock options
    bedrock_model="llama-3.3-70b",
    bedrock_region="us-east-1",
    enable_tiered_models=False,        # Fast/smart model routing
)
```

## Environment Variables

```bash
# Choose your LLM provider
ANTHROPIC_API_KEY=sk-ant-...    # For Claude
OPENAI_API_KEY=sk-...           # For GPT-4 / embeddings

# Optional: AWS Bedrock
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=us-east-1
```

MCAL auto-detects API keys from environment variables when not passed explicitly.

## Documentation

- [GitHub Repository](https://github.com/Shivakoreddi/mcal-ai)
- [Design Document](https://github.com/Shivakoreddi/mcal-ai/blob/main/docs/MCAL_DESIGN.md)
- [LLM Selection Guide](https://github.com/Shivakoreddi/mcal-ai/blob/main/docs/LLM_SELECTION_GUIDE.md)

## License

MIT License — see [LICENSE](https://github.com/Shivakoreddi/mcal-ai/blob/main/LICENSE) for details.

## Author

Created by [Shiva Koreddi](https://github.com/Shivakoreddi)
