Skip to main content

memwall

ci python license

Antivirus for AI agent memory.

Persistent memory is the newest attack surface in agentic AI. One poisoned memory — planted through an email, a webpage, or a document your agent read — survives across sessions and fires days or weeks later. OWASP added Memory and Context Poisoning to its 2026 Agentic AI Top 10 (ASI06); published research shows attack success rates of 80–99% against real agent stacks.

memwall scans agent memory stores for injected standing orders, exfiltration vectors, hidden payloads, and hygiene issues like retained PII. Zero dependencies for the core scan.

Quickstart

pip install memwall

memwall scan path/to/memory.json          # one store or export
memwall scan .                            # walk a project: CLAUDE.md, AGENTS.md, memory files
memwall scan memory.json --judge          # add the Claude semantic judge (needs ANTHROPIC_API_KEY)
memwall rules                             # list detection rules

60-second demo — scan the bundled example store and watch it catch an invoice-exfiltration implant and a payment redirect:

git clone https://github.com/gbayerv26/memwall && cd memwall
pip install -e .
memwall scan examples/

Directory scans are memory-aware: package.json, tsconfig.json, and other non-memory JSON are skipped automatically, as are files over 5 MB.

Supported stores

  • MCP reference memory server — memory.json / .jsonl of entities and observations
  • mem0-style exports — JSON lists of memory objects
  • SQLite-backed stores — Letta, mem0 history, custom agent DBs: every text cell in every table, auto-detected by file magic, opened read-only
  • Agent instruction files — CLAUDE.md, AGENTS.md, GEMINI.md, .cursorrules, .mdc
  • Notes / markdown memory files and generic JSON dumps

How it works

Pass 1 — heuristics (free, instant). Rules MW001–MW016 catch the known shapes of memory poisoning: instruction overrides, secrecy pressure ("don't tell the user"), authority claims ("system note:", "developer mode"), payment redirection, crypto wallets, encoded payloads, zero-width/bidi hidden characters, chat-role smuggling (<|im_start|>), rendering beacons (remote markdown images), delayed triggers ("when the user asks about X..." — the signature of implants that fire later), and PII that needs an expiry policy. A combo rule (MW000) escalates to CRITICAL when a standing order and an outbound destination appear in the same memory — the classic exfiltration shape.

Instruction files get a calibrated ruleset: imperatives are normal in a CLAUDE.md, so only the genuinely suspicious rules apply there.

Pass 2 — the judge (optional). --judge sends flagged records to Claude for semantic classification (benign_fact / preference / task_context / suspicious_instruction / likely_injection). The judge treats memory content as untrusted data and never follows instructions inside it.

pip install "memwall[judge]"
export ANTHROPIC_API_KEY=sk-ant-...
memwall scan memory.json --judge

CI gate

memwall scan ./agent-memory --fail-on high --json memwall-report.json

Exit code is 1 when any finding meets the --fail-on threshold, so you can block deploys on a poisoned store.

Accepted findings can be baselined so CI only fails on new ones — a baselined finding stays suppressed until the memory content itself changes:

memwall scan ./agent-memory --baseline .memwall-baseline.json --update-baseline  # accept current state
memwall scan ./agent-memory --baseline .memwall-baseline.json --fail-on high -q  # gate on new findings

The gateway — quarantine before commit

memwall gateway is a transparent MCP proxy you put in front of any stdio memory server. Every memory write is scanned before it reaches the store; anything at or above the block threshold is quarantined instead of written, and the agent gets a clear "blocked, do not retry" tool response. Reads and all other traffic pass through untouched.

memwall gateway --state-dir ~/.memwall -- npx -y @modelcontextprotocol/server-memory

Claude Desktop / Claude Code config — wrap your existing memory server:

{
  "mcpServers": {
    "memory": {
      "command": "memwall",
      "args": ["gateway", "--state-dir", "/home/you/.memwall", "--",
               "npx", "-y", "@modelcontextprotocol/server-memory"]
    }
  }
}

Writes (tool names matching create/add/store/save/write/update/remember/...) are scanned with the same rule engine as memwall scan. The gateway fails open on internal errors and keeps protocol traffic on stdout and diagnostics on stderr, so it never takes your memory server down.

Review what happened — every write is recorded in an append-only audit trail with a payload hash, so you can answer "when did this belief enter memory":

memwall log --state-dir ~/.memwall                # forensic event log
memwall quarantine --state-dir ~/.memwall list    # held writes
memwall quarantine --state-dir ~/.memwall show q1a2b3c4
memwall quarantine --state-dir ~/.memwall release q1a2b3c4 -- npx -y @modelcontextprotocol/server-memory
memwall quarantine --state-dir ~/.memwall drop q1a2b3c4

