Metadata-Version: 2.4
Name: waggle-mcp
Version: 0.1.11
Summary: MCP server that gives LLMs persistent graph-structured memory
Author: Abhigyan Shekhar
License: MIT
Project-URL: Homepage, https://github.com/Abhigyan-Shekhar/Waggle-mcp
Project-URL: Repository, https://github.com/Abhigyan-Shekhar/Waggle-mcp
Project-URL: Documentation, https://github.com/Abhigyan-Shekhar/Waggle-mcp#readme
Project-URL: Bug Tracker, https://github.com/Abhigyan-Shekhar/Waggle-mcp/issues
Project-URL: Changelog, https://pypi.org/project/waggle-mcp/#history
Keywords: mcp,knowledge-graph,memory,llm,context
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: anyio>=4.4.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: networkx>=3.2.1
Requires-Dist: numpy>=1.26.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: python-louvain>=0.16
Requires-Dist: pyvis>=0.3.2
Requires-Dist: sentence-transformers>=2.6.0
Requires-Dist: starlette>=0.37.2
Requires-Dist: uvicorn>=0.30.0
Provides-Extra: dev
Requires-Dist: httpx>=0.27.0; extra == "dev"
Requires-Dist: pytest>=8.2.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.7; extra == "dev"
Provides-Extra: neo4j
Requires-Dist: neo4j>=5.20.0; extra == "neo4j"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/Abhigyan-Shekhar/graph-memory-mcp/main/assets/banner.png" alt="waggle-mcp" width="720"/>
</p>

<!-- mcp-name: io.github.Abhigyan-Shekhar/Waggle-mcp -->

<p align="center">
  <strong>Your AI forgets everything between sessions. Waggle gives it a graph-backed brain.</strong><br/>
  Persistent, structured memory for AI agents — in the checked-in comparison snapshot, about 2.6× fewer tokens on factual lookups.
</p>

<p align="center">
  <em>Waggle is not a code indexer. It's a conversational memory engine — it remembers what you decided, why, and what changed, across every session.</em>
</p>

<p align="center">
  <a href="https://pypi.org/project/waggle-mcp"><img src="https://img.shields.io/pypi/v/waggle-mcp?color=39d5cf&label=pypi" alt="PyPI"/></a>
  <img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+"/>
  <img src="https://img.shields.io/badge/MCP-compatible-brightgreen" alt="MCP compatible"/>
  <img src="https://img.shields.io/badge/embeddings-local%2C%20no%20API%20key-orange" alt="Local embeddings"/>
  <img src="https://img.shields.io/badge/license-MIT-lightgrey" alt="MIT"/>
</p>

<p align="center">
  <a href="https://glama.ai/mcp/servers/Abhigyan-Shekhar/Waggle-mcp"><img src="https://glama.ai/mcp/servers/Abhigyan-Shekhar/Waggle-mcp/badges/card.svg" alt="Waggle-mcp MCP server"/></a>
  <a href="https://glama.ai/mcp/servers/Abhigyan-Shekhar/Waggle-mcp"><img src="https://glama.ai/mcp/servers/Abhigyan-Shekhar/Waggle-mcp/badges/score.svg" alt="Waggle-mcp MCP server score"/></a>
</p>

---

## Demo First

The quickest way to understand Waggle is to run the feature demo and the smoke test:

