SDKs

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/core

MemHQMessageHistory 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-langchain

MemHQChatMessageHistory 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 llamaindex

MemHQChatMemory 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-llamaindex
from 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 ai

withMemHQ 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.