Persistent visual entity memory for AI agents — self-hosted, model-agnostic
Project description
vemem
Persistent visual entity memory for AI agents. Self-hosted, open source, model-agnostic.
vemem is the memory layer for what AI agents see, not just what they're told. It resolves image observations (faces, objects, places) to named entities and accumulates knowledge against those entities across sessions — the piece that's missing from every text-based memory system.
Status
Pre-alpha. v0 implements the full op surface from docs/spec/identity-semantics.md with 260+ tests, but the API is not yet frozen.
| Docs index | docs/README.md |
| Architecture | docs/ARCHITECTURE.md |
| Spec | docs/spec/identity-semantics.md |
| Plan | docs/plan/v0-implementation.md |
| Examples | docs/examples/ — MCP config, OpenAI tools, CLI tour, bridge.py |
| Changelog | CHANGELOG.md |
| Compliance | COMPLIANCE.md |
| Security | SECURITY.md |
| Contributing | CONTRIBUTING.md |
What it does
Given an image, identify() returns named entities a text LLM can reason about — no training, no prompt stuffing, no per-session re-introduction. Corrections (relabel, merge, split), privacy-safe deletion (forget with LanceDB version prune), and bi-temporal audit are first-class.
Works as:
- a Python library you import (
from vemem import Vemem) - an MCP server any MCP-capable LLM client can call (Claude Desktop, Cursor, custom agents)
- OpenAI function-calling tool schemas for any non-MCP function-calling LLM (OpenAI, Anthropic, Gemini, Ollama)
- a CLI (
vm label,vm inspect,vm forget, …) for manual work and debugging - first-party host integrations (see Integrations below) — vemem slots in as your host's automatic image-understanding layer, mem0-style, without the agent needing to call a tool
- an Agent Skills package at
skills/vemem/that drops into Claude, Claude Code, Cursor, Hermes Agent, OpenClaw, Goose, OpenHands, Letta, and 25+ other skills-compatible hosts
Installation
git clone https://github.com/linville-charlie/vemem
cd vemem
uv sync
On first use, uv run python -c "from vemem import Vemem; Vemem()" will download InsightFace's buffalo_l weights (~200MB) to ~/.insightface/. Offline-only deployments should pre-install the weights.
Python 3.12 and 3.13 supported. 3.14 is blocked by a lancedb 0.19 segfault; we pin to 3.13 locally via .python-version.
Quick start
from vemem import Vemem
with Vemem() as vem: # LanceDB at ~/.vemem, InsightFace
observations = vem.observe(image_bytes) # detect + embed
candidates = vem.identify(image_bytes) # [] on first image
if not candidates:
entity = vem.label([o.id for o in observations], name="Charlie")
vem.remember(entity.id, "training for Boston Marathon")
# later — different session, different image of Charlie
matches = vem.identify(another_image)
# → [Candidate(entity=Charlie, confidence=0.94,
# facts=[Fact("training for Boston Marathon")])]
Test it without the real encoder (no model download, works offline):
from vemem import Vemem
from tests.support.fake_store import FakeStore # test-only, not shipped
class StubDetector:
id = "stub/detector@1"
def detect(self, img): return [(0, 0, 100, 100)]
class StubEncoder:
id = "stub/encoder@1"; dim = 4
def embed(self, img): return (float(img[0]), 1.0, 0.0, 0.0)
vem = Vemem(store=FakeStore(), encoder=StubEncoder(), detector=StubDetector())
Run as an MCP server
vemem-mcp-server # installed via uv tool install / pipx — runs on stdio
# or, in a repo checkout:
uv run vemem-mcp-server
# or:
uv run python -m vemem.mcp_server
Then paste docs/examples/claude_desktop_config.json into your Claude Desktop config. Remote Claude can now call identify_image, label, recall, forget, … against your local store without your biometric data ever leaving the laptop.
Run as a CLI
uv run vm --help
uv run vm observe photo.jpg
uv run vm label obs_... --name Charlie
uv run vm remember <entity_id> --fact "runs marathons"
uv run vm recall <entity_id>
Integrations
vemem is designed to slot under an existing agent framework as the automatic image-understanding layer — every image attachment is described through face recognition + persistent identity before the thinking LLM sees the message. The agent doesn't have to call a tool; vemem is just how the host describes images. This is the same seam mem0/supermemory use for conversational memory.
| Host | Status | Docs |
|---|---|---|
| openclaw | Supported (v0.1) | integrations/openclaw/README.md |
| Anything MCP-capable (Claude Desktop, Cursor, custom MCP clients) | Supported via the MCP server | docs/examples/mcp_usage.md |
| Anything OpenAI-function-calling capable (OpenAI, Groq, Ollama-tools) | Supported via tool schemas | docs/examples/openai_tools.md |
Additional hosts are welcome as PRs under integrations/. The HTTP sidecar shipped with vemem (vemem-openclaw-sidecar, installed with the package) can be reused for any framework that can run a child process and call localhost HTTP.
Compliance
vemem stores biometric identifiers. If you deploy it, you are the data controller under GDPR / BIPA / CCPA.
forget(entity_id)→ hard delete + LanceDBoptimize(cleanup_older_than=0)(verified by test — spec §4.5, §7)restrict(entity_id)— GDPR Art. 18 (stop processing without deleting)export(entity_id)— GDPR Art. 20 (portability)- EventLog never stores raw biometric content
See COMPLIANCE.md for the full deployer checklist.
Does it replace mem0 / supermemory?
No — they compose. vemem owns visual identity (image → entity id); mem0 / supermemory own text-conversational memory. Typical pipeline:
image → VLM → scene text ─┐
→ vemem → entity_id ├──► LLM
mem0.search(user_id=entity_id) → facts about that entity ─┘
The entity_id vemem returns becomes the user_id mem0 keys on. Most serious multimodal agents will want both.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vemem-0.1.0.tar.gz.
File metadata
- Download URL: vemem-0.1.0.tar.gz
- Upload date:
- Size: 653.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6268add0aeda0a7e72edf0a3e6312c10f2f68c7fd39266ab6411fbac61522d02
|
|
| MD5 |
0a32ef885ad5c10dee1009939c0db648
|
|
| BLAKE2b-256 |
97c78a6a5ead20b66b1aaf1349db63008d784d999c1a8b9e3b1b7ab067da0e3a
|
File details
Details for the file vemem-0.1.0-py3-none-any.whl.
File metadata
- Download URL: vemem-0.1.0-py3-none-any.whl
- Upload date:
- Size: 85.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae499a827b841833c10204df7a5998ce5b9d49cbb695cfc4d010ba1ba629de17
|
|
| MD5 |
0f387dbba6ec445b3c8143476410d706
|
|
| BLAKE2b-256 |
218d11a1b5df8b14ea9934a8bf91d986b9e263d7b5c1d48fb5c8b062d5bf7cd2
|