# Integrations Guide

How to connect the cognitive memory system to your LLM setup. There are multiple integration paths depending on your environment.

## Autoassociative vs. Manual Memory

The key distinction:

- **Autoassociative (fully automatic)**: The memory system passively monitors all conversation turns — both user messages and LLM responses — and automatically surfaces relevant memories without anyone deciding to "look something up." This is the core thesis of the project. **Every integration path supports autoassociative memory except MCP tools.**

- **MCP tools (semi-automatic)**: The LLM has access to `memory_recall` and `memory_store` tools and decides when to use them. This is better than no memory, but the LLM must actively choose to remember and retrieve. This is the only option for environments that don't support hooks or middleware wrapping (e.g., Claude Desktop without hooks).

## Integration Paths

### 1. HTTP Memory Server — Any Language, Any LLM (Autoassociative)

**`integrations/claude-code/memory_server.py`**

The memory server is a lightweight HTTP API that any programming language can call. It maintains the full cognitive memory pipeline (FAISS index, entity index, decay, priming, working memory) in-process.

**Endpoints:**

| Method | Endpoint | Description |
|---|---|---|
| **Core** | | |
| `POST` | `/ingest` | Store a message: `{"role": "user", "content": "...", "agent_id": "..."}` |
| `POST` | `/recall` | Search memory: `{"query": "...", "top_k": 5, "agent_id": "..."}` |
| `POST` | `/ingest_and_recall` | Ingest + recall in one call (for hooks) |
| **CRUD** | | |
| `GET` | `/memory/{id}` | Get a single memory by ID |
| `PUT` | `/memory/{id}` | Update a memory's gist, tags, or importance |
| `DELETE` | `/memory/{id}` | Delete a single memory |
| `DELETE` | `/memories/agent/{agent_id}` | Delete all memories from a specific agent |
| `GET` | `/memories?agent_id=X&limit=50` | List memories (filterable, newest first) |
| **Management** | | |
| `POST` | `/save` | Save memory to disk |
| `POST` | `/consolidate` | Run nightly consolidation |
| `POST` | `/contradictions` | Detect cross-agent contradictions |
| `POST` | `/merge` | Merge a local agent's memory store into central |
| `POST` | `/end_of_day` | Full nightly workflow: consolidate + maintain + save |
| `GET` | `/health` | Memory system health check |
| `GET` | `/stats` | Per-agent memory counts |

All endpoints accept optional `agent_id` and `session_id` fields for multi-agent use.

**To get autoassociative memory, wrap your LLM calls:**

```
1. User sends message
2. POST /ingest_and_recall with user message → get recalled memories
3. Prepend recalled memories to LLM prompt
4. Send augmented prompt to LLM → get response
5. POST /ingest with LLM response (role: "assistant")
6. Return response to user
```

This pattern works with **any LLM in any language**. If your code can make HTTP requests and call an LLM API, you have autoassociative memory. Recalled memories are clearly framed as "from memory, not current user input" so the LLM doesn't confuse them with the active conversation.

**Start the server:**
```bash
# Single user, no persistence
python -m integrations.claude-code.memory_server

# With persistence (survives restarts)
python -m integrations.claude-code.memory_server --data-dir ./memory_data

# Multi-agent team (network-accessible, auto-save every 5 min)
python -m integrations.claude-code.memory_server --host 0.0.0.0 --data-dir ./memory_data --auto-save 300
```

**Example (any language):**
```bash
# Store a memory
curl -X POST http://localhost:7832/ingest \
  -H "Content-Type: application/json" \
  -d '{"role": "user", "content": "I am allergic to peanuts."}'

# Recall memories
curl -X POST http://localhost:7832/recall \
  -H "Content-Type: application/json" \
  -d '{"query": "ordering food for the team"}'
```

---

### 2. Claude Code Hooks — Zero-Config Autoassociative (Autoassociative)

**`integrations/claude-code/hooks/`**

For Claude Code (CLI or Desktop app) users. Hooks fire automatically on every user message and every assistant response — no code changes, no tool calls, no decisions.

**How it works:**
```
User types message
  → UserPromptSubmit hook fires
  → Hook calls memory server: ingest + recall
  → Recalled memories injected as additionalContext
  → Claude sees: user message + recalled memories
  → Claude responds
  → Stop hook fires
  → Hook calls memory server: ingest assistant response
  → Both sides of conversation stored automatically
```

**Setup:**

1. Start the memory server: `python -m integrations.claude-code.memory_server`
2. Add hooks to Claude Code settings — see `integrations/claude-code/README.md`
3. Use Claude Code normally. Memory happens automatically.

---