release replays the original write to the backend after human review; drop discards it. Both decisions are appended to the audit trail, never rewritten over it.

Monitoring — catch poison the moment it lands

memwall watch re-scans a store on an interval and alerts only on new findings — the first run establishes a snapshot, every later run reports what appeared since:

memwall watch ./agent-memory --interval 300          # continuous, every 5 min
memwall watch ./agent-memory --once --fail-on-new    # one delta check (cron / CI)

--once --fail-on-new exits 1 when something new appeared, so a cron job, scheduled CI run, or systemd timer becomes a poisoning alarm with one line.

Compliance

Right to be forgotten (GDPR Art. 17). Erasure quietly fails in summarized agent memory — a name survives inside a paraphrase after the source row was deleted. forget-check checks whether supplied literal identifiers remain (case-insensitive); it cannot prove paraphrase or semantic erasure:

memwall forget-check ./agent-memory --subject "alice@corp.com" --subject "Alice Smith" --json proof.json

Exit 0 when identifiers are absent; exit 1 with every remaining literal reference. Add --json to save the result as a report.

Standard exports. memwall scan --sarif report.sarif emits SARIF 2.1.0 for GitHub code scanning and security dashboards; --html report.html writes a self-contained, dark-mode-aware report you can attach to a compliance ticket or email to a client.

Trust-aware policies — the provenance handshake

Agents (or their harnesses) can declare where memory content came from by attaching MCP metadata to the write call:

{"method": "tools/call",
 "params": {"name": "add_observations",
            "_meta": {"memwall": {"origin": "web"}},
            "arguments": {"...": "..."}}}

Each origin maps to a block threshold — content from the open web is held to a stricter bar than something the user typed:

origin blocks at
user critical
agent high
tool / web / email / document medium
undeclared --block-at (default high)

Override with a preset — --policy strict, --policy balanced, or --policy permissive — or a JSON file:

{"default_block_at": "high", "origins": {"web": "low", "voicemail": "low"}}

Unlisted origins keep the built-in table. The declared origin is recorded on every event and quarantine entry, so the audit trail carries provenance. The memwall meta key is stripped before the call reaches the backend.

Judge-in-the-loop

memwall gateway --judge -- npx -y @modelcontextprotocol/server-memory

With --judge, flagged writes get a second opinion from the Claude judge before quarantining. Clearing verdicts (fact / preference / task context) let the write through — cutting heuristic false positives without losing the block on real injections. If the judge is unavailable or unsure, the write stays quarantined (fail-safe). Needs pip install "memwall[judge]" and ANTHROPIC_API_KEY; adds one API call only to writes heuristics already flagged, so normal traffic pays zero latency.

Roadmap

  • Hosted memwall. The watch engine as a managed service: fleet dashboard, alert routing (Slack/email), and scheduled compliance reports. Interested? Open an issue titled "hosted waitlist".
  • More stores: Zep, Letta, LangGraph checkpoints, vector DBs.
  • Policy packs: shareable, versioned policies per industry / risk appetite.

Honest limitations

Heuristics have false positives and false negatives by design — they are a triage layer, not a verdict. Review findings before deleting memories. The judge pass improves precision but is only as good as the model behind it.

License

MIT

Metadata

Release files for memwall 0.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for memwall 0.6.1
File Size Uploaded
memwall-0.6.1.tar.gz 42.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for memwall 0.6.1
File Interpreter ABI Platform
memwall-0.6.1-py3-none-any.whl Python 3 none any Details

Total release size: 79.1 kB

Release files / memwall-0.6.1.tar.gz

Download URL memwall-0.6.1.tar.gz
Size 42.1 kB
Tags Source
SHA-256 checksum
How to use checksums
824cedee92ba34d8e6e95d9eb562bb9f7a5535667911a4c0aeb286a09f5050ce
BLAKE2b-256 checksum
How to use checksums
1da7a782f99e7abeffee25212f1f960a31830309009e12a1d49dd2bfc3dd698b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Release files / memwall-0.6.1-py3-none-any.whl

Download URL memwall-0.6.1-py3-none-any.whl
Size 37.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d284278df2b5ef95dd9f691ff75e84ae743af6f3089906a8eedd9d5a137dd690
BLAKE2b-256 checksum
How to use checksums
2daae2795e3881f90ba68ad356a818bf3a1985d407e78ed32f49031d09816eb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.1 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page