# Tribal Memory

> Your AI tools don't share a brain. Tribal Memory gives them one.

One memory store, many agents. Teach Claude Code something — Codex already knows it. That's not just persistence — it's **cross-agent intelligence**.

<p align="center">
  <img src="docs/assets/one-brain-two-agents.gif" alt="One Brain, Two Agents — Claude Code stores memories, Codex recalls them" width="700">
  <br>
  <em>Claude Code stores architecture decisions → Codex recalls them instantly</em>
</p>

[![asciinema demo](https://img.shields.io/badge/demo-asciinema-d40000)](https://asciinema.org/a/ZM74iIXzM07SV21P)
[![PyPI](https://img.shields.io/pypi/v/tribalmemory)](https://pypi.org/project/tribalmemory/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)

## Why

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.

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.

## Install

**macOS:**
```bash
# Install uv (https://docs.astral.sh/uv/)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Restart your terminal, or run:
source ~/.zshrc

# Install tribalmemory
uv tool install tribalmemory
```

> **Why uv?** macOS blocks `pip install` into the system Python with "externally-managed-environment" errors. `uv tool install` handles isolated environments automatically.

**Linux:**
```bash
pip install tribalmemory

# Or with uv:
# curl -LsSf https://astral.sh/uv/install.sh | sh
# source ~/.bashrc
# uv tool install tribalmemory
```

## Quick Start

### Option A: Local Mode (Zero Cloud, Zero Cost)

No API keys. No cloud. Everything runs on your machine.

```bash
# Set up with local Ollama embeddings
tribalmemory init --local

# Pull an embedding model (one time)
ollama pull nomic-embed-text

# Start the server
tribalmemory serve
```

### Option B: OpenAI Embeddings

```bash
# Set up with OpenAI
export OPENAI_API_KEY=sk-...
tribalmemory init

# Start the server
tribalmemory serve
```

Server runs on `http://localhost:18790`.

## Claude Code Integration (MCP)

```bash
# Auto-configure Claude Code
tribalmemory init --local --claude-code

# Or manually add to your Claude Code MCP config:
```

```json
{
  "mcpServers": {
    "tribal-memory": {
      "command": "tribalmemory-mcp"
    }
  }
}
```

Now Claude Code has persistent memory across sessions:

```
You: Remember that the auth service uses JWT with RS256
Claude: ✅ Stored.

--- next session ---

You: How does the auth service work?
Claude: Based on my memory, the auth service uses JWT with RS256...
```

## Architecture

```
┌─────────────┐
│  Claude Code │──── MCP ────┐
└─────────────┘              │
┌─────────────┐              ▼
│  Codex CLI   │──── MCP ───► Tribal Memory Server
└─────────────┘              ▲  (localhost:18790)
┌─────────────┐              │
│  OpenClaw    │── plugin ───┘
└─────────────┘
```

The server is the single source of truth. Each agent connects as an instance. Memories are tagged with `source_instance` so you can see *who* learned *what*.

## Features

- **Semantic search** — Find memories by meaning, not keywords
- **Cross-agent sharing** — Memories from one agent are available to all
- **Automatic deduplication** — Won't store the same thing twice
- **Memory corrections** — Update outdated information with audit trail
- **Import/export** — Portable JSON bundles with embedding metadata
- **Token budgets** — Smart context management to avoid LLM overload
- **Local-only mode** — Ollama + LanceDB = zero data leaves your machine
- **MCP server** — Native integration with Claude Code and compatible tools

## MCP Tools

When connected via MCP, your AI gets these tools:

| Tool | Description |
|------|-------------|
| `tribal_remember` | Store a new memory with deduplication |
| `tribal_recall` | Search memories by semantic similarity |
| `tribal_correct` | Update/correct an existing memory |
| `tribal_forget` | Delete a memory (soft delete) |
| `tribal_stats` | Get memory statistics |
| `tribal_export` | Export memories to portable JSON |
| `tribal_import` | Import memories from a bundle |

## Configuration

Generated by `tribalmemory init`. Lives at `~/.tribal-memory/config.yaml`:

```yaml
instance_id: my-agent

embedding:
  provider: openai
  model: nomic-embed-text        # or text-embedding-3-small
  api_base: http://localhost:11434/v1  # Ollama (omit for OpenAI)
  dimensions: 768                # 768 for nomic, 1536 for OpenAI
  # api_key not needed for local Ollama

db:
  provider: lancedb
  path: ~/.tribal-memory/lancedb

server:
  host: 127.0.0.1
  port: 18790
```

### Environment Variables

| Variable | Description |
|----------|-------------|
| `OPENAI_API_KEY` | OpenAI API key (not needed for local mode) |
| `TRIBAL_MEMORY_CONFIG` | Path to config file (default: `~/.tribal-memory/config.yaml`) |
| `TRIBAL_MEMORY_INSTANCE_ID` | Override instance ID |
| `TRIBAL_MEMORY_EMBEDDING_API_BASE` | Override embedding API base URL |

## Python API

```python
from tribalmemory.services import create_memory_service

# Local embeddings
service = create_memory_service(
    instance_id="my-agent",
    db_path="./memories",
    api_base="http://localhost:11434/v1",
    embedding_model="nomic-embed-text",
    embedding_dimensions=768,
)

# Store
result = await service.remember(
    "User prefers TypeScript for web projects",
    tags=["preference", "coding"]
)

# Recall
results = await service.recall("What language for web?")
for r in results:
    print(f"{r.similarity_score:.2f}: {r.memory.content}")

# Correct
await service.correct(
    original_id=result.memory_id,
    corrected_content="User prefers TypeScript for web, Python for scripts"
)
```

## Demo

See cross-agent memory sharing in action:

```bash
# Start the server
tribalmemory serve

# Run the interactive demo
./demo.sh
```

See [docs/demo-output.md](docs/demo-output.md) for example output.

## HTTP API

All endpoints are under the `/v1` prefix.

```bash
# Store a memory
curl -X POST http://localhost:18790/v1/remember \
  -H "Content-Type: application/json" \
  -d '{"content": "The database uses Postgres 16", "tags": ["infra"]}'

# Search memories
curl -X POST http://localhost:18790/v1/recall \
  -H "Content-Type: application/json" \
  -d '{"query": "what database", "limit": 5}'

# Get stats
curl http://localhost:18790/v1/stats

# Health check
curl http://localhost:18790/v1/health
```

## OpenClaw Integration

Tribal Memory includes a plugin for [OpenClaw](https://github.com/openclaw/openclaw):

```bash
openclaw plugins install ./extensions/memory-tribal
openclaw config set plugins.slots.memory=memory-tribal
```

## Development

```bash
git clone https://github.com/abbudjoe/TribalMemory.git
cd TribalMemory
pip install -e ".[dev]"

# Run tests
PYTHONPATH=src pytest

# Run linting
ruff check .
black --check .
```

## Privacy

In local mode (Ollama + LanceDB), **zero data leaves your machine**:
- Embeddings computed locally by Ollama
- Memories stored locally in LanceDB
- No API keys, no cloud services, no telemetry

## License

Apache 2.0 — see [LICENSE](LICENSE)