### 3. Python Middleware — Wrap Any LLM API Call (Autoassociative)

**`integrations/middleware.py`**

For Python developers building applications with LLM APIs. Wraps any OpenAI-compatible or Anthropic API call with automatic memory.

```python
from integrations.middleware import MemoryMiddleware

# With OpenAI or any OpenAI-compatible API
mw = MemoryMiddleware(api_type="openai", api_key="sk-...")
response = mw.chat("I'm allergic to peanuts.")
response = mw.chat("Order lunch for the team.")
# ^ Automatically recalls the peanut allergy

# With Anthropic
mw = MemoryMiddleware(api_type="anthropic")
response = mw.chat("My project deadline is April 15th.")

# With any OpenAI-compatible endpoint (Together, Groq, vLLM, LM Studio)
mw = MemoryMiddleware(
    api_type="openai",
    base_url="https://api.together.xyz/v1",
    model="meta-llama/Llama-3-8b-chat-hf",
    api_key="...",
)
```

Every `mw.chat()` call automatically:
1. Ingests the user message into memory
2. Recalls relevant memories and injects them into the prompt
3. Sends the augmented prompt to the LLM
4. Ingests the LLM response into memory
5. Returns the response

**Think-out-loud mode**: capture the LLM's reasoning as THOUGHT memories.

```python
mw = MemoryMiddleware(api_type="anthropic", think_out_loud=True)
response = mw.chat("Debug this CSV parser issue.")
# LLM's <thinking>...</thinking> block is stored as a THOUGHT memory
# and stripped from the returned response.
```

---

### 4. MCP Server — For MCP-Compatible Clients (Semi-Automatic)

**`integrations/mcp/server.py`**

For Claude Desktop, Cursor, Windsurf, and any MCP-compatible application. The LLM sees memory tools and can choose to use them.

**This is the only integration that is NOT fully autoassociative** — the LLM must decide to call `memory_recall` or `memory_store`. However, well-prompted LLMs will use these tools naturally.

**Tools exposed:**

| Tool | Description |
|---|---|
| `memory_recall(query)` | Search memory for relevant information |
| `memory_store(content)` | Store new information in memory |
| `memory_recall_with_confidence(query)` | Search with metamemory confidence levels |
| `memory_status()` | Check memory system health |
| `memory_consolidate()` | Trigger episodic → semantic consolidation |

**Configure in Claude Desktop (`claude_desktop_config.json`):**
```json
{
  "mcpServers": {
    "cognitive-memory": {
      "command": "python",
      "args": ["-m", "integrations.mcp.server"],
      "cwd": "/path/to/cognitive-memory-model",
      "env": {}
    }
  }
}
```

---

### 5. Direct Python Library — Full Control (Autoassociative)

For developers who want direct access to the pipeline API:

```python
from cmm.pipeline.conversation import CognitiveMemoryPipeline

pipeline = CognitiveMemoryPipeline()

# Ingest turns (returns recalled memories)
results = pipeline.ingest("user", "I saw a zebra at the zoo today.")
results = pipeline.ingest("assistant", "Zebras are fascinating animals!")

# Recall without storing
results = pipeline.recall("tell me about the zebra")
context = pipeline.format_recalled(results)

# Recall with metamemory (confidence + partial matches)
meta = pipeline.recall_with_metamemory("something about a striped animal")

# End session (creates session summary)
pipeline.end_session()

# Run consolidation (episodic → semantic)
pipeline.consolidate()

# Maintenance (prune + deduplicate)
pipeline.maintain()
```

---

## Gist Encoder Options

The gist encoder compresses conversation turns into summaries. Choose based on what you have available:

| Encoder | Requires | Best For |
|---|---|---|
| `OllamaGistEncoder` | Local Ollama server | Privacy-first, free, no API key needed |
| `OpenAIGistEncoder` | OpenAI API key (or any compatible API) | Broadest compatibility |
| `AnthropicGistEncoder` | Anthropic API key | Claude users |
| `PassthroughGistEncoder` | Nothing | Testing, minimal setup, embedding-only |

```python
from cmm.encoding.ollama_gist_encoder import OllamaGistEncoder
from cmm.encoding.openai_gist_encoder import OpenAIGistEncoder
from cmm.encoding.anthropic_gist_encoder import AnthropicGistEncoder
from cmm.encoding.gist_encoder import PassthroughGistEncoder

# Use any encoder with the pipeline:
pipeline = CognitiveMemoryPipeline(gist_encoder=OpenAIGistEncoder(api_key="sk-..."))
```

---

## Multi-Agent Team Workflow

For teams with multiple developers, each with their own AI agents:

### Daily Workflow

