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 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 (claude_desktop_config.json)
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
- # Claude Code MCP config paths by platform
140
- claude_config_paths = [
141
- Path.home() / ".claude" / "claude_desktop_config.json", # Claude Code CLI (all platforms)
142
- Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json", # Claude Desktop (macOS)
143
- Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json", # Claude Desktop (Windows)
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
- config_path = None
147
- for p in claude_config_paths:
148
- if p.exists():
149
- config_path = p
150
- break
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
- if config_path is None:
153
- # Create default location
154
- config_path = claude_config_paths[0]
155
- config_path.parent.mkdir(parents=True, exist_ok=True)
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
- # Read existing config or start fresh
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
- print(
163
- f"⚠️ Existing config has invalid JSON: {e}"
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
- else:
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.0
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
+ [![asciinema demo](https://img.shields.io/badge/demo-asciinema-d40000)](https://asciinema.org/a/ZM74iIXzM07SV21P)
58
+ [![PyPI](https://img.shields.io/pypi/v/tribalmemory)](https://pypi.org/project/tribalmemory/)
59
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](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/memories \
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 "http://localhost:18790/memories/search?query=what+database&limit=5"
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=QYpHt0E-hRWK35YttlJks-xuV6kDfc6O4FrxChvZaxU,9043
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.0.dist-info/licenses/LICENSE,sha256=M8D9Xf3B6C6DFiCgAAhKcXeTscaC4cw1fhr3LHUrALU,10774
47
- tribalmemory-0.1.0.dist-info/METADATA,sha256=l-vV4rYIt3WFbe6Jbtzot4fZ3yTuzQA_yEXcmzdVJXs,7804
48
- tribalmemory-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
49
- tribalmemory-0.1.0.dist-info/entry_points.txt,sha256=9Pep7JNCk9ifdFP4WbeCugDOjMrLVegGJ5iuvbcZ9e8,103
50
- tribalmemory-0.1.0.dist-info/top_level.txt,sha256=kX36ZpH4W7EWcInV4MrIudicusdz5hfkezKMZ3HCMQs,13
51
- tribalmemory-0.1.0.dist-info/RECORD,,
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,,