SurrealDB ships an official integration for the LangChain.js and LangGraph.js ecosystems. It wraps the @surrealdb/memory client so a chain or agent can retrieve from SurrealDB Agent Memory's knowledge base, expose memory as tools, and read memory through a LangGraph store.
The integration is TypeScript. Python applications call SurrealDB Agent Memory through the Python SDK or the REST API instead.
Packages
| Package | What it provides |
|---|---|
@surrealdb/langchain-core | Shared SurrealDB client, config, schema and filter helpers, and the SurrealDB Agent Memory HTTP client |
@surrealdb/langchain | SurrealDBVectorStore, HybridRetriever, AgentMemoryRetriever, agent tools, and a persisting chat model wrapper |
@surrealdb/langgraph | LangGraph BaseCheckpointSaver and BaseStore implementations, and AgentMemoryStore, backed by SurrealDB Agent Memory |
Requirements
Node.js 22+ or Bun 1+
SurrealDB Agent Memory access: endpoint, context, and API key
Installation
bun add @surrealdb/langchain @surrealdb/langgraph @surrealdb/memoryConfigure the client
Construct a client directly, or resolve one from the environment:
import { AgentMemory } from "@surrealdb/langchain-core";
const memory = new AgentMemory({
context: "acme-prod",
apiKey: process.env.AGENT_MEMORY_API_KEY!,
endpoint: process.env.AGENT_MEMORY_ENDPOINT!,
});resolveAgentMemory reads AGENT_MEMORY_ENDPOINT, AGENT_MEMORY_API_KEY, and AGENT_MEMORY_CONTEXT, throwing a clear error if any is missing:
import { resolveAgentMemory } from "@surrealdb/langchain-core";
const memory = resolveAgentMemory({}); // all three from the environment| Field | Required | Notes |
|---|---|---|
context | Yes | Context id, for example "acme-prod". Pins every request to /api/v1/{context}/…. |
apiKey | Yes | Bearer token, sent as Authorization: Bearer …. |
endpoint | Yes | SurrealDB Agent Memory API origin, no trailing slash. There is no implicit default host. |
Retrieval
AgentMemoryRetriever turns knowledge-base hits into LangChain Documents, with the chunk text as pageContent and document, chunk, score, and graph metadata in metadata:
import { AgentMemoryRetriever } from "@surrealdb/langchain/retrievers";
const retriever = new AgentMemoryRetriever({
client: memory,
mode: "hybrid_graph", // "vector" | "bm25" | "hybrid" | "hybrid_graph"
k: 8,
});
const docs = await retriever.invoke("what is the return policy?");Agent tools
Two tool factories wire SurrealDB Agent Memory into an agent. Both take a client, which is either an instantiated client or a plain config object that falls back to the AGENT_MEMORY_* environment variables:
import { createAgentMemoryQueryTool, createAgentMemoryReflectTool } from "@surrealdb/langchain/tools";
const tools = [
createAgentMemoryQueryTool({ client: memory }),
createAgentMemoryReflectTool({ client: memory }),
];The query tool takes { query, k?, mode?, filter? }. It gives the model a readable digest of the top hits and returns the retrieved Documents as the tool artifact. The reflect tool takes { query, persist? } and returns the reflection.
LangGraph store
AgentMemoryStore is a read-oriented BaseStore adapter. Reads delegate to SurrealDB Agent Memory; writes are not supported, because Agent Memory persists memory through sessions and reflections rather than raw key/value puts:
import { AgentMemoryStore } from "@surrealdb/langgraph/memory_store";
const store = new AgentMemoryStore({ client: memory });
await store.get(["Person"], "tobie"); // → entities.get
await store.search([], { query: "who is tobie?", limit: 5 }); // → recallRecall has no namespace dimension, so search with a non-empty namespace prefix throws by default. Set namespaceMode: "lens" to apply the prefix as a scope lens, or namespaceMode: "ignore" to search without it.
| Method | Backed by | Supported |
|---|---|---|
get | entities.get | Yes |
search | recall | Yes (requires query) |
put / delete / listNamespaces | n/a | Throws |
Vector store without agent memory
@surrealdb/langchain also exposes SurrealDBVectorStore, backed by SurrealDB's native HNSW index, for RAG against a SurrealDB instance you run yourself rather than the hosted agent memory service:
import { OpenAIEmbeddings } from "@langchain/openai";
import { SurrealDBVectorStore } from "@surrealdb/langchain";
const store = await SurrealDBVectorStore.initialize(new OpenAIEmbeddings(), {
surreal: { url: "ws://localhost:8000", username: "root", password: "secret", namespace: "app", database: "rag" },
tableName: "documents",
dimensions: 1536,
});When to use MCP or the SDK instead
If the host is Claude, Cursor, or another MCP-native client, prefer the MCP server, with no adapter required.
If your application calls SurrealDB Agent Memory directly rather than through LangChain, use the JavaScript SDK.