tribalmemory 0.1.0__py3-none-any.whl → 0.1.1__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.
- tribalmemory/cli.py +53 -32
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/METADATA +61 -8
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/RECORD +7 -7
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/WHEEL +0 -0
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/entry_points.txt +0 -0
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {tribalmemory-0.1.0.dist-info → tribalmemory-0.1.1.dist-info}/top_level.txt +0 -0
tribalmemory/cli.py
CHANGED
|
@@ -26,7 +26,7 @@ TRIBAL_DIR = Path.home() / ".tribal-memory"
|
|
|
26
26
|
CONFIG_FILE = TRIBAL_DIR / "config.yaml"
|
|
27
27
|
DEFAULT_INSTANCE_ID = "default"
|
|
28
28
|
|
|
29
|
-
# MCP config for Claude Code
|
|
29
|
+
# MCP config for Claude Code CLI and Claude Desktop
|
|
30
30
|
CLAUDE_CODE_MCP_CONFIG = {
|
|
31
31
|
"mcpServers": {
|
|
32
32
|
"tribal-memory": {
|
|
@@ -135,54 +135,75 @@ def cmd_init(args: argparse.Namespace) -> int:
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
def _setup_claude_code_mcp(is_local: bool) -> None:
|
|
138
|
-
"""Add Tribal Memory to Claude Code's MCP configuration.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
"""Add Tribal Memory to Claude Code's MCP configuration.
|
|
139
|
+
|
|
140
|
+
Claude Code CLI reads MCP servers from ~/.claude.json (user scope).
|
|
141
|
+
Claude Desktop reads from platform-specific claude_desktop_config.json.
|
|
142
|
+
We update both if they exist, and always ensure ~/.claude.json is set.
|
|
143
|
+
"""
|
|
144
|
+
# Claude Code CLI config (primary — this is what `claude` CLI reads)
|
|
145
|
+
claude_cli_config = Path.home() / ".claude.json"
|
|
146
|
+
|
|
147
|
+
# Claude Desktop config paths (secondary — update if they exist)
|
|
148
|
+
claude_desktop_paths = [
|
|
149
|
+
Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json", # macOS
|
|
150
|
+
Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json", # Windows
|
|
151
|
+
Path.home() / ".claude" / "claude_desktop_config.json", # Legacy / Linux
|
|
144
152
|
]
|
|
145
153
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
mcp_entry = {
|
|
155
|
+
"command": "tribalmemory-mcp",
|
|
156
|
+
"env": {},
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if is_local:
|
|
160
|
+
mcp_entry["env"]["TRIBAL_MEMORY_EMBEDDING_API_BASE"] = "http://localhost:11434/v1"
|
|
161
|
+
|
|
162
|
+
# Always update Claude Code CLI config (~/.claude.json)
|
|
163
|
+
_update_mcp_config(claude_cli_config, mcp_entry, create_if_missing=True)
|
|
164
|
+
print(f"✅ Claude Code CLI config updated: {claude_cli_config}")
|
|
151
165
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
# Also update Claude Desktop config (create platform-appropriate path)
|
|
167
|
+
desktop_path = _get_claude_desktop_config_path()
|
|
168
|
+
_update_mcp_config(desktop_path, mcp_entry, create_if_missing=True)
|
|
169
|
+
print(f"✅ Claude Desktop config updated: {desktop_path}")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _get_claude_desktop_config_path() -> Path:
|
|
173
|
+
"""Get the platform-appropriate Claude Desktop config path."""
|
|
174
|
+
if sys.platform == "darwin":
|
|
175
|
+
return Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json"
|
|
176
|
+
elif sys.platform == "win32":
|
|
177
|
+
return Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json"
|
|
178
|
+
else:
|
|
179
|
+
return Path.home() / ".claude" / "claude_desktop_config.json"
|
|
156
180
|
|
|
157
|
-
|
|
181
|
+
|
|
182
|
+
def _update_mcp_config(
|
|
183
|
+
config_path: Path, mcp_entry: dict, create_if_missing: bool = False
|
|
184
|
+
) -> None:
|
|
185
|
+
"""Update an MCP config file with the tribal-memory server entry."""
|
|
158
186
|
if config_path.exists():
|
|
159
187
|
try:
|
|
160
188
|
existing = json.loads(config_path.read_text())
|
|
161
189
|
except json.JSONDecodeError as e:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
)
|
|
190
|
+
backup_path = config_path.with_suffix(".json.bak")
|
|
191
|
+
config_path.rename(backup_path)
|
|
192
|
+
print(f"⚠️ Existing config has invalid JSON: {e}")
|
|
193
|
+
print(f" Backed up to {backup_path}")
|
|
165
194
|
print(f" Creating fresh config at {config_path}")
|
|
166
195
|
existing = {}
|
|
167
|
-
|
|
196
|
+
elif create_if_missing:
|
|
197
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
168
198
|
existing = {}
|
|
199
|
+
else:
|
|
200
|
+
return
|
|
169
201
|
|
|
170
|
-
# Merge MCP server config
|
|
171
202
|
if "mcpServers" not in existing:
|
|
172
203
|
existing["mcpServers"] = {}
|
|
173
204
|
|
|
174
|
-
mcp_entry = {
|
|
175
|
-
"command": "tribalmemory-mcp",
|
|
176
|
-
"env": {},
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if is_local:
|
|
180
|
-
mcp_entry["env"]["TRIBAL_MEMORY_EMBEDDING_API_BASE"] = "http://localhost:11434/v1"
|
|
181
|
-
|
|
182
205
|
existing["mcpServers"]["tribal-memory"] = mcp_entry
|
|
183
|
-
|
|
184
206
|
config_path.write_text(json.dumps(existing, indent=2) + "\n")
|
|
185
|
-
print(f"✅ Claude Code MCP config updated: {config_path}")
|
|
186
207
|
|
|
187
208
|
|
|
188
209
|
def _setup_codex_mcp(is_local: bool) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tribalmemory
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Shared memory infrastructure for multi-instance AI agents
|
|
5
5
|
Author-email: Joe <joe@example.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -48,12 +48,48 @@ Dynamic: license-file
|
|
|
48
48
|
|
|
49
49
|
One memory store, many agents. Teach Claude Code something — Codex already knows it. That's not just persistence — it's **cross-agent intelligence**.
|
|
50
50
|
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="docs/assets/one-brain-two-agents.gif" alt="One Brain, Two Agents — Claude Code stores memories, Codex recalls them" width="700">
|
|
53
|
+
<br>
|
|
54
|
+
<em>Claude Code stores architecture decisions → Codex recalls them instantly</em>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
[](https://asciinema.org/a/ZM74iIXzM07SV21P)
|
|
58
|
+
[](https://pypi.org/project/tribalmemory/)
|
|
59
|
+
[](LICENSE)
|
|
60
|
+
|
|
51
61
|
## Why
|
|
52
62
|
|
|
53
63
|
Every AI coding assistant starts fresh. Claude Code doesn't know what you told Codex. Codex doesn't know what you told Claude. You repeat yourself constantly.
|
|
54
64
|
|
|
55
65
|
Tribal Memory is a shared memory server that any AI agent can connect to. Store a memory from one agent, recall it from another. It just works.
|
|
56
66
|
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
**macOS:**
|
|
70
|
+
```bash
|
|
71
|
+
# Install uv (https://docs.astral.sh/uv/)
|
|
72
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
73
|
+
|
|
74
|
+
# Restart your terminal, or run:
|
|
75
|
+
source ~/.zshrc
|
|
76
|
+
|
|
77
|
+
# Install tribalmemory
|
|
78
|
+
uv tool install tribalmemory
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> **Why uv?** macOS blocks `pip install` into the system Python with "externally-managed-environment" errors. `uv tool install` handles isolated environments automatically.
|
|
82
|
+
|
|
83
|
+
**Linux:**
|
|
84
|
+
```bash
|
|
85
|
+
pip install tribalmemory
|
|
86
|
+
|
|
87
|
+
# Or with uv:
|
|
88
|
+
# curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
89
|
+
# source ~/.bashrc
|
|
90
|
+
# uv tool install tribalmemory
|
|
91
|
+
```
|
|
92
|
+
|
|
57
93
|
## Quick Start
|
|
58
94
|
|
|
59
95
|
### Option A: Local Mode (Zero Cloud, Zero Cost)
|
|
@@ -61,8 +97,6 @@ Tribal Memory is a shared memory server that any AI agent can connect to. Store
|
|
|
61
97
|
No API keys. No cloud. Everything runs on your machine.
|
|
62
98
|
|
|
63
99
|
```bash
|
|
64
|
-
pip install tribalmemory
|
|
65
|
-
|
|
66
100
|
# Set up with local Ollama embeddings
|
|
67
101
|
tribalmemory init --local
|
|
68
102
|
|
|
@@ -76,8 +110,6 @@ tribalmemory serve
|
|
|
76
110
|
### Option B: OpenAI Embeddings
|
|
77
111
|
|
|
78
112
|
```bash
|
|
79
|
-
pip install tribalmemory
|
|
80
|
-
|
|
81
113
|
# Set up with OpenAI
|
|
82
114
|
export OPENAI_API_KEY=sk-...
|
|
83
115
|
tribalmemory init
|
|
@@ -224,19 +256,40 @@ await service.correct(
|
|
|
224
256
|
)
|
|
225
257
|
```
|
|
226
258
|
|
|
259
|
+
## Demo
|
|
260
|
+
|
|
261
|
+
See cross-agent memory sharing in action:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Start the server
|
|
265
|
+
tribalmemory serve
|
|
266
|
+
|
|
267
|
+
# Run the interactive demo
|
|
268
|
+
./demo.sh
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
See [docs/demo-output.md](docs/demo-output.md) for example output.
|
|
272
|
+
|
|
227
273
|
## HTTP API
|
|
228
274
|
|
|
275
|
+
All endpoints are under the `/v1` prefix.
|
|
276
|
+
|
|
229
277
|
```bash
|
|
230
278
|
# Store a memory
|
|
231
|
-
curl -X POST http://localhost:18790/
|
|
279
|
+
curl -X POST http://localhost:18790/v1/remember \
|
|
232
280
|
-H "Content-Type: application/json" \
|
|
233
281
|
-d '{"content": "The database uses Postgres 16", "tags": ["infra"]}'
|
|
234
282
|
|
|
235
283
|
# Search memories
|
|
236
|
-
curl
|
|
284
|
+
curl -X POST http://localhost:18790/v1/recall \
|
|
285
|
+
-H "Content-Type: application/json" \
|
|
286
|
+
-d '{"query": "what database", "limit": 5}'
|
|
237
287
|
|
|
238
288
|
# Get stats
|
|
239
|
-
curl http://localhost:18790/stats
|
|
289
|
+
curl http://localhost:18790/v1/stats
|
|
290
|
+
|
|
291
|
+
# Health check
|
|
292
|
+
curl http://localhost:18790/v1/health
|
|
240
293
|
```
|
|
241
294
|
|
|
242
295
|
## OpenClaw Integration
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
tribalmemory/__init__.py,sha256=DNgC_ZT0lrhxsPdhXu4oeG_UdrLstYQHeKwR-U2toeY,104
|
|
2
|
-
tribalmemory/cli.py,sha256=
|
|
2
|
+
tribalmemory/cli.py,sha256=1QDcRxBBNBm1ysUv06FgwMCBHMctdJyUARuy4y0XHSs,10292
|
|
3
3
|
tribalmemory/interfaces.py,sha256=W2BNYyYlY-RHTbnJn8-u1wbhfcUK5egzjUzrGexxyB0,9966
|
|
4
4
|
tribalmemory/utils.py,sha256=aei7xR6OVMGkllPySA2boeHyI3D1JsHTUX1YeaZdkMY,696
|
|
5
5
|
tribalmemory/a21/__init__.py,sha256=u1793uKzbWGKwiAVmCxEO9_3rdTL7QKTLhQQB8Umsl4,1181
|
|
@@ -43,9 +43,9 @@ tribalmemory/testing/fixtures.py,sha256=_zDyUVm6CQqXK1Us8CN6A95tJcmo1D7LFDktIvjO
|
|
|
43
43
|
tribalmemory/testing/metrics.py,sha256=X1n84dJDNQXsfGV-i-MzhsWKnFgqHWIcIaQB-BUp0e0,8711
|
|
44
44
|
tribalmemory/testing/mocks.py,sha256=sjLy-pq3D_T21rEvWWKM_bqw7xnchRPGLARZNfKkpGU,19788
|
|
45
45
|
tribalmemory/testing/semantic_expansions.py,sha256=AbbJIXYN4EJT8WKJ7UmIlNRlv63VejbcnbzBy2z2Ofk,2953
|
|
46
|
-
tribalmemory-0.1.
|
|
47
|
-
tribalmemory-0.1.
|
|
48
|
-
tribalmemory-0.1.
|
|
49
|
-
tribalmemory-0.1.
|
|
50
|
-
tribalmemory-0.1.
|
|
51
|
-
tribalmemory-0.1.
|
|
46
|
+
tribalmemory-0.1.1.dist-info/licenses/LICENSE,sha256=M8D9Xf3B6C6DFiCgAAhKcXeTscaC4cw1fhr3LHUrALU,10774
|
|
47
|
+
tribalmemory-0.1.1.dist-info/METADATA,sha256=IyhoTSK64QZKLTu0CjFRnmbfbvlkUGNtFNxvx2R21Ag,9239
|
|
48
|
+
tribalmemory-0.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
49
|
+
tribalmemory-0.1.1.dist-info/entry_points.txt,sha256=9Pep7JNCk9ifdFP4WbeCugDOjMrLVegGJ5iuvbcZ9e8,103
|
|
50
|
+
tribalmemory-0.1.1.dist-info/top_level.txt,sha256=kX36ZpH4W7EWcInV4MrIudicusdz5hfkezKMZ3HCMQs,13
|
|
51
|
+
tribalmemory-0.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|