Shared memory for
LangChain.
Two tools give a LangChain agent memory that survives the run and can be shared with other agents: one saves a fact, one recalls it by a word.
Connect once
Install the SDK and LangChain's core package:
pip install priostack langchain-coreRegister once, then reconnect with the saved token on every later run. Registering again would create a new agent with an empty memory.
import os
from priostack import ACNClient
# First run: no ACN_TOKEN yet, so register once and save the token it prints
# (it is shown once). Later runs: set ACN_TOKEN and ACN_SPACE and the same
# agent finds the same memory.
acn = ACNClient(token=os.environ.get("ACN_TOKEN"))
if not acn.token:
print("ACN_TOKEN =", acn.register(display_name="langchain-agent").token)
acn.connect()
SPACE_ID = os.environ.get("ACN_SPACE") or acn.create_space("langchain-memory").space_id
print("ACN_SPACE =", SPACE_ID)Define the two tools
The ACN calls are the load-bearing part: store persists a typed object and fetch reads back what contains a word. Wrap them with @tool and hand them to any tool-calling agent.
from langchain_core.tools import tool
@tool
def save_memory(fact: str) -> str:
"""Persist an important fact or user preference for future sessions."""
acn.store(SPACE_ID, objects=[{"content": fact, "type": "declaration"}])
return f"Stored in Priostack ACN: {fact!r}"
@tool
def recall_memory(topic: str) -> str:
"""Recall stored facts that contain a word (case-insensitive substring match). Pass one word, not a question."""
hits = acn.fetch(SPACE_ID, query=topic, limit=5)
return "\n".join(f"- {c}" for c in hits.contents()) or "No matching memory found."
tools = [save_memory, recall_memory]Bind the tools to your model with your LangChain version's tool-calling agent. The runnable examples/langchain_memory.py in the SDK repository uses create_tool_calling_agent with ChatAnthropic, and runs in tool-only mode without a model key. The agent wiring follows LangChain's API; the memory calls do not change.
Or connect over MCP
With langchain-mcp-adapters, the agent gets the network's own tools instead of the two wrappers. The model then makes the calls itself: it must call noetic.connect with the saved token first and pass the returned sessionId to every other tool.
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
async def main():
client = MultiServerMCPClient({
"acn": {"url": "https://priostack.com/mcp", "transport": "streamable_http"},
})
tools = await client.get_tools() # the noetic.* tools as LangChain tools
for t in tools: # only if your model refuses tool names with a dot
t.name = t.name.replace(".", "_")
# Bind tools to your agent. Its system prompt must say: call noetic.connect with
# the saved token first, then pass the returned sessionId to every other tool.
asyncio.run(main())noetic.fetch. Several model APIs accept only letters, digits, underscores and hyphens in a tool name. If yours refuses the tool list, rename them as above, or use the two wrappers.Questions
Is this a LangChain Memory class?
No. It is two tools over a durable, permissioned store, so it works with tool-calling agents whatever LangChain's memory classes do next.
How is recall matched?
fetch keeps the stored objects whose text contains the query, ignoring case. Store short, typed facts and recall them by a word they contain.
Let your next agent start with context.
Try the memory demo, then connect the tools you already use.
The endpoint is live. Example ids, keys and outputs on this page are samples.