SurrealDB ships an official integration for the LangChain.js and LangGraph.js ecosystems. It wraps the @surrealdb/spectron client so a chain or agent can retrieve from Spectron's knowledge base, expose memory as tools, and read memory through a LangGraph store.
The integration is TypeScript. Python applications call Spectron 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 Spectron HTTP client |
@surrealdb/langchain | VectorStore, hybrid Retriever, SpectronRetriever, agent tools, and a persisting chat model wrapper |
@surrealdb/langgraph | LangGraph BaseCheckpointSaver, BaseStore, and the Spectron-backed SpectronStore |
Requirements
Node.js 22+ or Bun 1+
Spectron access: endpoint, context, and API key
Installation
bun add @surrealdb/langchain @surrealdb/langgraph @surrealdb/spectronConfigure the client
Construct a client directly, or resolve one from the environment:
import { Spectron } from "@surrealdb/langchain-core";
const spectron = new Spectron({
context: "acme-prod",
apiKey: process.env.SPECTRON_API_KEY!,
endpoint: process.env.SPECTRON_ENDPOINT!,
});resolveSpectron reads SPECTRON_ENDPOINT, SPECTRON_API_KEY, and SPECTRON_CONTEXT, throwing a clear error if any is missing:
import { resolveSpectron } from "@surrealdb/langchain-core";
const spectron = resolveSpectron({}); // 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 | Spectron API origin, no trailing slash. There is no implicit default host. |
Retrieval
SpectronRetriever turns knowledge-base hits into LangChain Documents, with the chunk text as pageContent and document, chunk, score, and graph metadata in metadata:
import { SpectronRetriever } from "@surrealdb/langchain/retrievers";
const retriever = new SpectronRetriever({
client: spectron,
mode: "hybrid_graph", // "vector" | "bm25" | "hybrid" | "hybrid_graph"
k: 8,
});
const docs = await retriever.invoke("what is the return policy?");Agent tools
Two StructuredTools wire Spectron into an agent. Both accept either an instantiated client or a plain config object resolved from SPECTRON_* environment variables:
import { SpectronQueryTool, SpectronReflectTool } from "@surrealdb/langchain/tools";
const tools = [
new SpectronQueryTool({ client: spectron }),
new SpectronReflectTool({ client: spectron }),
];SpectronQueryTool takes { query, k?, mode?, filter? } and returns a compact JSON array of hits. SpectronReflectTool takes { query, persist? } and returns the reflection.
LangGraph store
SpectronStore is a read-oriented BaseStore adapter. Reads delegate to Spectron; writes are not supported, because Spectron persists memory through sessions and reflections rather than raw key/value puts:
import { SpectronStore } from "@surrealdb/langgraph/spectron_store";
const store = new SpectronStore({ spectron });
await store.get(["Person"], "tobie"); // → entities.get
await store.search(["Person"], { query: "who is tobie?", limit: 5 }); // → recall| Method | Backed by | Supported |
|---|---|---|
get | entities.get | Yes |
search | recall | Yes (requires query) |
put / delete / listNamespaces | n/a | Throws |
Vector store without Spectron
@surrealdb/langchain also exposes a VectorStore backed by SurrealDB's native HNSW index, for RAG against a SurrealDB instance you run yourself rather than the hosted Spectron service:
import { OpenAIEmbeddings } from "@langchain/openai";
import { VectorStore } from "@surrealdb/langchain";
const store = await VectorStore.initialize(new OpenAIEmbeddings(), {
surreal: { url: "ws://localhost:8000", username: "root", password: "root", 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 Spectron directly rather than through LangChain, use the JavaScript SDK.