LangChain / LangGraph Integration
February 16, 2026 · View on GitHub
Initial integration for using keep as memory within LangChain and LangGraph applications. Provides a LangGraph BaseStore, LangChain tools, a retriever, and middleware.
Installation
pip install keep-skill[langchain]
Or install the discovery shim (pulls in everything):
pip install langchain-keep
You still need an embedding/summarization provider configured — see QUICKSTART.md.
Components
KeepStore — LangGraph BaseStore
Maps LangGraph's namespace/key model to Keep's document model:
from keep.langchain import KeepStore
store = KeepStore() # default store (~/.keep)
store = KeepStore(store="~/.keep") # explicit path
store = KeepStore(keeper=my_keeper) # existing Keeper instance
Use with LangGraph:
from langgraph.graph import StateGraph
graph = StateGraph(...)
graph.compile(store=store)
Use with langmem:
from langmem import create_manage_memory_tool, create_search_memory_tool
tools = [
create_manage_memory_tool(namespace=("memories", "{user_id}")),
create_search_memory_tool(namespace=("memories", "{user_id}")),
]
Namespace-to-tag mapping
LangGraph uses hierarchical namespace tuples like ("memories", "alice"). Keep uses flat key-value tags. The namespace_keys setting bridges these:
# Default: namespace_keys=["user"]
# ("alice",) → {"user": "alice"}
# Custom mapping:
store = KeepStore(namespace_keys=["category", "user"])
# ("memories", "alice") → {"category": "memories", "user": "alice"}
These become regular Keep tags — visible to CLI, searchable, filterable:
keep list --tag user=alice # Find LangGraph-managed items
keep find "auth" -t category=memories # Search within a namespace
Configure in keep.toml instead of code:
[tags]
namespace_keys = ["category", "user"]
Value mapping
value["content"]becomes Keep's document text (configurable viacontent_key)- Other string values become tags
- Non-string values are preserved in a
_keep_datasystem tag (JSON) - The
_source=langchainsystem tag marks KeepStore-managed items
KeepNotesToolkit — LangChain Tools
Four curated tools for LangChain agents:
from keep.langchain import KeepNotesToolkit
from keep import Keeper
toolkit = KeepNotesToolkit(keeper=Keeper())
tools = toolkit.get_tools()
# → [remember, recall, get_context, update_context]
| Tool | Description |
|---|---|
remember | Store a note with tags |
recall | Semantic search |
get_context | Get current intentions (keep now) |
update_context | Update current intentions |
KeepNotesRetriever — BaseRetriever
For RAG chains with optional now-context injection:
from keep.langchain import KeepNotesRetriever
from keep import Keeper
retriever = KeepNotesRetriever(keeper=Keeper(), k=5)
docs = retriever.invoke("authentication patterns")
With now-context (prepends current intentions):
retriever = KeepNotesRetriever(keeper=Keeper(), include_now=True)
KeepNotesMiddleware — LCEL Runnable
Auto-injects memory context into RunnableConfig:
from keep.langchain import KeepNotesMiddleware
from keep import Keeper
middleware = KeepNotesMiddleware(keeper=Keeper())
chain = middleware | your_chain
Multi-user scoping
For multi-user applications, use user_id to scope all operations:
store = KeepStore(user_id="alice")
# All put/search/list operations auto-filter by user=alice
Combined with required_tags in config, this enforces per-user isolation:
[tags]
required = ["user"]
With this config, put() calls without a user tag raise ValueError. Scoped set_now(scope="alice") auto-tags user=alice, satisfying the requirement.
Limitations
This is an initial integration. Known limitations:
list_namespaces()scans up to 10K items (sufficient for most use cases)- Search
filtersupports exact-match equality only (operator filters like$gtare not supported) - KeepStore operations are synchronous;
abatch()wraps the sync implementation - The
langchain-keepshim re-exports fromkeep.langchain— no additional functionality
See Also
- PYTHON-API.md — Core Python API
- TAGGING.md — Tag system and conventions
- KEEP-CONFIG.md — Configuration reference
- ARCHITECTURE.md — System architecture