diff --git a/apps/docs/docs.json b/apps/docs/docs.json
index 2f543b02..ace8fe43 100644
--- a/apps/docs/docs.json
+++ b/apps/docs/docs.json
@@ -155,6 +155,7 @@
"integrations/openai",
"integrations/mastra",
"integrations/langchain",
+ "integrations/crewai",
"integrations/agno",
"integrations/memory-graph",
"integrations/claude-memory",
diff --git a/apps/docs/integrations/crewai.mdx b/apps/docs/integrations/crewai.mdx
new file mode 100644
index 00000000..f4fdc9c4
--- /dev/null
+++ b/apps/docs/integrations/crewai.mdx
@@ -0,0 +1,338 @@
+---
+title: "CrewAI"
+sidebarTitle: "CrewAI"
+description: "Add persistent memory to CrewAI agents with Supermemory"
+icon: "users"
+---
+
+CrewAI agents don't remember anything between runs by default. Supermemory fixes that. You get a memory layer that stores what happened, who the user is, and what they care about. Your crews can pick up where they left off.
+
+## What you can do
+
+- Give agents access to user preferences and past interactions
+- Store crew outputs so future runs can reference them
+- Search memories to give agents relevant context before they start
+
+## Setup
+
+Install the required packages:
+
+```bash
+pip install crewai supermemory python-dotenv
+```
+
+Configure your environment:
+
+```bash
+# .env
+SUPERMEMORY_API_KEY=your-supermemory-api-key
+OPENAI_API_KEY=your-openai-api-key
+```
+
+Get your Supermemory API key from [console.supermemory.ai](https://console.supermemory.ai).
+
+## Basic Integration
+
+Initialize Supermemory and inject user context into your agent's backstory:
+
+```python
+import os
+from crewai import Agent, Task, Crew, Process
+from supermemory import Supermemory
+from dotenv import load_dotenv
+
+load_dotenv()
+
+memory = Supermemory()
+
+def build_context(user_id: str, query: str) -> str:
+ """Fetch user profile and relevant memories."""
+ result = memory.profile(container_tag=user_id, q=query)
+
+ static = result.profile.static or []
+ dynamic = result.profile.dynamic or []
+ memories = result.search_results.results if result.search_results else []
+
+ return f"""
+User Profile:
+{chr(10).join(static) if static else 'No profile data.'}
+
+Current Context:
+{chr(10).join(dynamic) if dynamic else 'No recent activity.'}
+
+Relevant History:
+{chr(10).join([m.memory or m.chunk for m in memories[:5]]) if memories else 'None.'}
+"""
+
+def create_agent_with_memory(user_id: str, role: str, goal: str, query: str) -> Agent:
+ """Create an agent with user context baked into its backstory."""
+ context = build_context(user_id, query)
+
+ return Agent(
+ role=role,
+ goal=goal,
+ backstory=f"""You have access to the following information about the user:
+{context}
+
+Use this context to personalize your work.""",
+ verbose=True
+ )
+```
+
+---
+
+## Core Concepts
+
+### User profiles
+
+Supermemory tracks two kinds of user data:
+
+- **Static facts**: Things that don't change often (preferences, job title, tech stack)
+- **Dynamic context**: What the user is working on right now
+
+```python
+result = memory.profile(
+ container_tag="user_abc",
+ q="project planning" # Optional: also returns relevant memories
+)
+
+print(result.profile.static) # ["Prefers Agile methodology", "Senior engineer"]
+print(result.profile.dynamic) # ["Working on Q2 roadmap", "Focused on API design"]
+```
+
+### Storing memories
+
+Save crew outputs so future runs can reference them:
+
+```python
+def store_crew_result(user_id: str, task_description: str, result: str):
+ """Save crew output as a memory."""
+ memory.add(
+ content=f"Task: {task_description}\nResult: {result}",
+ container_tag=user_id,
+ metadata={"type": "crew_execution"}
+ )
+```
+
+### Searching memories
+
+Pull up past interactions before running a crew:
+
+```python
+results = memory.search.memories(
+ q="previous project recommendations",
+ container_tag="user_abc",
+ search_mode="hybrid",
+ limit=10
+)
+
+for r in results.results:
+ print(r.memory or r.chunk)
+```
+
+---
+
+## Example: research crew with memory
+
+This crew has two agents: a researcher and a writer. The researcher adjusts its technical depth based on the user's background. The writer remembers formatting preferences. Both can see what the user has asked about before.
+
+```python
+import os
+from crewai import Agent, Task, Crew, Process
+from crewai_tools import SerperDevTool
+from supermemory import Supermemory
+from dotenv import load_dotenv
+
+load_dotenv()
+
+class ResearchCrew:
+ def __init__(self):
+ self.memory = Supermemory()
+ self.search_tool = SerperDevTool()
+
+ def get_user_context(self, user_id: str, topic: str) -> dict:
+ """Retrieve user profile and related research history."""
+ result = self.memory.profile(
+ container_tag=user_id,
+ q=topic,
+ threshold=0.5
+ )
+
+ return {
+ "expertise": result.profile.static or [],
+ "focus": result.profile.dynamic or [],
+ "history": [m.memory for m in (result.search_results.results or [])[:3]]
+ }
+
+ def create_researcher(self, context: dict) -> Agent:
+ """Build a researcher agent with user context."""
+ expertise_note = ""
+ if context["expertise"]:
+ expertise_note = f"The user has this background: {', '.join(context['expertise'])}. Adjust technical depth accordingly."
+
+ history_note = ""
+ if context["history"]:
+ history_note = f"Previous research on related topics: {'; '.join(context['history'])}"
+
+ return Agent(
+ role="Research Analyst",
+ goal="Conduct research tailored to the user's expertise level",
+ backstory=f"""You research topics and synthesize findings into clear summaries.
+{expertise_note}
+{history_note}""",
+ tools=[self.search_tool],
+ verbose=True
+ )
+
+ def create_writer(self, context: dict) -> Agent:
+ """Build a writer agent that matches user preferences."""
+ style_note = "Write in a clear, technical style."
+ for fact in context.get("expertise", []):
+ if "non-technical" in fact.lower():
+ style_note = "Write in plain language, avoiding jargon."
+ break
+
+ return Agent(
+ role="Content Writer",
+ goal="Transform research into readable content",
+ backstory=f"""You write clear, engaging content. {style_note}""",
+ verbose=True
+ )
+
+ def research(self, user_id: str, topic: str) -> str:
+ """Run the research crew and store results."""
+ context = self.get_user_context(user_id, topic)
+
+ researcher = self.create_researcher(context)
+ writer = self.create_writer(context)
+
+ research_task = Task(
+ description=f"Research the following topic: {topic}",
+ expected_output="Detailed findings with sources",
+ agent=researcher
+ )
+
+ writing_task = Task(
+ description="Write a summary based on the research findings",
+ expected_output="A clear, structured summary",
+ agent=writer
+ )
+
+ crew = Crew(
+ agents=[researcher, writer],
+ tasks=[research_task, writing_task],
+ process=Process.sequential,
+ verbose=True
+ )
+
+ result = crew.kickoff()
+
+ # Store for future sessions
+ self.memory.add(
+ content=f"Research on '{topic}': {str(result)[:500]}",
+ container_tag=user_id,
+ metadata={"type": "research", "topic": topic}
+ )
+
+ return str(result)
+
+
+if __name__ == "__main__":
+ crew = ResearchCrew()
+
+ # Teach preferences
+ crew.memory.add(
+ content="User prefers concise summaries with bullet points",
+ container_tag="researcher_1"
+ )
+
+ # Run research
+ result = crew.research("researcher_1", "latest developments in AI agents")
+ print(result)
+```
+
+---
+
+## More patterns
+
+### Crews with multiple users
+
+Sometimes you need context from several users at once:
+
+```python
+def create_collaborative_context(user_ids: list[str], topic: str) -> str:
+ """Aggregate context from multiple users."""
+ combined = []
+
+ for user_id in user_ids:
+ result = memory.profile(container_tag=user_id, q=topic)
+ if result.profile.static:
+ combined.append(f"{user_id}: {', '.join(result.profile.static[:3])}")
+
+ return "\n".join(combined) if combined else "No shared context available."
+```
+
+### Only storing successful runs
+
+You might not want to save every crew output:
+
+```python
+def store_if_successful(user_id: str, task: str, result: str, success: bool):
+ """Only store successful task completions."""
+ if not success:
+ return
+
+ memory.add(
+ content=f"Completed: {task}\nOutcome: {result}",
+ container_tag=user_id,
+ metadata={"type": "success", "task": task}
+ )
+```
+
+### Using metadata to organize memories
+
+Metadata lets you filter memories by project, agent, or whatever else makes sense:
+
+```python
+# Store with metadata
+memory.add(
+ content="Research findings on distributed systems",
+ container_tag="user_123",
+ metadata={
+ "project": "infrastructure-review",
+ "agents": ["researcher", "writer"],
+ "confidence": "high"
+ }
+)
+
+# Search with filters
+results = memory.search.memories(
+ q="distributed systems",
+ container_tag="user_123",
+ filters={
+ "AND": [
+ {"key": "project", "value": "infrastructure-review"},
+ {"key": "confidence", "value": "high"}
+ ]
+ }
+)
+```
+
+---
+
+## Related docs
+
+
+
+ How automatic profiling works
+
+
+ Filtering and search modes
+
+
+ Memory for LangChain apps
+
+
+ Memory middleware for Next.js
+
+