1. **Morning**: Each agent starts fresh and loads the consolidated central store.
2. **During the day**: Each agent writes to their own local memory store (fast, no contention). All agents also read from the central store for recall.
3. **End of day**: Each agent's local store is merged into the central store via `POST /merge` or `POST /end_of_day`.
4. **Overnight**: Nightly consolidation runs — clustering episodic memories into semantic memories, deduplication, pruning, and contradiction detection.
5. **Next morning**: Agents load the freshly consolidated central store.

### Setup

```bash
# Start the central server (accessible to all agents on the network)
python -m integrations.claude-code.memory_server \
    --host 0.0.0.0 --port 7832 \
    --data-dir /shared/team-memory \
    --auto-save 300

# Each agent includes their agent_id in requests
curl -X POST http://memory-server:7832/ingest_and_recall \
    -d '{"agent_id": "alice-agent-1", "session_id": "sprint-14", "role": "user", "content": "..."}'

# End of day: run the full nightly workflow
curl -X POST http://memory-server:7832/end_of_day -d '{}'
```

### Contradiction Detection

When agents submit conflicting information, the system flags it with agent attribution:

```bash
curl -X POST http://memory-server:7832/contradictions -d '{"threshold": 0.7}'
# Returns: who said what, so the team can investigate
```

---

## Summary: Which Integration Should I Use?

| I want to... | Use this | Autoassociative? |
|---|---|---|
| Add memory to Claude Code | Claude Code Hooks | Yes |
| Add memory to any Claude Desktop / Cursor project | MCP Server | Semi (tool-based) |
| Build a Python app with memory | Python Middleware or Direct Library | Yes |
| Build a non-Python app with memory | HTTP Memory Server | Yes |
| Run a multi-agent team with shared memory | HTTP Memory Server (networked) | Yes |
| Just try it out quickly | Direct Python Library | Yes |

---

## Memory Editing and Management

Memories are stored in a database like any other data — they can be read, updated, and deleted through the CRUD endpoints.

**View a memory:**
```bash
curl http://localhost:7832/memory/42
```

**Update a memory** (fix wrong information):
```bash
curl -X PUT http://localhost:7832/memory/42 \
    -d '{"gist": "The API rate limit is 480 req/min (confirmed by load test)", "importance": 2.0}'
```

**Delete a memory:**
```bash
curl -X DELETE http://localhost:7832/memory/42
```

**Delete all memories from a specific agent** (e.g., an agent that was hallucinating):
```bash
curl -X DELETE http://localhost:7832/memories/agent/agent-47
```

**List recent memories** (for auditing):
```bash
curl "http://localhost:7832/memories?limit=20"
curl "http://localhost:7832/memories?agent_id=agent-47&limit=50"
```

---

## Production Deployment: Authentication and Access Control

The memory server is a plain HTTP API with **no built-in authentication**. This is intentional — every team has different auth infrastructure (OAuth, LDAP, API keys, IAM roles, etc.).

**For production deployments with multi-agent teams, you MUST put an authentication layer in front of the memory server.** Without it, anyone who can reach the server can read, write, or delete memories.

### Recommended Architecture

```
Agents / Users
      │
      ▼
┌──────────────┐
│ Auth Proxy   │  nginx, API gateway, or your own middleware
│ (you provide)│  — authenticates requests
│              │  — enforces role-based access
│              │  — logs all operations for audit
└──────┬───────┘
       │
       ▼
┌──────────────┐
│ CMM Memory   │  binds to 127.0.0.1 (not exposed directly)
│ Server       │
└──────────────┘
```

### Example with nginx

```nginx
server {
    listen 443 ssl;
    server_name memory.internal.company.com;

    # Your auth (e.g., OAuth2 proxy, mTLS, API key header check)
    auth_request /auth;

    location / {
        proxy_pass http://127.0.0.1:7832;
    }
}
```

### Access Control Recommendations

| Role | Allowed Operations |
|---|---|
| **Agent (read/write)** | `/ingest`, `/recall`, `/ingest_and_recall` |
| **Agent (read-only)** | `/recall`, `/memory/{id}`, `/memories`, `/health` |
| **Team admin** | All of the above + `/consolidate`, `/end_of_day`, `/save` |
| **System admin** | All of the above + `DELETE` endpoints, `/merge` |

### Audit Trail

Every memory includes `agent_id` and `session_id` metadata, so you always know who created what. The HTTP server logs all requests. For full audit logging, configure your auth proxy to log request bodies.

### Data Backup

The `--data-dir` directory contains three files: `faiss.index`, `memories.json`, and `entities.json`. Back these up regularly. The memory server saves automatically on shutdown and optionally at intervals (`--auto-save`).
