Metadata-Version: 2.4
Name: enhanced-mcp-memory
Version: 2.6.1
Summary: Enterprise-grade MCP server with sequential thinking, project convention learning, and intelligent memory management
Home-page: https://github.com/cbunting99/enhanced-mcp-memory
Author: cbunting99
Author-email: cbunting99 <cbunting99@users.noreply.github.com>
Maintainer-email: cbunting99 <cbunting99@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/cbunting99/enhanced-mcp-memory
Project-URL: Repository, https://github.com/cbunting99/enhanced-mcp-memory
Project-URL: Issues, https://github.com/cbunting99/enhanced-mcp-memory/issues
Project-URL: Documentation, https://github.com/cbunting99/enhanced-mcp-memory#readme
Keywords: mcp,memory,ai,task-management,knowledge-graph,semantic-search,sequential-thinking,project-conventions,token-optimization
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Database
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp>=2.10.5
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: sentence-transformers>=2.2.0
Requires-Dist: numpy>=1.21.0
Requires-Dist: scipy>=1.7.0
Requires-Dist: filelock>=3.0.0
Provides-Extra: enterprise
Requires-Dist: cryptography>=41.0.0; extra == "enterprise"
Requires-Dist: prometheus_client>=0.19.0; extra == "enterprise"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: isort>=5.0.0; extra == "dev"
Requires-Dist: flake8>=4.0.0; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Enhanced MCP Memory

> An enterprise-grade Model Context Protocol server for AI agents: long-term memory, task management, sequential reasoning, project-convention learning, and intelligent auto-processing — with at-rest encryption, an audit log, Prometheus metrics, and structured logging baked in.

