CrewAI × CLS++ (native external-memory provider)
Plug CLS++ in as CrewAI's persistent memory layer. Facts your agents learn
during one crew run are stored in CLS++ and automatically recalled — as task
context — on later runs, across processes and machines. This is the same slot
CrewAI documents for Mem0 (a third-party ExternalMemory storage), routed
through the CLS++ brain instead.
Install
pip install clsplusplus[crewai]
crewai is an optional extra — importing clsplusplus never requires it.
You only need it installed to actually run a Crew.
Configure
Grab an API key from your profile: https://www.clsplusplus.com/profile#api-keys
export CLS_API_KEY="cls_live_..."
# optional — defaults to https://www.clsplusplus.com
export CLS_BASE_URL="https://www.clsplusplus.com"
The provider reads CLS_API_KEY / CLS_BASE_URL from the environment (the
same defaults as the rest of the CLS++ SDK). You can also pass api_key= /
url= to CLSMemoryStorage(...) explicitly.
Wire it into a Crew
from crewai import Agent, Crew, Task
from crewai.memory.external.external_memory import ExternalMemory
from clsplusplus.integrations.crewai import CLSMemoryStorage
# `user` is the CLS++ namespace ("whose brain"). Use a per-crew or per-tenant
# id so memory is scoped correctly.
cls_storage = CLSMemoryStorage(user="support-crew")
researcher = Agent(
role="Researcher",
goal="Answer questions using what the crew has learned before",
backstory="You remember everything across runs via CLS++.",
)
task = Task(
description="What contact preferences do we know about this customer?",
expected_output="A short summary of known preferences.",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
memory=True,
external_memory=ExternalMemory(storage=cls_storage),
)
result = crew.kickoff()
print(result)
On each kickoff(), CrewAI:
- Recalls — calls
cls_storage.search(task_description)and injects the returned memories into the agent's task context. - Stores — calls
cls_storage.save(value, metadata)with what the agents produced, persisting it to CLS++ for the next run.
What the provider implements
CLSMemoryStorage implements CrewAI's storage contract
(crewai.memory.storage.interface.Storage):
| Method | CLS++ behavior |
|---|---|
save(value, metadata) |
Stores the text in CLS++ (Brain.learn), forwarding CrewAI metadata. |
search(query, limit, score_threshold) |
Semantic recall (Brain.ask); returns list[dict] where each item has a "content" key (what CrewAI's ContextualMemory reads). |
reset() |
Documented no-op — CLS++ is durable shared memory; manage retention via the CLS++ API or Brain.forget. Override the method if you want crew.reset_memories() to clear the namespace. |
Notes
- Scoping: every
CLSMemoryStorage(user=...)maps to a CLS++ namespace. Different crews / tenants should use differentuservalues. - No HTTP reimplemented: the provider delegates to the existing CLS++
Brainclient, so it inherits its auth, retries, and base-URL handling. isinstancechecks: CrewAI'sExternalMemoryis structural and accepts any object withsave/search/reset. If you specifically need a true subclass of CrewAI'sStorage, useCLSMemoryStorage.as_crewai_storage(user="...")(requirescrewai).