- [`tests/artifacts/test-run/comprehensive_feature_demo.md`](./tests/artifacts/test-run/comprehensive_feature_demo.md)
- [`scripts/smoke_test_mcp.py`](./scripts/smoke_test_mcp.py)
- [`waggle-mcp features`](#cli-command-reference)

That demo exercises the full MCP surface: graph ingestion, retrieval, conflict handling, export/import, and graph inspection.

## Who It's For

**→ Individual developer** extending Claude, Codex, Cursor, or Antigravity with persistent memory:
Use Python 3.11+ and install via `pipx` (no venv activation needed):
`brew install pipx && pipx ensurepath && pipx install waggle-mcp && waggle-mcp init`.
SQLite + local embeddings, zero infra.

**→ Team sharing a canonical project memory across multiple agents and developers:** Waggle ships with a Docker image, Kubernetes manifests, Prometheus metrics, and multi-tenant auth. See [deploy/kubernetes/](./deploy/kubernetes/) and [docs/runbooks/](./docs/runbooks/).

Both paths share the same MCP tool surface — the difference is only the backend and transport.

---

## Why Waggle

`waggle-mcp` is a local-first memory layer for MCP-compatible AI clients, built on a persistent knowledge graph.

| Stuffed context | Structured retrieval |
|-----------------|----------------------|
| Huge prompts every session | Compact subgraph retrieved at query time |
| Session-local memory | Persistent multi-session memory |
| Flat notes and chunks | Typed nodes and edges: decisions, reasons, contradictions |
| "What changed?" requires replaying logs | Temporal queries and diffs are first-class |

Waggle often uses materially fewer tokens than naive chunked retrieval on factual lookups, while graph-traversal queries intentionally spend more context to include reasoning chains such as updates, contradictions, and dependencies.

---

## Architecture

```mermaid
flowchart LR
  C["MCP Client\n(Claude/Cursor/Codex/Antigravity)"] --> S["waggle.server\nMCP tool surface"]
  S --> G["Graph Engine\nMemoryGraph / Neo4jMemoryGraph"]
  G --> DB["SQLite (local default)\nor Neo4j (service mode)"]
  G --> E["Embeddings\n(sentence-transformers or deterministic fallback)"]
```

---

## Quick start (Recommended)

The simplest way to use Waggle is via `pipx`. This installs the package in an isolated environment and makes the `waggle-mcp` command available globally **without needing to manage a virtual environment (`.venv`) manually**.

```bash
# 1. Install waggle globally
pipx install waggle-mcp

# 2. Run the interactive setup
waggle-mcp init
```
*(If you don't have `pipx`, install it via `brew install pipx && pipx ensurepath`.)*

Running `init` will detect your MCP client (Codex, Claude, Cursor, or Antigravity), write the necessary configuration, and initialize your local database. Restart your client, and you're ready to go.

For Codex, `waggle-mcp init` also writes a managed Waggle block into `AGENTS.md` in the current workspace so automatic memory is enabled by default for that repo.

Manual MCP setup examples for **Codex**, **Claude Code**, **Cursor**, and **Antigravity** are in [docs/reference.md](./docs/reference.md#manual-client-configuration).

Comprehensive live feature run (full tool surface, multi-query graph tests, export/import validation):
[`tests/artifacts/test-run/comprehensive_feature_demo.md`](./tests/artifacts/test-run/comprehensive_feature_demo.md)

> **Best entry point:** if you do nothing else, run `waggle-mcp features` to get the tool map, workflows, and setup hints in one place.

> **⚠️ Edges are what make graph memory work.**
> `observe_conversation` and `decompose_and_store` create edges automatically.
> If you only call `store_node`, you get isolated facts — not a connected graph.
> Always prefer `observe_conversation` for conversational ingestion.

---

## Setting Up waggle as an MCP Server

> **One-time install:** `pipx install waggle-mcp` (requires Python 3.11+; recommended on macOS/Homebrew Python) — no API key, no cloud account, no Docker required for local use.

Use this shared JSON config shape for clients that accept `mcpServers` JSON (recommended when installed via `pipx`):

```json
{
  "mcpServers": {
    "waggle": {
      "command": "waggle-mcp",
      "args": ["serve"],
      "env": {
        "WAGGLE_TRANSPORT": "stdio",
        "WAGGLE_BACKEND": "sqlite",
        "WAGGLE_DB_PATH": "~/.waggle/memory.db",
        "WAGGLE_DEFAULT_TENANT_ID": "local-default",
        "WAGGLE_MODEL": "all-MiniLM-L6-v2"
      }
    }
  }
}
```

<details>
<summary>Claude Desktop / Antigravity / Cursor / Claude Code setup details</summary>

**Claude Desktop config file location**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

**Antigravity**
- Open agent panel → `···` → **Manage MCP Servers** → **View raw config**
- Paste the same JSON block above.

**Cursor**
- `Cursor Settings -> Features -> MCP Servers -> + Add`
- Command: `waggle-mcp`
- Args: `serve`
- Env vars: same keys as the JSON block above.

**Claude Code**
```bash
claude mcp add waggle \
  --env WAGGLE_TRANSPORT=stdio \
  --env WAGGLE_BACKEND=sqlite \
  --env WAGGLE_DB_PATH=~/.waggle/memory.db \
  --env WAGGLE_DEFAULT_TENANT_ID=local-default \
  --env WAGGLE_MODEL=all-MiniLM-L6-v2 \
  -- waggle-mcp serve
```

</details>

### Codex

Add to `~/.codex/config.toml`:

```toml
[mcp_servers.waggle]
command = "waggle-mcp"
args    = ["serve"]
env     = {
  WAGGLE_TRANSPORT         = "stdio",
  WAGGLE_BACKEND           = "sqlite",
  WAGGLE_DB_PATH           = "~/.waggle/memory.db",
  WAGGLE_DEFAULT_TENANT_ID = "local-default",
  WAGGLE_MODEL             = "all-MiniLM-L6-v2"
}
```

A live-source development example is included in [codex_config.example.toml](./codex_config.example.toml).

### `waggle-mcp` not on PATH?

If you installed with `pipx`, ensure its bin path is available:

```bash
pipx ensurepath
```

Then restart your terminal/client. If you're using a venv-based install, use the venv interpreter path instead of `waggle-mcp`:

```bash
which python3   # macOS / Linux
where python    # Windows
```

e.g. `/usr/local/bin/python3` or `C:\Python311\python.exe`.

### Verify it works

After restarting your client, ask the agent:

> *"Store a note: we're using PostgreSQL for this project."*

Then open a **fresh session** and ask:

> *"What database are we using?"*

Expected result (example):

```text
You're using PostgreSQL for this project.
```

If you see that kind of recall in a new session, you're live.

### What To Ask The Agent

| Ask the agent... | Tool called |
|---|---|
| "Remember that..." | `observe_conversation` |
| "What do you know about X?" | `query_graph` |
| "What changed recently?" | `graph_diff` |
| "Summarize context for a new session" | `prime_context` |
| "Show all stored topics" | `get_topics` |
| "Export my memory to a file" | `export_graph_backup` |

<details>
<summary>What's New — v0.1.9</summary>

- `waggle-mcp ingest-transcript-handoff` ingests ordered transcripts, deduplicates by `message_identity`, and exports a session-scoped handoff bundle.
- Append-only reruns avoid reprocessing completed turns while still finishing a trailing `user` block when the matching `assistant` arrives later.
- Batch ingestion keeps evidence turn indices aligned with stored transcript rows, including tool/system-interleaved sessions.
- Handoff export failures now surface as real CLI failures instead of being downgraded into `export_skipped`.
- The repo includes an end-to-end benchmark harness, LongMemEval artifacts, observability assets, and runbooks.

</details>

## Automatic Memory Setup For Codex And Antigravity

Registering Waggle as an MCP server is necessary, but it is not sufficient for automatic cross-session memory. The client still needs instructions telling the agent to use Waggle in the background.

`waggle-mcp init` now does this automatically for Codex by writing a managed Waggle memory block to the workspace `AGENTS.md`. Other clients still need their equivalent instruction layer.

There is not a better generic repo-side mechanism for third-party MCP clients today. If the client does not provide a runtime hook that automatically calls memory tools, the practical setup is:
- register Waggle as an MCP server
- add an agent instruction / User Rule telling the model when to call Waggle

If a client later exposes a native pre-answer / post-turn orchestration hook, that is better than prompt rules. Until then, prompt-level rules are the portable solution across Codex and Antigravity.

For product integrations, the preferred path is the event-driven runtime in [docs/memory-orchestration.md](./docs/memory-orchestration.md): call `build_context(...)` before each answer and `on_assistant_turn(...)` after each completed turn. MCP tool exposure alone does not make memory automatic.

Use the same rule text in:
- **Codex**: your global/project instructions or equivalent agent rule layer
- **Antigravity**: **User Rules** / custom instructions for the agent

A copy-pasteable version also lives in [docs/automatic-memory-rules.md](./docs/automatic-memory-rules.md).

Recommended rule text:

```text
Use Waggle automatically for conversational memory.

At the start of a new session, if project, agent, or session scope is known, call prime_context.

Before answering questions that may depend on prior decisions, preferences, constraints, project state, or earlier conversation context, call query_graph with the narrowest relevant scope.

After completed turns that contain durable information such as decisions, preferences, constraints, requirements, user corrections, project facts, or meaningful task outcomes, call observe_conversation automatically.

Waggle should remember relevant context automatically. If memory appears empty, the session is likely missing the automatic memory policy or the runtime hooks that call build_context before answers and on_assistant_turn after answers.

Do not ask the user to trigger Waggle manually. Use it in the background when relevant.
```

### Important Findings

- **MCP registration alone does not create automatic memory.** If the client only exposes Waggle as a tool, cross-session recall can still fail.
- **Scope must match across sessions.** Store and recall need to use the same database, tenant, and relevant scope such as `project`.
- **Rollover handoff is separate from live-turn memory.** `ingest-transcript-handoff` fixes end-of-window/session import and export. Live conversational memory still depends on automatic `observe_conversation` and `query_graph` usage during normal chats.
- **For same-machine multi-client sharing, use the same `WAGGLE_DB_PATH`.** Codex and Antigravity can share one local brain if both point to the same SQLite file.

For the full tool surface and environment variable reference see [docs/reference.md](./docs/reference.md).

---

## CLI Command Reference

Waggle includes a built-in CLI for setup, maintenance, and learning the memory system.

| Command | Description |
|---|---|
| `waggle-mcp --help` | Show all available commands, options, and usage examples. |
| `waggle-mcp features` | **Best first command** — Explain the main tools, graph workflows, and how connected context reaches the model. |
| `waggle-mcp init` | Interactive setup wizard to configure Codex, Claude, Cursor, or Antigravity. |
| `waggle-mcp serve` | Run the MCP server (usually started automatically by your client). |
| `waggle-mcp ingest-transcript-handoff` | Ingest a rollover transcript and export a handoff bundle for the next window or IDE. |
| `waggle-mcp export-context-bundle` | Export a portable Markdown/JSON context pack for another AI. |
| `waggle-mcp export-markdown-vault` | Export your memory graph as an Obsidian-style vault. |

For advanced commands (tenant management, API keys, Neo4j migration), see the full help output:
```bash
waggle-mcp --help
```

---

## Cross-Client Handoffs & Migration

Waggle is designed to be a "portable brain" for your AI sessions. Whether you are switching editors (e.g., Antigravity to Codex) or moving across machines, your memory can follow you.

### 1. Automatic Sharing (Same Machine)
If you run multiple MCP clients (like Codex and Antigravity) on the same machine, they can share a single "brain" automatically. 
*   **How:** Ensure both clients use the same `WAGGLE_DB_PATH` in their environment configuration (default is `~/.waggle/memory.db`).
*   **Result:** A decision made in one editor is immediately known by the agent in the other.

### 2. Session Handoffs (Context Bundles)
If you hit a session limit or want to jump to a fresh context while keeping important facts:
```bash
# Export a condensed, AI-ready summary of your current project context
waggle-mcp export-context-bundle --format markdown --output-path ./handoff.md
```
Paste the contents of `handoff.md` into your new session to "re-prime" the AI with your project's history.

### 3. Full Memory Migration (Backup/Import)
To move your entire memory history to a new machine:
*   **Export:** `waggle-mcp export-graph-backup --output-path my_memory.json`
*   **Import:** `waggle-mcp import-graph-backup --input-path my_memory.json`

---

## Using It In MCP Clients

Once installed, you usually do not run `waggle-mcp` commands by hand during daily work. Talk to the agent normally, and it calls Waggle MCP tools to store and retrieve memory.

- **Codex / Claude Code**: `observe_conversation`, `query_graph`, and `prime_context` are called automatically during normal threads.
- **Cursor**: decisions and facts can be persisted as graph memory instead of getting lost in old chat windows.
- **Antigravity**: conversation turns can be extracted via `observe_conversation`; context can be exported with `export_context_bundle`.

---

## See it in action

![Waggle init demo](./assets/demo.svg)

### How It Works (Interaction Flow)

```text
User  -> Agent -> observe_conversation(...) -> Graph stores typed nodes + edges
User  -> Agent -> query_graph("database")    -> Subgraph returned -> Agent answers with linked rationale
```

**Session 1** — April 10
```text
User:  Let's use PostgreSQL. MySQL replication has been painful.
Agent: [calls observe_conversation()]
       → stores decision node: "Chose PostgreSQL over MySQL"
       → stores reason node:   "MySQL replication painful"
       → links them with a depends_on edge
```

**Session 2** — April 12 (fresh context window, no history)
```text
User:  What did we decide about the database?
Agent: [calls query_graph("database decision")]
       → retrieves the decision node + linked reason from April 10

       "You decided on PostgreSQL on April 10. The reason recorded was
        that MySQL replication had been painful."
```

**Session 3** — April 14
```text
User:  Actually, let's reconsider — the team is more familiar with MySQL.
Agent: [calls store_node() + store_edge(new_node → old_node, "contradicts")]
       → both positions are preserved, and the contradiction is explicit
```

### Knowledge graph visual (example)

```mermaid
graph TD
  D1["Decision: Use PostgreSQL"]
  R1["Reason: MySQL replication pain"]
  D2["Decision update: reconsider MySQL"]
  P1["Preference: dark mode UI"]
  N1["Note: add integration tests"]

  D1 -- "depends_on" --> R1
  D2 -- "contradicts" --> D1
  N1 -- "relates_to" --> D2
  P1 -- "part_of project context" --> D1
```

---

## Key Features

- **Automatic Extraction**: `observe_conversation` ingests facts into the graph without manual schema work.
- **Portable Context**: `export_context_bundle` generates Markdown/JSON context packs for another AI.
- **Vault Round-trip**: `export_markdown_vault` / `import_markdown_vault` for Obsidian-style node editing.
- **Conflict Resolution**: `list_conflicts` / `resolve_conflict` to manage contradictions without losing history.
- **Deterministic Fallback**: Stable SHA-256 hashing for reliable, reproducible offline operation when transformer models are unavailable.

For a concise "what to say about Waggle" version, see [docs/briefing.md](./docs/briefing.md). That doc is intentionally a media-kit style summary; this README remains the canonical product and setup reference.

---

## Security & Privacy

By default, data stays local on your machine (`sqlite` backend, local database path such as `~/.waggle/memory.db`).  
Waggle does not require telemetry or cloud calls for core local operation.  
Your conversation memory only leaves your machine if you explicitly configure a remote backend or remote infrastructure.

Waggle currently stores local memory as a normal SQLite file and does not add application-level encryption at rest. Use standard filesystem permissions and OS disk encryption if the stored conversation history is sensitive.

---

## Graph Data Model

### Node Types

`fact`, `entity`, `concept`, `preference`, `decision`, `question`, `note`

### Edge Types

`relates_to`, `contradicts`, `depends_on`, `part_of`, `updates`, `derived_from`, `similar_to`

---

## Model Support

Waggle currently uses a local `sentence-transformers` embedding model selected by `WAGGLE_MODEL`.

- Default: `all-MiniLM-L6-v2`
- Any locally available `sentence-transformers` model name can be used.
- If the selected model is unavailable locally, Waggle falls back to deterministic embeddings for portability.

Set model in env:

```bash
WAGGLE_MODEL=all-mpnet-base-v2 waggle-mcp serve
```

Set model in MCP client config (example):

```json
{
  "mcpServers": {
    "waggle": {
      "command": "python",
      "args": ["-m", "waggle.server"],
      "env": {
        "WAGGLE_MODEL": "all-mpnet-base-v2"
      }
    }
  }
}
```

Notes:
- Waggle does not currently route to hosted embedding providers directly; embedding inference is local to the runtime.
- Deterministic mode is useful for offline/testing portability, but semantic retrieval quality is lower than transformer mode.

---

## Benchmarks & Verification

Checked-in artifacts back the headline claims:

- Token use: `63.0` comparative mean context tokens for Waggle vs `161.8` for the naive RAG baseline, about `2.6x` fewer tokens on the saved comparison snapshot.
- LongMemEval: `graph_raw` reaches `97.4% R@5` and `88.4% Exact@5` on the saved 500-question split; `graph_hybrid` reaches `96.4%` and `85.6%`.
- Local operation latency snapshot: `observe_conversation` mean `1.54 ms`, `query_graph` mean `1.60 ms`, `graph_diff` mean `0.80 ms` using local SQLite plus deterministic embeddings.
- Automated verification: MCP integration, transcript handoff, and benchmark harness tests are checked into the repo, and the local smoke path exercises live `store_node`, `query_graph`, and `graph://stats`.

README benchmark claims in this repo are limited to Waggle runs with checked-in artifacts and reproducible commands. Cross-project comparisons are intentionally excluded unless they are apples-to-apples on split, protocol, and scoring.

Detailed artifacts and methodology live in:

- [docs/benchmark-methodology.md](./docs/benchmark-methodology.md)
- [docs/longmemeval-methodology.md](./docs/longmemeval-methodology.md)
- [tests/artifacts/README.md](./tests/artifacts/README.md)
- [tests/artifacts/benchmark_current.md](./tests/artifacts/benchmark_current.md)
- [tests/artifacts/verification/2026-04-20-performance-snapshot/performance_snapshot.md](./tests/artifacts/verification/2026-04-20-performance-snapshot/performance_snapshot.md)

> **Note on dates:** some checked-in benchmark and demo artifacts use `2026-04-2x` timestamps as fixture metadata for reproducibility. Treat them as artifact dates, not a product release calendar.

---

## Known Limitations

- **Best on structured recall, weaker on answer synthesis**: Waggle is strongest at "retrieve the right facts and relationships" — not at emitting a single benchmark-formatted final answer from memory.
- **Edges are load-bearing**: `observe_conversation` and `decompose_and_store` create them automatically. Raw `store_node` calls without follow-up edges produce disconnected nodes with no traversal value.
- **Graph retrieval trades tokens for reasoning context**: factual lookups are often cheaper than chunked RAG; graph-expansion queries intentionally spend more tokens to carry update chains and contradictions.
- **Deduplication is fixture-backed, not universal semantic equivalence**: the current 32-case fixture covers common memory-node paraphrases and false friends, but broader production text can still require additional aliases or stricter domain guards.

For operational details, scaling considerations, tool-level behavior, and the full MCP feature surface, see [docs/reference.md](./docs/reference.md).

---

## Contributing

PRs and issues are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md).

---

## Reference & Docs

Detailed reference material lives in external documentation:

- **[docs/reference.md](./docs/reference.md)**: Environment variables, admin commands, Docker setup, and full tool surface.
- **[deploy/kubernetes/README.md](./deploy/kubernetes/README.md)**: Production deployment.
- **[docs/runbooks/](./docs/runbooks/)**: Operations and troubleshooting.
- **[tests/artifacts/README.md](./tests/artifacts/README.md)**: Benchmark artifacts and traceability.

---

## License

MIT — see [LICENSE](./LICENSE).