[![PyPI version](https://img.shields.io/pypi/v/enhanced-mcp-memory)](https://pypi.org/project/enhanced-mcp-memory/)
![Python](https://img.shields.io/badge/python-3.8%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![Tests](https://img.shields.io/badge/tests-45%20passed-brightgreen)
![MCP](https://img.shields.io/badge/MCP-FastMCP%202.x-purple)

> Optimised for Claude Sonnet 4 and other long-context reasoning models. Works equally well as a local memory layer for any MCP-capable client.

---

## Table of contents

1. [Why this exists](#why-this-exists)
2. [Features at a glance](#features-at-a-glance)
3. [Quick start](#quick-start)
4. [MCP client configuration](#mcp-client-configuration)
5. [Available tools](#available-tools)
6. [Configuration reference](#configuration-reference)
7. [Enterprise hardening (v2.6.0)](#enterprise-hardening-v260)
8. [Project convention learning](#project-convention-learning)
9. [Database & storage](#database--storage)
10. [Logging](#logging)
11. [Project structure](#project-structure)
12. [Testing](#testing)
13. [Building & publishing](#building--publishing)
14. [Troubleshooting](#troubleshooting)
15. [License](#license)

---

## Why this exists

Memory and task state for an AI agent shouldn't be lost when the conversation ends. Most MCP servers treat memory as a sidecar feature — a few JSON blobs, no audit trail, no encryption, no retry semantics. **Enhanced MCP Memory** treats memory as production infrastructure:

- **Reliable** — bare `except Exception: pass` is gone. Every silent failure logs at WARNING with full context. SIGTERM and SIGINT trigger a graceful shutdown that flushes the audit log.
- **Observable** — Prometheus metrics for every tool call, structured JSON logs ready for log shippers, and a tamper-evident `audit_log` table recording who did what and when.
- **Secure by default** — opt-in at-rest encryption with Fernet (AES-128-CBC + HMAC-SHA256) for memories, tasks, thinking chains, and project content.
- **Defensive under load** — circuit breaker, sampling, and a per-call cap on the auto-processing middleware so a chatty agent can't melt the server.
- **Typed knowledge graph** — `depends_on`, `relates_to`, `conflicts_with`, `implements`, `references`, `similar_content`, with `strength` clamped to `[0, 1]` and direction-aware queries.

---

## Features at a glance

| Area | What you get |
|---|---|
| Memory | Semantic search via sentence-transformers, automatic classification + importance scoring, content-hash deduplication, file-path associations, LRU cap with importance-aware eviction. |
| Sequential thinking | Five-stage reasoning chains (analysis -> planning -> execution -> validation -> reflection), real-time token estimation, 30-70% context compression, key-point / decision / action auto-extraction. |
| Tasks | Auto-extraction from conversation and code, status tracking (pending / in_progress / completed / cancelled), task-memory relationships, project scoping, no-false-positive `decompose_task`. |
| Project conventions | Auto-detect OS / shell / toolchain / build commands, learn npm scripts and Makefile targets, suggest correct commands, persist as high-importance memories. |
| Enterprise | At-rest encryption, audit log, structured JSON logging, Prometheus `/metrics` endpoint, circuit-breakered middleware, typed KG, graceful shutdown. |
| Operations | `health_check()`, `get_performance_stats()`, `cleanup_old_data()`, `optimize_memories()`, `get_database_stats()`, multi-editor safe with WAL + 5s busy-timeout. |
| Deployment | Single entry point (`enhanced-mcp-memory`) — works under `uvx`, `uv tool install`, and `pip install`. No nested venv built on top of uvx's cache. |

---

## Quick start

The launcher (`run_in_venv.main`) is wired into `[project.scripts]`, so **every install path funnels through it**. The launcher detects how it was invoked and picks the right strategy:

| Invocation | What the launcher does |
|---|---|
| `uvx enhanced-mcp-memory` | Detects uvx's cache venv (`sys.prefix != sys.base_prefix`) and runs the server in place — no nested venv. |
| `uv tool install enhanced-mcp-memory` then `enhanced-mcp-memory` | Same as uvx: detects the tool venv, runs in place. |
| `pip install enhanced-mcp-memory` then `enhanced-mcp-memory` | Same: runs in the install's venv in place. |
| `python run_in_venv.py` (from a checkout) | Builds (or reuses) a private `~/enhanced-mcp-memory/.venv`, editable-installs the package, re-execs the server inside. |

### Option 1 — `uvx` (recommended for end users)

```bash
uvx enhanced-mcp-memory
```

First launch is slow (it builds uvx's cache venv and downloads dependencies); subsequent launches are a near-zero-overhead passthrough.

### Option 2 — run from a checkout (recommended for development)

```bash
git clone https://github.com/cbunting99/enhanced-mcp-memory.git
cd enhanced-mcp-memory
python run_in_venv.py
```

Use this when you want to hack on the server — the editable install means source edits take effect after a re-launch.

### Option 3 — system Python, no venv

```bash
git clone https://github.com/cbunting99/enhanced-mcp-memory.git
cd enhanced-mcp-memory
pip install -r requirements.txt
python mcp_server_enhanced.py
```

### Add the enterprise extras (encryption + metrics)

The base wheel ships the memory, task, and thinking modules. To get **at-rest encryption**, the **Prometheus metrics endpoint**, and the **audit log**, install the optional `enterprise` extra — pipe it through whichever launcher you use:

| Launcher | Command |
|---|---|
| `uvx` (one-off) | `uvx --from "enhanced-mcp-memory[enterprise]" enhanced-mcp-memory` |
| `uv tool` (persistent) | `uv tool install enhanced-mcp-memory[enterprise]` |
| `pip` | `pip install "enhanced-mcp-memory[enterprise]"` |

If you skip the extras, the server still works — `crypto.status()` reports `enabled=False`, `ENCRYPTION_KEY` is silently ignored, and `METRICS_PORT` does nothing.

### Useful launcher flags

```bash
python run_in_venv.py                    # bootstrap (or reuse) + run
python run_in_venv.py --venv-path        # print the resolved venv path
python run_in_venv.py --data-dir         # print the resolved data dir path
python run_in_venv.py --upgrade          # force reinstall into the venv
python run_in_venv.py --uninstall        # remove venv + database + logs
python run_in_venv.py --uninstall --yes  # same, skip the confirmation prompt
```

Override locations with environment variables if needed:

```bash
export ENHANCED_MCP_MEMORY_VENV=/some/other/path/.venv
export ENHANCED_MCP_MEMORY_DATA=/some/other/data/dir
```

---

## MCP client configuration

The MCP server is launched via the same `enhanced-mcp-memory` entry point regardless of install method — point your client at whichever form fits.

### `uvx` (recommended for end users)

```json
{
  "mcpServers": {
    "memory-manager": {
      "command": "uvx",
      "args": ["--from", "enhanced-mcp-memory[enterprise]", "enhanced-mcp-memory"],
      "env": {
        "LOG_LEVEL": "INFO",
        "MAX_MEMORY_ITEMS": "1000",
        "ENABLE_AUTO_CLEANUP": "true",
        "STRUCTURED_LOGS": "true",
        "METRICS_PORT": "9090",
        "AUDIT_ACTOR": "$USER@$(hostname)"
      }
    }
  }
}
```

### Local checkout (developer / hacking)

```json
{
  "mcpServers": {
    "memory-manager": {
      "command": "python",
      "args": ["run_in_venv.py"],
      "cwd": "/path/to/enhanced-mcp-memory",
      "env": {
        "LOG_LEVEL": "INFO",
        "MAX_MEMORY_ITEMS": "1000",
        "ENABLE_AUTO_CLEANUP": "true",
        "STRUCTURED_LOGS": "true",
        "METRICS_PORT": "9090",
        "AUDIT_ENABLED": "true"
      }
    }
  }
}
```

> If you use multiple editors (Cursor, Claude Desktop, VS Code, etc.), make sure they all use the same `DATA_DIR` — otherwise each editor writes to its own private database and memories will appear to "vanish" when you switch editors. See [Canonical data directory](#canonical-data-directory) below.

---

## Available tools

### Core memory tools

| Tool | Purpose |
|---|---|
| `get_memory_context(query)` | Fetch relevant memories and project context for the current prompt. |
| `list_memories(memory_type, project_id, limit)` | List stored memories with optional filters. |
| `create_task(title, description, priority, category)` | Create a new task in the active project. |
| `get_tasks(status, limit)` | Retrieve tasks, optionally filtered by status. |
| `get_project_summary()` | Get a comprehensive overview of the active project. |

### Sequential thinking tools

| Tool | Purpose |
|---|---|
| `start_thinking_chain(objective)` | Begin a structured reasoning process. |
| `add_thinking_step(chain_id, stage, title, content, reasoning)` | Append one reasoning step. |
| `get_thinking_chain(chain_id)` | Retrieve the complete chain. |
| `list_thinking_chains(limit)` | List recent chains. |

### Context management tools

| Tool | Purpose |
|---|---|
| `create_context_summary(content, key_points, decisions, actions)` | Compress context for token optimisation. |
| `start_new_chat_session(title, objective, continue_from)` | Begin a new conversation with optional continuation. |
| `consolidate_current_session()` | Compress the current session for handoff. |
| `get_optimized_context(max_tokens)` | Get token-optimised context within a budget. |
| `estimate_token_usage(text)` | Real-time token count for planning. |

### Enterprise auto-processing tools

| Tool | Purpose |
|---|---|
| `auto_process_conversation(content, interaction_type)` | Extract memories and tasks automatically; threshold + per-call cap enforced. |
| `decompose_task(prompt)` | Break a complex task into subtasks — no false positives on trivial or conversational prompts. |

### Project convention tools

| Tool | Purpose |
|---|---|
| `auto_learn_project_conventions(project_path)` | Automatically detect and learn project patterns. |
| `get_project_conventions_summary()` | Get a formatted summary of learned conventions. |
| `suggest_correct_command(user_command)` | Suggest project-appropriate command corrections. |
| `remember_project_pattern(pattern_type, pattern, description)` | Manually store a project pattern. |
| `update_memory_context()` | Refresh memory context with the latest project conventions. |

### System management tools

| Tool | Purpose |
|---|---|
| `health_check()` | Run health checks and connectivity diagnostics. |
| `get_performance_stats()` | Get detailed performance metrics. |
| `cleanup_old_data(days_old)` | Clean up old memories and tasks. |
| `optimize_memories()` | Remove duplicates and optimize storage. |
| `get_database_stats()` | Get comprehensive database statistics. |

---

## Configuration reference

All settings are environment variables — no config files required.

### Core

| Variable | Default | Description |
|---|---|---|
| `DATA_DIR` | `~/enhanced-mcp-memory` | Where to store data and logs. Important: keep this consistent across every editor's MCP config — see [Canonical data directory](#canonical-data-directory). |
| `LOG_LEVEL` | `INFO` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`. |
| `MAX_MEMORY_ITEMS` | `1000` | Maximum memories per project; LRU-evicts lowest-importance items when over. |
| `MAX_CONTEXT_TOKENS` | `8000` | Token threshold at which context auto-compression kicks in. |
| `CLEANUP_INTERVAL_HOURS` | `24` | How often the background cleanup pass runs. |
| `ENABLE_AUTO_CLEANUP` | `true` | Toggle the background cleanup pass. |
| `MAX_CONCURRENT_REQUESTS` | `5` | Max concurrent MCP tool calls. |
| `REQUEST_TIMEOUT` | `30` | Per-request timeout in seconds. |

### Enterprise (require `[enterprise]` extras)

| Variable | Default | Description |
|---|---|---|
| `ENCRYPTION_KEY` | _unset_ | Fernet key (base64-url, 32 bytes). When set, memory, task, thinking-chain, and project content columns are encrypted at rest with AES-128-CBC + HMAC. Generate with `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`. Existing plaintext databases remain readable when the key is unset. |
| `METRICS_PORT` | _unset_ | When set, exposes Prometheus metrics on `http://127.0.0.1:PORT/metrics` (where `PORT` is the value of this variable). |
| `METRICS_HOST` | `127.0.0.1` | Bind address for the metrics endpoint. |
| `STRUCTURED_LOGS` | `false` | When `true`, logs are emitted as one JSON object per line (log-shipper friendly). |
| `LOG_FILE` | _unset_ | When set, also writes JSON-formatted logs to this file path (parallel to the console log). |
| `AUDIT_ENABLED` | `true` | Master switch for the `audit_log` writes. Set to `false` for read-only or audit-bypass deployments. |
| `AUDIT_ACTOR` | `$USER` | Identity recorded in each `audit_log` row. Override per environment so multi-tenant deployments can attribute actions correctly. |

### Middleware (auto-processing gate)

| Variable | Default | Description |
|---|---|---|
| `MIDDLEWARE_ENABLED` | `true` | Master switch for the conversation auto-processing middleware. |
| `MIDDLEWARE_SAMPLE_RATE` | `1.0` | Probability (0.0-1.0) that a conversation triggers extraction. Lower = less work. |
| `MIDDLEWARE_MIN_CONTENT_LEN` | `200` | Skip extraction when content is shorter than this many characters. |
| `MIDDLEWARE_CIRCUIT_FAILURES` | `5` | Consecutive failures that trip the middleware circuit breaker. |
| `MIDDLEWARE_CIRCUIT_COOLDOWN` | `60` | Seconds the middleware stays disabled after tripping. |
| `AUTO_PROCESS_THRESHOLD` | `0.5` | Importance threshold above which extracted items become memories. |
| `AUTO_PROCESS_MAX_PER_CALL` | `5` | Hard cap on memories / tasks created per `auto_process_conversation` call. |

---

## Enterprise hardening (v2.6.0)

### At-rest encryption

Set `ENCRYPTION_KEY` and the server transparently encrypts all sensitive columns — memory `title` / `content`, task descriptions, thinking-chain content, and project conventions — using **Fernet** (AES-128-CBC + HMAC-SHA256). Each row is independently keyed with a fresh IV; ciphertexts are prefixed with `fernet:v1:` so a future format change can be detected at read time.

The encryption layer is **fail-soft**: a transient decryption error logs at WARNING and returns the ciphertext unchanged rather than crashing the request. The format version prefix means you can rotate `ENCRYPTION_KEY` and run an offline re-encryption migration without touching call sites.

### Audit log

Every mutating tool writes one row to `audit_log`:

| Column | Meaning |
|---|---|
| `timestamp` | ISO-8601 UTC at write time. |
| `actor` | `$AUDIT_ACTOR` (defaults to `$USER` / `$USERNAME`, falls back to `system`). |
| `action` | Tool name / operation. |
| `resource_type` | e.g. `memory`, `task`, `project`. |
| `resource_id` | UUID of the affected row, when applicable. |
| `success` | `1` on success, `0` on failure. |
| `error` | Error string on failure. |
| `metadata` | Free-form JSON (request args, prior value, etc.). |
| `host`, `pid` | Process attribution. |

Audit writes are best-effort: if the table is unreachable the tool call still succeeds. Set `AUDIT_ENABLED=false` to skip writes entirely (e.g. for read-only mirrors).

### Structured (JSON) logging

Set `STRUCTURED_LOGS=true` and every log line becomes a single JSON object:

```json
{"ts": "2026-07-09T03:26:49.714Z", "level": "INFO", "logger": "audit",
 "message": "memory mutated", "pid": 15268, "tid": 26564}
```

Set `LOG_FILE=/var/log/enhanced-mcp-memory.jsonl` to tee the same JSON into a file for downstream shippers (Loki, Vector, Fluent Bit). The console stays human-readable.

### Prometheus metrics

Set `METRICS_PORT=9090` (or any free port) and the server exposes `/metrics`. Counters: tool calls, tool errors, audit writes. Histograms: tool latency. Gauges: database size, memory count, circuit-breaker state.

```bash
$ curl -s http://127.0.0.1:9090/metrics | head
# HELP enhanced_mcp_tool_calls_total Total MCP tool invocations.
# TYPE enhanced_mcp_tool_calls_total counter
enhanced_mcp_tool_calls_total{tool="get_memory_context",status="success"} 42
```

### Reliability primitives

Every silent-failure path now flows through `safe_call(logger, op, fn, *args, default=None, **kwargs)`. The helper runs `fn(*args, **kwargs)`, catches `Exception`, logs at WARNING with the operation name and exception class, and returns `default`. Bare `except Exception: pass` is gone — enforced in CI by a banned-pattern grep.

A SIGTERM and SIGINT handler is installed at startup (and registered with `atexit`) so the server flushes pending audit writes and closes the database cleanly before exit. CI catches the SIGTERM that pytest sends at teardown.

### Middleware hardening

The conversation auto-processing path is gated by:

- a **circuit breaker** (`MIDDLEWARE_CIRCUIT_FAILURES` / `MIDDLEWARE_CIRCUIT_COOLDOWN`) — consecutive failures trip the breaker and disable the path until cooldown elapses,
- **sampling** (`MIDDLEWARE_SAMPLE_RATE`) — only a fraction of conversations trigger extraction,
- a **minimum-content gate** (`MIDDLEWARE_MIN_CONTENT_LEN`) — short conversations are skipped without overhead.

Each skip / trip event is itself recorded in `audit_log` and in the Prometheus counters so you can see why extraction didn't run.

### Typed knowledge graph

`add_relationship(from_type, from_id, to_type, to_id, relationship_type, strength=1.0)` now validates the typed catalog and clamps `strength` to `[0, 1]`:

```python
allowed = {"depends_on", "relates_to", "conflicts_with",
           "implements", "references", "similar_content"}

db.add_relationship("memory", "m1", "task", "t1", "relates_to", strength=2.5)
# ^ ValueError: unknown relationship_type; valid set: depends_on, ...
# strength clamped to 1.0 before insert
```

`get_related_items(item_type, item_id, relationship_type=None, min_strength=0.0, limit=50)` honours both filters and returns both `outgoing` and `incoming` edges with a `direction` field.

---

## Project convention learning

The server automatically detects and remembers project-specific conventions so AI assistants stop suggesting the wrong commands. Across detection:

- **Operating system & shell** — Windows vs Unix, `cmd.exe` / PowerShell / Bash / Zsh.
- **Project type** — Node.js, Python (FastAPI / Django / pytest / poetry), Rust, Go, Java, MCP servers.
- **Build & test commands** — `npm run *`, `cargo test`, `pytest`, `go test`, Makefile targets, project-specific scripts.
- **Tooling** — IDEs, linters (flake8 / eslint), formatters (black / prettier), CI/CD files (GitHub Actions / GitLab CI).
- **Package management** — npm / yarn / pnpm, pip / poetry / uv, cargo, go modules.
- **Smart suggestions** — given `"node server.js"` in a project with `"dev": "node server.js"` in `package.json`, the suggestion engine responds with the correct invocation.

All learned conventions persist as **high-importance memories** so they appear in AI context for every interaction, across session and project boundaries.

Windows-specific quirks (path separators, `dir` vs `ls`, `where` vs `which`, `cmd.exe` quoting) are detected and respected automatically.

---

## Database & storage

- **SQLite** for reliable, file-based storage — no separate DB process to manage.
- **WAL journal mode + 5s busy-timeout** — safe concurrent access from multiple editors.
- **Automatic schema migrations** — every migration recorded in `schema_migrations` and run exactly once; older DBs upgrade transparently on first connect.
- **`audit_log` table** — every mutating tool writes a row (see [Audit log](#audit-log)).
- **Comprehensive indexing** — most queries return in single-digit milliseconds even at 100k rows.
- **Built-in backup & repair tools** — `optimize_memories()` deduplicates on content hash; `get_database_stats()` reports size + integrity.

Default location: `~/enhanced-mcp-memory/data/mcp_memory.db` (or `$DATA_DIR/data/mcp_memory.db` when set).

### Canonical data directory

When you point several MCP clients at this server, **every client must use the same `DATA_DIR`** — or, easier, leave `DATA_DIR` unset everywhere and let each client fall back to the default `~/enhanced-mcp-memory`. Otherwise each editor writes to its own private database and memories appear to "vanish" when you switch editors.

Symptoms of a misconfigured setup:

- Memory counts differ between editors.
- Multiple `mcp_memory.db` files exist at `~/.enhanced_mcp_memory/`, `~/ClaudeMemory/`, etc.
- The server logs `data dir SOME_PATH is inside cwd SOME_PATH` at startup — that warning means the project root was used as the data dir, which produces a brand-new DB per project.

If you already have scattered DBs, consolidate them into the canonical target:

```bash
# Dry-run first; shows how many rows would merge and how many dedup by content_hash.
python scripts/merge_databases.py \
  "$HOME/.enhanced_mcp_memory/data/mcp_memory.db" \
  "$HOME/ClaudeMemory/data/mcp_memory.db"

# When the dry-run looks right, apply (each source is auto-backed up to
# <source>.bak-TIMESTAMP).
python scripts/merge_databases.py --apply \
  "$HOME/.enhanced_mcp_memory/data/mcp_memory.db" \
  "$HOME/ClaudeMemory/data/mcp_memory.db"

# Add more sources later by re-running; idempotent by primary key plus
# content_hash dedup for memories.
```

Run `scripts/merge_databases.py --help` for the full flag list (`--no-backup`, `--target` / `-d`, etc.).

---

## Logging

- **Daily rotation** in `./logs/` (or `$DATA_DIR/logs/`).
- **Human-readable console** by default; set `STRUCTURED_LOGS=true` for one-JSON-object-per-line.
- **Optional file sink** via `LOG_FILE=/path/to/file.jsonl` — useful for Loki / Vector / Fluent Bit ingestion.
- **Performance tracking** integrated — every tool call emits a structured event with latency and success.
- **Error tracking** with full stack traces at WARNING and above.

The structured-logging helpers (`structured_logging.install_once(level, log_file)`) are safe to call multiple times — only the first call wires a new handler; subsequent calls are no-ops. This lets MCP tool decorators request a logger without worrying about double-handler noise.

---

## Project structure

```text
enhanced-mcp-memory/
  mcp_server_enhanced.py            # Main MCP server, FastMCP integration
  memory_manager.py                 # Core memory / task logic + project detection
  sequential_thinking.py            # Five-stage reasoning chains + context optimisation
  database.py                       # SQLite layer, typed KG, audit schema install
  project_conventions.py            # OS / shell / toolchain / command learner
  enhanced_automation_middleware.py # Auto-processing with circuit breaker + sampling
  audit.py                          # Audit-log writer (audit_log table)
  crypto.py                         # Fernet at-rest encryption  [enterprise]
  metrics.py                        # Prometheus counters / histograms / gauges  [enterprise]
  structured_logging.py             # JSON formatter + install_once()
  run_in_venv.py                    # Cross-platform venv launcher (console_script)
  version.py                        # Single-source __version__
  pyproject.toml                    # Build metadata + [enterprise] / [dev] extras
  tests/                            # Pytest suite: 45 tests, all passing
    conftest.py
    test_audit.py
    test_concurrency.py
    test_database_schema.py
    test_decompose_task.py
    test_encryption.py
    test_knowledge_graph.py
    test_memory_manager.py
    test_metrics.py
    test_middleware_circuit_breaker.py
    test_structured_logging.py
    test_sweep_bare_except.py
  data/                             # SQLite database storage
  logs/                             # Application logs
  .github/workflows/ci.yml          # Pytest matrix + flake8 + banned-pattern grep
```

---

## Testing

The repo ships with a 45-test pytest suite under `tests/`. Run it locally:

```bash
pip install -e ".[enterprise,dev]"
pytest tests/
```

CI (`.github/workflows/ci.yml`) runs the suite across Python 3.9-3.12, plus `flake8` and a banned-pattern sweep that fails the build if any `except Exception: pass` or bare `except:` slips back into production:

```yaml
- ! grep -rnE 'except\s+Exception\s*:\s*pass' --include='*.py' .
- ! grep -rnE '^\s*except\s*:\s*$' --include='*.py' .
```

Targeted runs are common while iterating:

```bash
pytest tests/test_encryption.py -v                  # only the crypto round-trip
pytest tests/test_audit.py -v                       # only the audit-log path
pytest tests/test_sweep_bare_except.py -v           # only the banned-pattern lint
pytest tests/ -k "decompose" -v                     # any test whose name matches "decompose"
```

---

## Building & publishing

The wheel is built with `python -m build` and validated with `twine check`. Both tools are pure-Python and install-on-demand.

```bash
# 1. Make sure the dev extras + the enterprise extras are present.
pip install -e ".[enterprise,dev]"

# 2. Build sdist + wheel into ./dist.
python -m build

# 3. Validate metadata and long-description rendering.
python -m twine check dist/*

# 4. Upload to TestPyPI first, smoke-test, then promote to PyPI.
python -m twine upload --repository testpypi dist/*
python -m twine upload dist/*
```

A successful `python -m build` produces:

```text
dist/
  enhanced_mcp_memory-2.6.1-py3-none-any.whl
  enhanced_mcp_memory-2.6.1.tar.gz
```

After upload, verify the published version is installable from a fresh venv:

```bash
python -m venv /tmp/verify
/tmp/verify/Scripts/python -m pip install "enhanced-mcp-memory[enterprise]"
/tmp/verify/Scripts/python -c \
  "import mcp_server_enhanced, audit, crypto, metrics, structured_logging; print('OK')"
```

### Manual release checklist

1. Bump `version.py` (`2.6.1` -> `2.6.2`, etc.).
2. `pytest tests/ -v` — must be 45 / 45.
3. `python -m build` then `python -m twine check dist/*` — must PASS.
4. Confirm CI green on the release branch.
5. Tag the release with `git tag -s v2.6.1 -m 'v2.6.1'`.
6. `python -m twine upload dist/*`.

---

## Troubleshooting

### The server starts but memories appear missing in editor X

Almost always a `DATA_DIR` mismatch — editor X is reading a different SQLite file than editor Y. See [Canonical data directory](#canonical-data-directory). Fix: pick one `DATA_DIR` and set it everywhere (or unset it everywhere and let every client default to `~/enhanced-mcp-memory`).

### `crypto.status()` reports `enabled=False` even though I set `ENCRYPTION_KEY`

You installed the base wheel without the `enterprise` extras. Reinstall as `pip install "enhanced-mcp-memory[enterprise]"` (or the equivalent `uvx --from` / `uv tool` form) so `cryptography` is on the Python path.

### `uvx enhanced-mcp-memory` hangs on first launch

First launch is slow: uvx builds a cache venv and downloads the sentence-transformers model (~90 MB). Subsequent launches are near-instant. Watch the first-launch output for `pip install` progress bars.

### The audit log keeps growing

Expected — every mutating tool writes a row. For long-running deployments, prune via `cleanup_old_data()` or a periodic SQL `DELETE FROM audit_log WHERE timestamp < datetime('now', '-90 days')`. Pairs naturally with `audit_log` being created with a covering index on `timestamp`.

### The auto-processing middleware stopped extracting

Check the circuit-breaker counters via `/metrics` (look for `enhanced_mcp_middleware_circuit_state`) or query `audit_log` for `action='middleware_skip'` entries to see why. Likely candidates: too many consecutive failures tripped the breaker, sample rate is `0.0`, or content length is below `MIDDLEWARE_MIN_CONTENT_LEN`.

---

## License

MIT — see [LICENSE](LICENSE).

## Support

- Issues: [cbunting99/enhanced-mcp-memory/issues](https://github.com/cbunting99/enhanced-mcp-memory/issues)
- Documentation: [README on GitHub](https://github.com/cbunting99/enhanced-mcp-memory#readme)
- Discussions: [cbunting99/enhanced-mcp-memory/discussions](https://github.com/cbunting99/enhanced-mcp-memory/discussions)

## Version history

- **v2.6.1** — README rewrite as pure GitHub Flavored Markdown; no HTML wrappers, properly-aligned tables, working ToC anchors.
- **v2.6.0** — Enterprise hardening release: at-rest encryption, audit log, structured logging, Prometheus metrics, circuit-breakered middleware, typed knowledge graph, full pytest + CI suite.
- **v2.0.2** — Build configuration + license compatibility fixes.
- **v2.0.1** — Sequential thinking + project conventions.
- **v1.2.0** — Performance monitoring + health checks.
- **v1.1.0** — Semantic search + knowledge graph.
- **v1.0.0** — Initial release.
