A template implementation of the Model Context Protocol (MCP) server integrated with Mem0 for providing AI agents with persistent memory capabilities.
Use this as a reference point to build your MCP servers yourself, or give this as an example to an AI coding assistant and tell it to follow this example for structure and code correctness!
This project demonstrates how to build an MCP server that enables AI agents to store, retrieve, and search memories using semantic search with complete user and session isolation. It serves as a practical template for creating your own MCP servers, simply using Mem0 and a practical example.
The implementation follows the best practices laid out by Anthropic for building MCP servers, allowing seamless integration with any MCP-compatible client while ensuring data privacy and security through proper isolation mechanisms.
This version introduces required userId parameters for all memory operations. See the Migration Guide for details on updating existing code.
The server provides four essential memory management tools with user isolation:
save_memory: Store any information in long-term memory with semantic indexing and user isolationget_all_memories: Retrieve all stored memories for a specific usersearch_memories: Find relevant memories using semantic search within user boundariesdelete_memory: Remove specific memories with user-level access control
- Required
userId: All operations require user identification for complete isolation - Cross-User Protection: No data leakage between different users
- Simple & Secure: Clean, straightforward user isolation without complex metadata filtering
- Python 3.12+
- Supabase or any PostgreSQL database (for vector storage of memories)
- API keys for your chosen LLM provider (OpenAI, OpenRouter, or Ollama)
- Docker if running the MCP server as a container (recommended)
-
Install uv if you don't have it:
pip install uv
-
Clone this repository:
git clone https://github.com/coleam00/mcp-mem0.git cd mcp-mem0 -
Install dependencies:
uv pip install -e . -
Create a
.envfile using one of these methods:Option A: Interactive configuration (Recommended)
python scripts/configure_env.py
Option B: Use the setup script
python scripts/setup_env.py
Option C: Manual setup
cp env.example .env # Then edit .env with your values -
Configure your environment variables in the
.envfile (see Configuration section)
-
Create a
.envfile based onenv.exampleand configure your environment variables:cp env.example .env # Edit .env with your configuration -
Start the service:
docker-compose up -d
-
View logs:
docker-compose logs -f
-
Stop the service:
docker-compose down
-
Build the Docker image:
docker build -t mcp/mem0 --build-arg PORT=8050 . -
Create a
.envfile based onenv.exampleand configure your environment variables -
Run the container:
docker run --env-file .env -p 8050:8050 mcp/mem0
-
Configure environment variables using the interactive configurator:
python scripts/configure_env.py
-
Install and start the systemd service:
sudo ./scripts/install_service.sh install
-
Check service status:
sudo ./install_service.sh status
-
View logs:
sudo journalctl -u mcp-mem0 -f
The following environment variables can be configured in your .env file:
| Variable | Description | Example |
|---|---|---|
TRANSPORT |
Transport protocol (sse or stdio) | sse |
HOST |
Host to bind to when using SSE transport | 0.0.0.0 |
PORT |
Port to listen on when using SSE transport | 8050 |
| Variable | Description | Example | Required |
|---|---|---|---|
DEFAULT_USER_ID |
Default user ID for development | default_user |
Optional |
| Variable | Description | Example |
|---|---|---|
LLM_PROVIDER |
LLM provider (openai, openrouter, or ollama) | openai |
LLM_BASE_URL |
Base URL for the LLM API | https://api.openai.com/v1 |
LLM_API_KEY |
API key for the LLM provider | sk-... |
LLM_CHOICE |
LLM model to use | gpt-4o-mini |
EMBEDDING_MODEL_CHOICE |
Embedding model to use | text-embedding-3-small |
EMBEDDING_MODEL_DIMS |
Embedding model dimensions for vector storage | 1536 |
| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://user:pass@host:port/db |
⚠️ Security Note: In production, ALWAYS overrideDEFAULT_USER_IDto prevent all users from sharing the same memory space. Use unique identifiers like authentication subject IDs, email hashes, or tenant+user combinations.
📏 Embedding Dimensions Note: The
EMBEDDING_MODEL_DIMSvalue must match your embedding model's output dimensions. If not set, the system defaults to:
1536for OpenAI models (text-embedding-3-small)1024for Ollama and other models (nomic-embed-text)You can override these defaults by setting
EMBEDDING_MODEL_DIMSto any value you need.
# Set TRANSPORT=sse in .env then:
uv run src/main.pyThe MCP server will essentially be run as an API endpoint that you can then connect to with config shown below.
With stdio, the MCP client iself can spin up the MCP server, so nothing to run at this point.
docker run --env-file .env -p:8050:8050 mcp/mem0The MCP server will essentially be run as an API endpoint within the container that you can then connect to with config shown below.
With stdio, the MCP client iself can spin up the MCP server container, so nothing to run at this point.
Once you have the server running with SSE transport, you can connect to it using this configuration:
{
"mcpServers": {
"mem0": {
"transport": "sse",
"url": "http://localhost:8050/sse"
}
}
}Note for Windsurf users: Use
serverUrlinstead ofurlin your configuration:{ "mcpServers": { "mem0": { "transport": "sse", "serverUrl": "http://localhost:8050/sse" } } }
Note for n8n users: Use host.docker.internal instead of localhost since n8n has to reach outside of it's own container to the host machine:
So the full URL in the MCP node would be: http://host.docker.internal:8050/sse
Make sure to update the port if you are using a value other than the default 8050.
Add this server to your MCP configuration for Claude Desktop, Windsurf, or any other MCP client:
{
"mcpServers": {
"mem0": {
"command": "your/path/to/mcp-mem0/.venv/Scripts/python.exe",
"args": ["your/path/to/mcp-mem0/src/main.py"],
"env": {
"TRANSPORT": "stdio",
"LLM_PROVIDER": "openai",
"LLM_BASE_URL": "https://api.openai.com/v1",
"LLM_API_KEY": "YOUR-API-KEY",
"LLM_CHOICE": "gpt-4o-mini",
"EMBEDDING_MODEL_CHOICE": "text-embedding-3-small",
"DATABASE_URL": "YOUR-DATABASE-URL"
}
}
}
}{
"mcpServers": {
"mem0": {
"command": "docker",
"args": ["run", "--rm", "-i",
"-e", "TRANSPORT",
"-e", "LLM_PROVIDER",
"-e", "LLM_BASE_URL",
"-e", "LLM_API_KEY",
"-e", "LLM_CHOICE",
"-e", "EMBEDDING_MODEL_CHOICE",
"-e", "DATABASE_URL",
"mcp/mem0"],
"env": {
"TRANSPORT": "stdio",
"LLM_PROVIDER": "openai",
"LLM_BASE_URL": "https://api.openai.com/v1",
"LLM_API_KEY": "YOUR-API-KEY",
"LLM_CHOICE": "gpt-4o-mini",
"EMBEDDING_MODEL_CHOICE": "text-embedding-3-small",
"DATABASE_URL": "YOUR-DATABASE-URL"
}
}
}
}# Save a memory for a specific user
await save_memory(
content="User prefers dark mode interface",
userId="user_123"
)
# Search memories for a user
results = await search_memories(
query="interface preferences",
userId="user_123"
)
# Get all memories for a user
memories = await get_all_memories(userId="user_123")
# Delete a specific memory
await delete_memory(
memoryId="mem_xyz789",
userId="user_123"
)userIdis REQUIRED for all operations- Users can only access their own memories
- Simple and secure user isolation
- No cross-user data leakage
This template provides a foundation for building more complex MCP servers. To build your own:
- Add your own tools by creating methods with the
@mcp.tool()decorator - Create your own lifespan function to add your own dependencies (clients, database connections, etc.)
- Modify the
utils.pyfile for any helper functions you need for your MCP server - Feel free to add prompts and resources as well with
@mcp.resource()and@mcp.prompt()
Run the comprehensive test suite to verify user isolation:
python3 tests/test_user_isolation.pyThe test suite validates:
- ✅ User isolation (no cross-user data access)
- ✅ Security validation (required userId)
- ✅ Error handling and edge cases
sudo ./install_service.sh installsudo ./install_service.sh statussudo ./install_service.sh uninstall# Check status
sudo systemctl status mcp-mem0
# View logs
sudo journalctl -u mcp-mem0 -f
# Restart service
sudo systemctl restart mcp-mem0
# Stop service
sudo systemctl stop mcp-mem0
# Enable/disable auto-start
sudo systemctl enable mcp-mem0
sudo systemctl disable mcp-mem0This error typically occurs when the Mem0 client is not properly initialized due to missing environment variables.
Solution:
- Run the setup script to configure your environment:
python setup_env.py
- Ensure all required environment variables are set:
LLM_PROVIDER(openai, openrouter, or ollama)LLM_API_KEY(your API key)LLM_CHOICE(model name)DATABASE_URL(Supabase connection string)
- Restart the MCP server after setting environment variables
If you see "Failed to initialize Mem0 client" errors:
Check:
- API keys are valid and have sufficient credits
- Database connection string is correct
- LLM provider is supported (openai, openrouter, or ollama)
- Required environment variables are set
For connection problems:
SSE Transport:
- Verify
HOSTandPORTare accessible - Check firewall settings
- Ensure the port is not already in use
STDIO Transport:
- Verify the client is properly configured for stdio
- Check for any buffering issues
Use the interactive configuration script for easy setup:
python scripts/configure_env.pyThis will guide you through setting up all required environment variables with validation and helpful instructions.
Alternative setup methods:
- scripts/setup_env.py: Basic setup script
- Manual: Copy env.example and edit manually
If you prefer manual setup:
-
Copy the example environment file:
cp env.example .env
-
Edit
.envwith your actual values:nano .env # or use your preferred editor -
Restart the MCP server
- Check the User Isolation Documentation for detailed implementation details
- Review the Implementation Summary for architecture overview
- Run the test suite to validate your setup:
python tests/test_user_isolation.py
- User Isolation Documentation - Comprehensive guide to user and session isolation
- Implementation Summary - Complete overview of the implementation
- Environment Configuration - Example environment file with security notes
- Test Suite - Validation tests for all isolation features
mcp-mem0/
├── src/ # Source code
│ ├── main.py # MCP server entry point
│ ├── config.py # Configuration management
│ ├── utils.py # Utility functions
│ ├── database_manager.py # Database connection management
│ ├── health_check.py # Health check endpoints
│ └── logger.py # Logging configuration
├── tests/ # Test files
├── scripts/ # Utility and setup scripts
│ ├── configure_env.py # Interactive environment setup
│ ├── setup_env.py # Basic environment setup
│ └── install_service.sh # Systemd service installer
├── docs/ # Documentation files
├── public/ # Static assets
├── Dockerfile # Docker image definition
├── docker-compose.yml # Docker Compose configuration
├── .dockerignore # Docker build exclusions
├── pyproject.toml # Python project configuration
└── README.md # This file
- Production Deployment: Consider overriding
DEFAULT_USER_IDin production for better user isolation - User Identification: Use stable, unique identifiers (UUIDs, auth subject IDs) when calling MCP tools
- Environment Variables: Secure all API keys and database credentials
- Regular Testing: Verify isolation features work correctly in your environment