better-mem0-mcp 1.1.0b22__py3-none-any.whl → 1.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- better_mem0_mcp/config.py +21 -14
- better_mem0_mcp/docs/memory.md +1 -14
- better_mem0_mcp/server.py +9 -16
- {better_mem0_mcp-1.1.0b22.dist-info → better_mem0_mcp-1.1.2.dist-info}/METADATA +37 -61
- better_mem0_mcp-1.1.2.dist-info/RECORD +11 -0
- better_mem0_mcp/__main__.py +0 -6
- better_mem0_mcp-1.1.0b22.dist-info/RECORD +0 -12
- {better_mem0_mcp-1.1.0b22.dist-info → better_mem0_mcp-1.1.2.dist-info}/WHEEL +0 -0
- {better_mem0_mcp-1.1.0b22.dist-info → better_mem0_mcp-1.1.2.dist-info}/entry_points.txt +0 -0
- {better_mem0_mcp-1.1.0b22.dist-info → better_mem0_mcp-1.1.2.dist-info}/licenses/LICENSE +0 -0
better_mem0_mcp/config.py
CHANGED
|
@@ -33,36 +33,43 @@ class Settings(BaseSettings):
|
|
|
33
33
|
embedder_models: str = "gemini/gemini-embedding-001"
|
|
34
34
|
|
|
35
35
|
def setup_api_keys(self) -> dict[str, list[str]]:
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
Example:
|
|
39
|
-
API_KEYS="GOOGLE_API_KEY:abc,GOOGLE_API_KEY:def,OPENAI_API_KEY:xyz"
|
|
36
|
+
"""
|
|
37
|
+
Parse API_KEYS and set environment variables for LiteLLM.
|
|
40
38
|
|
|
41
39
|
Returns:
|
|
42
|
-
Dict mapping
|
|
40
|
+
Dict mapping provider to list of API keys.
|
|
43
41
|
"""
|
|
44
|
-
|
|
42
|
+
env_map = {
|
|
43
|
+
"gemini": "GOOGLE_API_KEY",
|
|
44
|
+
"openai": "OPENAI_API_KEY",
|
|
45
|
+
"anthropic": "ANTHROPIC_API_KEY",
|
|
46
|
+
"groq": "GROQ_API_KEY",
|
|
47
|
+
"deepseek": "DEEPSEEK_API_KEY",
|
|
48
|
+
"mistral": "MISTRAL_API_KEY",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
keys_by_provider: dict[str, list[str]] = {}
|
|
45
52
|
|
|
46
53
|
for pair in self.api_keys.split(","):
|
|
47
54
|
pair = pair.strip()
|
|
48
55
|
if ":" not in pair:
|
|
49
56
|
continue
|
|
50
57
|
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
provider, key = pair.split(":", 1)
|
|
59
|
+
provider = provider.strip().lower()
|
|
53
60
|
key = key.strip()
|
|
54
61
|
|
|
55
62
|
if not key:
|
|
56
63
|
continue
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
keys_by_provider.setdefault(provider, []).append(key)
|
|
59
66
|
|
|
60
|
-
# Set first key of each env var (LiteLLM reads from env)
|
|
61
|
-
for
|
|
62
|
-
if keys:
|
|
63
|
-
os.environ[
|
|
67
|
+
# Set first key of each provider as env var (LiteLLM reads from env)
|
|
68
|
+
for provider, keys in keys_by_provider.items():
|
|
69
|
+
if provider in env_map and keys:
|
|
70
|
+
os.environ[env_map[provider]] = keys[0]
|
|
64
71
|
|
|
65
|
-
return
|
|
72
|
+
return keys_by_provider
|
|
66
73
|
|
|
67
74
|
def parse_database_url(self) -> dict:
|
|
68
75
|
"""Parse DATABASE_URL into connection parameters."""
|
better_mem0_mcp/docs/memory.md
CHANGED
|
@@ -17,8 +17,6 @@ Save information to long-term memory. Mem0 automatically:
|
|
|
17
17
|
{"action": "add", "content": "User prefers dark mode and uses FastAPI"}
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
**Response:** `Saved: {results: [{id, memory, event}]}`
|
|
21
|
-
|
|
22
20
|
### search
|
|
23
21
|
Semantic search across stored memories. Combines vector search with graph context.
|
|
24
22
|
|
|
@@ -26,8 +24,6 @@ Semantic search across stored memories. Combines vector search with graph contex
|
|
|
26
24
|
{"action": "search", "query": "coding preferences", "limit": 5}
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
**Response:** Formatted list of matching memories with optional graph context.
|
|
30
|
-
|
|
31
27
|
### list
|
|
32
28
|
Get all stored memories for a user.
|
|
33
29
|
|
|
@@ -35,8 +31,6 @@ Get all stored memories for a user.
|
|
|
35
31
|
{"action": "list"}
|
|
36
32
|
```
|
|
37
33
|
|
|
38
|
-
**Response:** `Memories (N): - [id] memory text`
|
|
39
|
-
|
|
40
34
|
### delete
|
|
41
35
|
Remove a memory by ID.
|
|
42
36
|
|
|
@@ -44,17 +38,10 @@ Remove a memory by ID.
|
|
|
44
38
|
{"action": "delete", "memory_id": "abc12345-..."}
|
|
45
39
|
```
|
|
46
40
|
|
|
47
|
-
**Response:** `Deleted: {memory_id}`
|
|
48
|
-
|
|
49
41
|
## Parameters
|
|
50
42
|
- `action` - Required: add, search, list, delete
|
|
51
43
|
- `content` - Required for add: information to remember
|
|
52
44
|
- `query` - Required for search: what to search for
|
|
53
45
|
- `memory_id` - Required for delete: ID of memory to remove
|
|
54
46
|
- `limit` - Optional for search: max results (default: 5)
|
|
55
|
-
- `user_id` - Optional: scope memories to a specific user
|
|
56
|
-
|
|
57
|
-
## Technical Notes
|
|
58
|
-
- Mem0 API returns `{"results": [...]}` for both `search()` and `get_all()`
|
|
59
|
-
- Graph context is automatically included in search results when available
|
|
60
|
-
- Embeddings use 1536 dimensions for pgvector HNSW compatibility
|
|
47
|
+
- `user_id` - Optional: scope memories to a specific user
|
better_mem0_mcp/server.py
CHANGED
|
@@ -108,24 +108,21 @@ async def memory(
|
|
|
108
108
|
if not query:
|
|
109
109
|
return "Error: 'query' required for search action"
|
|
110
110
|
|
|
111
|
-
# Vector search
|
|
112
|
-
|
|
113
|
-
memories = (
|
|
114
|
-
response.get("results", []) if isinstance(response, dict) else response
|
|
115
|
-
)
|
|
111
|
+
# Vector search
|
|
112
|
+
results = _memory.search(query, user_id=user_id, limit=limit)
|
|
116
113
|
|
|
117
114
|
# Add graph context
|
|
118
115
|
graph_context = ""
|
|
119
116
|
if _graph:
|
|
120
117
|
graph_context = _graph.get_context(query, user_id)
|
|
121
118
|
|
|
122
|
-
if not
|
|
119
|
+
if not results and not graph_context:
|
|
123
120
|
return "No memories found."
|
|
124
121
|
|
|
125
122
|
output = ""
|
|
126
|
-
if
|
|
123
|
+
if results:
|
|
127
124
|
output = "Memories:\n" + "\n".join(
|
|
128
|
-
[f"- {
|
|
125
|
+
[f"- {r.get('memory', str(r))}" for r in results]
|
|
129
126
|
)
|
|
130
127
|
if graph_context:
|
|
131
128
|
output += f"\n\n{graph_context}"
|
|
@@ -133,17 +130,13 @@ async def memory(
|
|
|
133
130
|
return output
|
|
134
131
|
|
|
135
132
|
elif action == "list":
|
|
136
|
-
|
|
137
|
-
response = _memory.get_all(user_id=user_id)
|
|
138
|
-
memories = (
|
|
139
|
-
response.get("results", []) if isinstance(response, dict) else response
|
|
140
|
-
)
|
|
133
|
+
results = _memory.get_all(user_id=user_id)
|
|
141
134
|
|
|
142
|
-
if not
|
|
135
|
+
if not results:
|
|
143
136
|
return "No memories stored."
|
|
144
137
|
|
|
145
|
-
lines = [f"- [{
|
|
146
|
-
return f"Memories ({len(
|
|
138
|
+
lines = [f"- [{r['id'][:8]}] {r['memory']}" for r in results]
|
|
139
|
+
return f"Memories ({len(results)}):\n" + "\n".join(lines)
|
|
147
140
|
|
|
148
141
|
elif action == "delete":
|
|
149
142
|
if not memory_id:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: better-mem0-mcp
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Zero-setup MCP Server for AI memory - works with Neon/Supabase
|
|
5
5
|
Project-URL: Homepage, https://github.com/n24q02m/better-mem0-mcp
|
|
6
6
|
Project-URL: Repository, https://github.com/n24q02m/better-mem0-mcp.git
|
|
@@ -17,7 +17,7 @@ Classifier: Operating System :: OS Independent
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
-
Requires-Python:
|
|
20
|
+
Requires-Python: >=3.13
|
|
21
21
|
Requires-Dist: google-genai>=1.0.0
|
|
22
22
|
Requires-Dist: litellm>=1.0.0
|
|
23
23
|
Requires-Dist: loguru>=0.7.0
|
|
@@ -29,28 +29,16 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
|
|
30
30
|
# better-mem0-mcp
|
|
31
31
|
|
|
32
|
-
**
|
|
32
|
+
**Zero-setup** MCP Server for AI memory. Works with Neon/Supabase free tier.
|
|
33
33
|
|
|
34
|
-
[](https://hub.docker.com/r/n24q02m/better-mem0-mcp)
|
|
36
|
-
[](LICENSE)
|
|
37
|
-
|
|
38
|
-
## Features
|
|
39
|
-
|
|
40
|
-
- **Self-hosted PostgreSQL** - Your data stays with you (Neon/Supabase free tier supported)
|
|
41
|
-
- **Graph Memory** - SQL-based relationship tracking alongside vector memory
|
|
42
|
-
- **Multi-provider LLM** - Gemini, OpenAI, Anthropic, Groq, DeepSeek, Mistral
|
|
43
|
-
- **Fallback chains** - Multi-key per provider + multi-model fallback
|
|
44
|
-
- **Zero manual setup** - Just `DATABASE_URL` + `API_KEYS`
|
|
45
|
-
|
|
46
|
-
---
|
|
34
|
+
[](https://opensource.org/licenses/MIT)
|
|
47
35
|
|
|
48
36
|
## Quick Start
|
|
49
37
|
|
|
50
38
|
### 1. Get Prerequisites
|
|
51
39
|
|
|
52
|
-
- **Database**: [Neon](https://neon.tech) or [Supabase](https://supabase.com) (free tier
|
|
53
|
-
- **API Key**:
|
|
40
|
+
- **Database**: [Neon](https://neon.tech) or [Supabase](https://supabase.com) (free tier)
|
|
41
|
+
- **API Key**: [Google AI Studio](https://aistudio.google.com/apikey) (free tier)
|
|
54
42
|
|
|
55
43
|
### 2. Add to mcp.json
|
|
56
44
|
|
|
@@ -59,12 +47,12 @@ Description-Content-Type: text/markdown
|
|
|
59
47
|
```json
|
|
60
48
|
{
|
|
61
49
|
"mcpServers": {
|
|
62
|
-
"
|
|
50
|
+
"memory": {
|
|
63
51
|
"command": "uvx",
|
|
64
|
-
"args": ["better-mem0-mcp
|
|
52
|
+
"args": ["better-mem0-mcp"],
|
|
65
53
|
"env": {
|
|
66
54
|
"DATABASE_URL": "postgresql://user:pass@xxx.neon.tech/neondb?sslmode=require",
|
|
67
|
-
"API_KEYS": "
|
|
55
|
+
"API_KEYS": "gemini:AIza..."
|
|
68
56
|
}
|
|
69
57
|
}
|
|
70
58
|
}
|
|
@@ -76,12 +64,12 @@ Description-Content-Type: text/markdown
|
|
|
76
64
|
```json
|
|
77
65
|
{
|
|
78
66
|
"mcpServers": {
|
|
79
|
-
"
|
|
67
|
+
"memory": {
|
|
80
68
|
"command": "docker",
|
|
81
69
|
"args": ["run", "-i", "--rm", "-e", "DATABASE_URL", "-e", "API_KEYS", "n24q02m/better-mem0-mcp:latest"],
|
|
82
70
|
"env": {
|
|
83
71
|
"DATABASE_URL": "postgresql://...",
|
|
84
|
-
"API_KEYS": "
|
|
72
|
+
"API_KEYS": "gemini:AIza..."
|
|
85
73
|
}
|
|
86
74
|
}
|
|
87
75
|
}
|
|
@@ -90,7 +78,7 @@ Description-Content-Type: text/markdown
|
|
|
90
78
|
|
|
91
79
|
### 3. Done!
|
|
92
80
|
|
|
93
|
-
Ask
|
|
81
|
+
Ask Claude: "Remember that I prefer dark mode and use FastAPI"
|
|
94
82
|
|
|
95
83
|
---
|
|
96
84
|
|
|
@@ -98,25 +86,22 @@ Ask your AI: "Remember that I prefer dark mode and use FastAPI"
|
|
|
98
86
|
|
|
99
87
|
| Variable | Required | Description |
|
|
100
88
|
|----------|----------|-------------|
|
|
101
|
-
| `DATABASE_URL` | Yes | PostgreSQL
|
|
102
|
-
| `API_KEYS` | Yes | `
|
|
103
|
-
| `LLM_MODELS` | No |
|
|
104
|
-
| `EMBEDDER_MODELS` | No |
|
|
89
|
+
| `DATABASE_URL` | Yes | PostgreSQL connection string |
|
|
90
|
+
| `API_KEYS` | Yes | `provider:key,...` (multi-key per provider OK) |
|
|
91
|
+
| `LLM_MODELS` | No | `provider/model,...` (fallback chain) |
|
|
92
|
+
| `EMBEDDER_MODELS` | No | `provider/model,...` (fallback chain) |
|
|
105
93
|
|
|
106
|
-
###
|
|
94
|
+
### Examples
|
|
107
95
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
**Single provider:**
|
|
112
|
-
```bash
|
|
113
|
-
API_KEYS=GOOGLE_API_KEY:AIza...
|
|
96
|
+
**Minimal (Gemini only):**
|
|
97
|
+
```
|
|
98
|
+
API_KEYS=gemini:AIza...
|
|
114
99
|
```
|
|
115
100
|
|
|
116
101
|
**Multi-key with fallback:**
|
|
117
|
-
```
|
|
118
|
-
API_KEYS=
|
|
119
|
-
LLM_MODELS=gemini/gemini-
|
|
102
|
+
```
|
|
103
|
+
API_KEYS=gemini:AIza-1,gemini:AIza-2,openai:sk-xxx
|
|
104
|
+
LLM_MODELS=gemini/gemini-2.5-flash,openai/gpt-4o-mini
|
|
120
105
|
EMBEDDER_MODELS=gemini/gemini-embedding-001,openai/text-embedding-3-small
|
|
121
106
|
```
|
|
122
107
|
|
|
@@ -124,7 +109,7 @@ EMBEDDER_MODELS=gemini/gemini-embedding-001,openai/text-embedding-3-small
|
|
|
124
109
|
|
|
125
110
|
| Setting | Default |
|
|
126
111
|
|---------|---------|
|
|
127
|
-
| `LLM_MODELS` | `gemini/gemini-
|
|
112
|
+
| `LLM_MODELS` | `gemini/gemini-2.5-flash` |
|
|
128
113
|
| `EMBEDDER_MODELS` | `gemini/gemini-embedding-001` |
|
|
129
114
|
|
|
130
115
|
---
|
|
@@ -133,41 +118,32 @@ EMBEDDER_MODELS=gemini/gemini-embedding-001,openai/text-embedding-3-small
|
|
|
133
118
|
|
|
134
119
|
| Tool | Description |
|
|
135
120
|
|------|-------------|
|
|
136
|
-
| `memory` |
|
|
137
|
-
| `help` |
|
|
121
|
+
| `memory` | `action`: add, search, list, delete |
|
|
122
|
+
| `help` | Detailed documentation |
|
|
138
123
|
|
|
139
|
-
### Usage
|
|
124
|
+
### Usage
|
|
140
125
|
|
|
141
126
|
```json
|
|
142
127
|
{"action": "add", "content": "I prefer TypeScript over JavaScript"}
|
|
143
|
-
{"action": "search", "query": "
|
|
128
|
+
{"action": "search", "query": "preferences"}
|
|
144
129
|
{"action": "list"}
|
|
145
130
|
{"action": "delete", "memory_id": "abc123"}
|
|
146
131
|
```
|
|
147
132
|
|
|
148
133
|
---
|
|
149
134
|
|
|
150
|
-
##
|
|
135
|
+
## Why better-mem0-mcp?
|
|
151
136
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# Run
|
|
160
|
-
uv run better-mem0-mcp
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Requirements:** Python 3.13+
|
|
137
|
+
| Feature | Official mem0-mcp | better-mem0-mcp |
|
|
138
|
+
|---------|-------------------|-----------------|
|
|
139
|
+
| Storage | Mem0 Cloud | **Self-hosted PostgreSQL** |
|
|
140
|
+
| Graph Memory | No | **Yes (SQL-based)** |
|
|
141
|
+
| LLM Provider | OpenAI only | **Any (Gemini/OpenAI/Ollama/...)** |
|
|
142
|
+
| Fallback | No | **Yes (multi-key + multi-model)** |
|
|
143
|
+
| Setup | API Key | **DATABASE_URL + API_KEYS** |
|
|
164
144
|
|
|
165
145
|
---
|
|
166
146
|
|
|
167
|
-
## Contributing
|
|
168
|
-
|
|
169
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
170
|
-
|
|
171
147
|
## License
|
|
172
148
|
|
|
173
|
-
MIT
|
|
149
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
better_mem0_mcp/__init__.py,sha256=fcqgbz2HvMCPidqqoPvtRky5pGIHP2w9oVim7UQkuBc,106
|
|
2
|
+
better_mem0_mcp/config.py,sha256=vgKLIw3jHyeBLTzzBnuHV5x6Nra0Rbav1IJRL8rLCuk,5576
|
|
3
|
+
better_mem0_mcp/graph.py,sha256=rE9z6XECiAktEqDNgmwqCpFpvKSn3azO9H4sRBhj8UU,6195
|
|
4
|
+
better_mem0_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
better_mem0_mcp/server.py,sha256=O6s0L1FggB9FDfX4OKF6govrRznwUIAh9RkFRCrYX3Y,5124
|
|
6
|
+
better_mem0_mcp/docs/memory.md,sha256=jqoxBYHVh2N9TZbt77qY5zhL1vSU-Ro-yuaczT1r7Mo,1126
|
|
7
|
+
better_mem0_mcp-1.1.2.dist-info/METADATA,sha256=-Ccmz2b162rXT7n0AnE6wbTRS2R1n3o7FG4vWOYWcZU,3871
|
|
8
|
+
better_mem0_mcp-1.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
9
|
+
better_mem0_mcp-1.1.2.dist-info/entry_points.txt,sha256=2b7E3D6yo94mQXP2Ms0bhUlWkK9f664f0GrstImOq30,57
|
|
10
|
+
better_mem0_mcp-1.1.2.dist-info/licenses/LICENSE,sha256=d7xQ6sRyeGus6gnvwgqiQtSY7XdFw0Jd0w5-Co_xHnk,1064
|
|
11
|
+
better_mem0_mcp-1.1.2.dist-info/RECORD,,
|
better_mem0_mcp/__main__.py
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
better_mem0_mcp/__init__.py,sha256=fcqgbz2HvMCPidqqoPvtRky5pGIHP2w9oVim7UQkuBc,106
|
|
2
|
-
better_mem0_mcp/__main__.py,sha256=IeeRidmZF4oBaamjQM6FUbhXpsSdE4sQF_6y_D2GEE4,116
|
|
3
|
-
better_mem0_mcp/config.py,sha256=cqLGzxYno7SgRMn7Y8GOBR0P4CrBuFjsmFpK6eGZhs0,5312
|
|
4
|
-
better_mem0_mcp/graph.py,sha256=rE9z6XECiAktEqDNgmwqCpFpvKSn3azO9H4sRBhj8UU,6195
|
|
5
|
-
better_mem0_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
better_mem0_mcp/server.py,sha256=QYLP46pz0U9gkxQKB_g8FMga77ywElMMjSCU-hGZQ-M,5499
|
|
7
|
-
better_mem0_mcp/docs/memory.md,sha256=198dDuAGccG5Ca7rhEXIU03ZhxNKK44B_Brl2glurGc,1608
|
|
8
|
-
better_mem0_mcp-1.1.0b22.dist-info/METADATA,sha256=GPpfk3pfbGIzWDVgHn6WdZ2G61sStge0k-EYUlrrUS8,4679
|
|
9
|
-
better_mem0_mcp-1.1.0b22.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
10
|
-
better_mem0_mcp-1.1.0b22.dist-info/entry_points.txt,sha256=2b7E3D6yo94mQXP2Ms0bhUlWkK9f664f0GrstImOq30,57
|
|
11
|
-
better_mem0_mcp-1.1.0b22.dist-info/licenses/LICENSE,sha256=d7xQ6sRyeGus6gnvwgqiQtSY7XdFw0Jd0w5-Co_xHnk,1064
|
|
12
|
-
better_mem0_mcp-1.1.0b22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|