Framework adapters
Drop-in MemHQ memory for LangChain, LlamaIndex, and the Vercel AI SDK — in Python and TypeScript.
Framework adapters
If you already build on LangChain, LlamaIndex, or the Vercel AI SDK, you don't need to call the MemHQ API directly. Each adapter implements that framework's own memory interface, so MemHQ becomes the persistence layer behind the abstraction you're already using.
Every adapter is a thin wrapper over @memhq/sdk or
memhq — same endpoints, same per-user graphs, nothing
hidden. Each one needs a project API key (mem_…), which it reads from
MEMHQ_API_KEY unless you pass it explicitly.
Memory is scoped per end-user. Every adapter takes a userId /
user_id; pass the same stable id across sessions and the graph
compounds. Pass a different one and you get a different graph — see
Memory model.
LangChain (TypeScript)
npm install @memhq/langchain @memhq/sdk @langchain/coreMemHQMessageHistory implements LangChain's BaseChatMessageHistory, so
it slots into RunnableWithMessageHistory wherever you'd otherwise use an
in-memory or Redis history.
import { MemHQMessageHistory } from "@memhq/langchain";
import { RunnableWithMessageHistory } from "@langchain/core/runnables";
const chain = new RunnableWithMessageHistory({
runnable: prompt.pipe(model),
getMessageHistory: (sessionId) =>
new MemHQMessageHistory({ userId: sessionId }),
inputMessagesKey: "input",
historyMessagesKey: "history",
});LangChain (Python)
pip install memhq-langchainMemHQChatMessageHistory implements BaseChatMessageHistory:
from memhq_langchain import MemHQChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
chain = RunnableWithMessageHistory(
prompt | model,
lambda session_id: MemHQChatMessageHistory(user_id=session_id),
input_messages_key="input",
history_messages_key="history",
)LlamaIndex (TypeScript)
npm install @memhq/llamaindex @memhq/sdk llamaindexMemHQChatMemory satisfies LlamaIndex's chat-memory interface, so an
agent keeps its recall between runs:
import { MemHQChatMemory } from "@memhq/llamaindex";
import { OpenAIAgent } from "llamaindex";
const agent = new OpenAIAgent({
memory: new MemHQChatMemory({ userId: "u_42" }),
tools: [],
});LlamaIndex (Python)
pip install memhq-llamaindexfrom memhq_llamaindex import MemHQMemory
from llama_index.core.agent import ReActAgent
agent = ReActAgent.from_tools(
tools,
llm=llm,
memory=MemHQMemory(user_id="u_42"),
)Vercel AI SDK
npm install @memhq/vercel-ai @memhq/sdk aiwithMemHQ wraps a generateText or streamText call: it retrieves
relevant memory before the model runs and writes the turn back afterwards,
so a route handler stays a single call.
import { withMemHQ } from "@memhq/vercel-ai";
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
const result = await withMemHQ(
{ userId: "u_42" },
({ system }) =>
streamText({ model: openai("gpt-4o-mini"), system, messages }),
);Choosing between an adapter and the SDK
Adapters are the right call when the framework already owns your control
flow and you want memory to be invisible. Reach past them to
the SDK when you want to decide what gets stored and
when it gets retrieved — for example writing only summarised turns, or
scoping a search to a group graph. The two mix freely: an adapter and a
direct SDK call against the same user_id read and write the same graph.