mcal-ai-langgraph
LangGraph integration for MCAL — Goal-aware memory for AI agents.
Installation
pip install mcal-ai-langgraph
This will automatically install mcal-ai and langgraph as dependencies.
Quick Start
from mcal import MCAL
from mcal_langgraph import MCALStore
# Initialize MCAL
mcal = MCAL(llm_provider="anthropic")
# Create LangGraph-compatible store
store = MCALStore(mcal)
# Use with LangGraph
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(
model=your_model,
tools=your_tools,
store=store # Goal-aware memory!
)
What's New in 0.5.0
- Query-Aware Subgraph Retrieval — New seed-and-expand pipeline replaces 6 query-blind retrieval paths with a single query-aware pass. Reduces context tokens by 53% at 1020 turns while improving DRR by 4.5pp.
QuerySubgraphdataclass — New public API for structured subgraph results, partitioned by node type (goals, decisions, facts, entities, actions) with structural edge resolution.- Adjacency index — Lazy-built bidirectional adjacency index on
UnifiedGraphenables O(1) neighbor lookups for graph traversal. - Improved DRR at scale — CTO-1020 DRR improved from 85.3% to 89.9% (+4.6pp); CTO-300 improved from 92.2% to 94.4% (+2.2pp).
- LoCoMo-10 Evaluation — Full 10-conversation, 1,540 QA binary evaluation: 46.1% overall accuracy.
What's New in 0.4.1
- First-Class FACT Nodes — 3 new typed edges (
measures,evidence_for,quantifies) improve fact retrieval; quantitative queries automatically boost fact content - Importance Scoring Boost — FACT nodes with numeric values score higher in retrieval
search_facts()API — Filter facts by category and value range onUnifiedGraph- Version Metadata Fix —
__version__now correctly reports 0.4.1 (was stuck at 0.2.9)
What's New in 0.4.0
- Graph Compaction Fixes — Improved retrieval quality with facts-in-context, expanded edge types, chunk boost scoring
- CTO-1020 Benchmark — 85.3% decision retention over 1020 turns, 95.6% cross-era recall, 88% token reduction
- Statistical Rigor — Multi-run validation with Fisher's exact test, Wilson score confidence intervals
What's New in 0.3.0
- Expanded Relationship Edge Types — 10 new edge types (
family,friend,colleague,likes,prefers,lives_in,works_at, etc.) for richer relationship graphs - Key Facts & Entities in Search Context —
search()now surfaces extracted facts and background entities directly inresult.context - Improved Chunk Retrieval — More results returned with equal weighting; conversation excerpts prioritized in context
Older releases
What's New in 0.2.9
- Configurable Extraction Profiles — Choose
decision,conversational, orcomprehensiveviaMCALMemoryConfig - Hybrid Retrieval with ChunkStore — Graph traversal + embedding search for maximum recall
- FACT/PERSON Node Protection — Graph compaction preserves factual and identity nodes
# Configuration options
memory = MCALMemory(
llm_provider="anthropic",
extraction_profile="decision", # "decision" | "conversational" | "comprehensive"
enable_chunk_store=True, # hybrid retrieval
)
Features
MCALStore (BaseStore)
Drop-in replacement for LangGraph's built-in stores with goal-aware memory:
from mcal_langgraph import MCALStore
store = MCALStore(mcal)
# Store memories
await store.aput(
namespace=("user_123", "memories"),
key="decision_1",
value={"text": "Decided to use PostgreSQL for ACID compliance"}
)
# Goal-aware search — returns memories relevant to current goals
results = await store.asearch(
namespace_prefix=("user_123",),
query="database choice"
)
# Results include goal context and decisions
for item in results:
print(item.value)
MCALMemory
Memory nodes for custom LangGraph workflows:
from mcal_langgraph import MCALMemory
# Initialize with provider (uses get_mcal() factory internally)
memory = MCALMemory(llm_provider="anthropic")
# Or pass an existing MCAL instance
memory = MCALMemory(mcal=mcal, user_id="user_123")
# Add as nodes in your graph
graph.add_node("update_memory", memory.update_node())
graph.add_node("get_context", memory.context_node())
MCALCheckpointer
State persistence for LangGraph graphs:
from mcal_langgraph import MCALCheckpointer
checkpointer = MCALCheckpointer(storage_path="~/.mcal")
graph = builder.compile(checkpointer=checkpointer)
Why mcal-ai-langgraph?
| Feature | LangGraph InMemoryStore | MCALStore |
|---|---|---|
| BaseStore interface | ✅ | ✅ |
| Namespace organization | ✅ | ✅ |
| TTL support | ❌ | ✅ |
| Filter operators ($eq, $gt, etc.) | ❌ | ✅ |
| Goal-aware search | ❌ | ✅ |
| Decision tracking | ❌ | ✅ |
| Intent preservation | ❌ | ✅ |
API Reference
MCALStore
class MCALStore(BaseStore):
def __init__(self, mcal: MCAL): ...
# Async API
async def aput(self, namespace, key, value, index=None): ...
async def aget(self, namespace, key) -> Optional[Item]: ...
async def adelete(self, namespace, key): ...
async def asearch(self, namespace_prefix, /, *, query=None, filter=None, limit=10, offset=0) -> list[Item]: ...
async def alist_namespaces(self, *, prefix=None, suffix=None, max_depth=None, limit=100, offset=0) -> list[tuple[str, ...]]: ...
# Sync API (also available)
def put(self, namespace, key, value, index=None): ...
def get(self, namespace, key) -> Optional[Item]: ...
def delete(self, namespace, key): ...
def search(self, namespace_prefix, /, *, query=None, filter=None, limit=10, offset=0) -> list[Item]: ...
MCALMemory
class MCALMemory:
def __init__(
self,
mcal: Optional[MCAL] = None,
llm_provider: str = "anthropic",
embedding_provider: str = "openai",
storage_path: Optional[str] = None,
user_id: str = "default",
**mcal_kwargs,
): ...
def update_node(self) -> Callable: ...
def context_node(self) -> Callable: ...
async def add(self, messages, user_id=None): ...
async def get_context(self, query, user_id=None): ...
async def search(self, query, user_id=None, limit=5): ...
MCALCheckpointer
class MCALCheckpointer(BaseCheckpointSaver):
def __init__(self, storage_path: Optional[str] = None): ...
def get(self, config) -> Optional[dict]: ...
def put(self, config, checkpoint): ...
def list(self, config) -> list[dict]: ...
Migrating from mcal[langgraph]
If you were using the old extras-based installation:
# Old way (deprecated)
from mcal.integrations.langgraph import MCALStore
# New way (recommended)
from mcal_langgraph import MCALStore
The old import path still works but will show a deprecation warning.
Requirements
- Python >= 3.11
- mcal-ai >= 0.2.0
- langgraph >= 0.2.0
- langchain-core >= 0.3.0
License
MIT
Metadata
Release files for mcal-ai-langgraph 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mcal_ai_langgraph-0.5.0.tar.gz | 16.7 kB | Without provenance | Details for mcal_ai_langgraph-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mcal_ai_langgraph-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for mcal_ai_langgraph-0.5.0-py3-none-any.whl |
Total release size: 31.3 kB
Release files / mcal_ai_langgraph-0.5.0.tar.gz
| Download URL | mcal_ai_langgraph-0.5.0.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
889be80fabab8442d1358df59a44607a12d2653992aa5b73f17f5017527d8f19
|
|
BLAKE2b-256 checksum How to use checksums |
189677c4273b8e95c5b4d7c8c74c5288576e98ca6db529ab67e8196e74dd17bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|
Release files / mcal_ai_langgraph-0.5.0-py3-none-any.whl
| Download URL | mcal_ai_langgraph-0.5.0-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e25d3d402119060cba48e88056520ade478422dd295437123374f3be29d6a4f
|
|
BLAKE2b-256 checksum How to use checksums |
9b36b6732dfccd9a94729fa88aa7348b0f74cdf99cf2cb9585284cbb3615b75e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|
Security for mcal-ai-langgraph 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.