{"id":48906220,"url":"https://github.com/t8/memoryport","last_synced_at":"2026-04-16T20:07:14.960Z","repository":{"id":348183118,"uuid":"1191050377","full_name":"t8/memoryport","owner":"t8","description":"Local-first permanent, persistent memory for all agents and humans","archived":false,"fork":false,"pushed_at":"2026-03-31T05:08:37.000Z","size":2102,"stargazers_count":72,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-31T07:40:59.587Z","etag":null,"topics":["agents","context-window","llms"],"latest_commit_sha":null,"homepage":"https://memoryport.ai","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t8.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-24T21:49:42.000Z","updated_at":"2026-03-31T07:17:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/t8/memoryport","commit_stats":null,"previous_names":["t8/memoryport"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/t8/memoryport","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t8%2Fmemoryport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t8%2Fmemoryport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t8%2Fmemoryport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t8%2Fmemoryport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t8","download_url":"https://codeload.github.com/t8/memoryport/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t8%2Fmemoryport/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31902201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"ssl_error","status_checked_at":"2026-04-16T18:21:47.142Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","context-window","llms"],"created_at":"2026-04-16T20:07:14.018Z","updated_at":"2026-04-16T20:07:14.954Z","avatar_url":"https://github.com/t8.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\".github/banner.jpg\" alt=\"Memoryport — Permanent memory for any LLM\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://memoryport.ai\"\u003eWebsite\u003c/a\u003e \u0026middot;\n  \u003ca href=\"https://github.com/t8/memoryport/releases\"\u003eDownload\u003c/a\u003e \u0026middot;\n  \u003ca href=\"https://github.com/t8/amp-spec\"\u003eAMP Spec\u003c/a\u003e\n\u003c/p\u003e\n\nMemoryport gives LLMs persistent, queryable memory using [Arweave](https://arweave.org) for permanent storage and [LanceDB](https://lancedb.com) for local vector search. Every conversation is stored permanently and retrieved semantically — so your AI never forgets.\n\nWorks with **Claude Code**, **Cursor**, **Open WebUI**, **Ollama**, and any OpenAI-compatible tool.\n\n## Install\n\n### Desktop App\n\nDownload the latest release for your platform:\n\n| Platform | Download |\n|----------|----------|\n| **macOS** (Apple Silicon \u0026 Intel) | [Download .dmg](https://memoryport.ai/api/download?platform=mac) |\n| **Linux** (x64) | [Download .AppImage](https://memoryport.ai/api/download?platform=linux) |\n\nThe desktop app includes a setup wizard, dashboard, and manages all services automatically.\n\n### CLI\n\n```bash\ncurl -fsSL https://memoryport.ai/install | sh\n```\n\nThen run the setup wizard:\n```bash\nuc init\n```\n\nThat's it. Restart your editor — Memoryport auto-captures conversations and surfaces relevant context.\n\n### Build from Source\n\n```bash\n# Prerequisites: Rust 1.91+, protoc (brew install protobuf), Node.js 18+, pnpm\ncargo build --release\ncd ui \u0026\u0026 pnpm install \u0026\u0026 pnpm build  # Dashboard\n```\n\n## Performance\n\n![Query Latency vs Context Space](tests/scale/performance_chart.png)\n\n**294ms query latency at 500M tokens** — brute force with 100% recall. No approximate indexing needed.\n\n| Context Space | Chunks | p50 Latency |\n|---|---|---|\n| 100K tokens | 266 | 1ms |\n| 1M tokens | 2,666 | 3ms |\n| 10M tokens | 26,666 | 9ms |\n| 100M tokens | 266,666 | 61ms |\n| 500M tokens | 1,333,333 | 294ms |\n\nTested with `nomic-embed-text` (768d, local via Ollama). Compacted LanceDB, no cloud APIs required.\n\n## Supported Integrations\n\n| Tool | Method | Setup |\n|------|--------|-------|\n| **Claude Code** | API Proxy | `uc init` configures automatically (sets `ANTHROPIC_BASE_URL`) |\n| **Cursor** | API Proxy | Set `ANTHROPIC_BASE_URL=http://127.0.0.1:9191` |\n| **Open WebUI** | Ollama Proxy | Set Ollama URL to `http://127.0.0.1:9191` in Settings → Connections |\n| **Ollama (terminal)** | Ollama Proxy | `OLLAMA_HOST=http://127.0.0.1:9191 ollama run llama3` |\n| **Continue.dev** | Ollama/OpenAI Proxy | Set endpoint to `http://127.0.0.1:9191` |\n| **Any OpenAI SDK app** | API Proxy | `OPENAI_BASE_URL=http://127.0.0.1:9191` |\n| **Claude Code (MCP)** | MCP Server | `uc init` registers MCP automatically |\n| **Cursor (MCP)** | MCP Server | `uc init` registers MCP automatically |\n\nThe proxy handles all three API formats on a single port (9191):\n- **Anthropic** `/v1/messages`\n- **OpenAI** `/v1/chat/completions`\n- **Ollama** `/api/chat`, `/api/generate`, `/api/tags`, and all `/api/*` routes\n\n## How It Works\n\nMemoryport supports two retrieval modes, configurable per-request:\n\n### Single-turn (default)\n\n```\nUser sends a message\n  │\n  ▼\nProxy intercepts transparently\n  │\n  ├─ Quality gating (skip greetings, commands, trivial queries)\n  ├─ Search memory for relevant context\n  ├─ Inject context into the message as plain text\n  ├─ Forward to LLM (Anthropic, OpenAI, Ollama)\n  ├─ Capture user message + assistant response\n  │   ├─ Sanitize (strip system prompts, internal commands)\n  │   ├─ Embed and store in LanceDB\n  │   └─ Optionally sync to Arweave (permanent storage)\n  └─ Return response to user\n```\n\n### Multi-turn (agentic retrieval)\n\n```\nUser sends a message\n  │\n  ▼\nProxy injects a memory search tool into the request\n  │\n  ├─ LLM decides what to search for and calls the tool\n  ├─ Proxy executes the search, returns results to LLM\n  ├─ LLM may search again (up to max_rounds)\n  ├─ LLM produces final response with full context\n  ├─ Capture and store conversation\n  └─ Return response to user\n```\n\nMulti-turn lets the model iteratively refine its memory queries — useful for complex questions that need multiple pieces of context. Toggle between modes in the dashboard Settings or via `[proxy.agentic] enabled` in config. See the [AMP specification](https://github.com/t8/amp-spec) for the protocol details.\n\n## Dashboard\n\nThe Tauri desktop app includes a full dashboard. For CLI users, run the stack manually:\n\n```bash\n./dev.sh start    # Build and start server + proxy + UI\n```\n\n**Pages:**\n- **Dashboard** — context space, indexed chunks, session browser, semantic search\n- **Analytics** — activity sparklines, storage growth, type/source distribution, sync status\n- **Integrations** — toggle MCP server, API proxy, Ollama capture on/off with live status\n- **Settings** — embedding provider, model, API key, smart gating, encryption, Arweave wallet\n\n## CLI\n\n```bash\nuc init                  # Interactive setup wizard\nuc store \"text\" -t knowledge  # Store a chunk\nuc query \"search term\"   # Full retrieval pipeline (gated + reranked + assembled)\nuc retrieve \"search\"     # Raw vector search (bypasses gating)\nuc proxy                 # Start the API proxy\nuc delete --tx-id \u003cid\u003e   # Logical deletion (destroy encryption key)\nuc rebuild-index -u \u003cid\u003e # Rebuild index from Arweave\nuc status                # Index stats\nuc flush                 # Flush pending writes\n```\n\n## MCP Tools\n\n| Tool | Description |\n|------|-------------|\n| `uc_auto_store` | Silently store a conversation turn (called automatically) |\n| `uc_store` | Store text with explicit metadata |\n| `uc_query` | Semantic search with full retrieval pipeline |\n| `uc_retrieve` | Raw ranked results |\n| `uc_get_session` | Full conversation history for a session |\n| `uc_list_sessions` | List all stored sessions |\n| `uc_status` | System status |\n\n## Configuration\n\n`~/.memoryport/uc.toml` (created by `uc init`):\n\n```toml\n[arweave]\ngateway = \"https://arweave.net\"\nturbo_endpoint = \"https://upload.ardrive.io\"\n# wallet_path = \"~/.memoryport/wallet.json\"\n\n[index]\npath = \"~/.memoryport/index\"\nembedding_dimensions = 768\n\n[embeddings]\nprovider = \"ollama\"              # or \"openai\"\nmodel = \"nomic-embed-text\"\ndimensions = 768\n\n[retrieval]\nmax_context_tokens = 50000\nsimilarity_top_k = 50\nrecency_window = 20\ngating_enabled = true            # Three-gate system: skip greetings, route by embedding, filter low quality\n# query_expansion = true         # LLM generates alternative search terms\n# hyde = true                    # Embed hypothetical answer instead of raw query\n# llm_model = \"gpt-4o-mini\"\n\n[encryption]\n# enabled = true\n# passphrase_env = \"UC_MASTER_PASSPHRASE\"\n\n[proxy]\nlisten = \"127.0.0.1:9191\"\n```\n\n## Architecture\n\n```\ncrates/\n├── uc-arweave/      # Arweave client (wallet, ANS-104, Turbo, GraphQL)\n├── uc-embeddings/   # Embedding + LLM providers (OpenAI, Ollama)\n├── uc-core/         # Core engine (chunk, index, retrieve, rerank, assemble, encrypt, gate)\n├── uc-cli/          # CLI binary with setup wizard\n├── uc-mcp/          # MCP server (stdio, 7 tools, 2 resources)\n├── uc-proxy/        # Multi-protocol API proxy (Anthropic + OpenAI + Ollama)\n├── uc-server/       # Multi-tenant hosted API server + dashboard\n└── uc-tauri/        # Tauri desktop app (macOS, Linux)\n\nui/                  # React 19 dashboard (Vite + Tailwind)\n```\n\n## Security\n\n- All data on Arweave is encrypted with AES-256-GCM (per-batch random keys)\n- Master key derived from passphrase via Argon2id\n- Logical deletion: destroy batch key → ciphertext permanently unreadable\n- Proxy sanitizes system prompts, internal commands, and meta-requests before storage\n\n## Deployment\n\n### Docker\n\n```bash\ndocker compose up\n```\n\nEnvironment variables:\n- `OPENAI_API_KEY` — for embeddings (if using OpenAI)\n- `UC_ADMIN_API_KEY` — admin API key for user management\n- `UC_SERVER_LISTEN` — listen address (default `0.0.0.0:8080`)\n- `UC_SERVER_DATA_DIR` — data directory (default `/var/lib/uc-server`)\n\n### Hosted API\n\n```bash\n# Create a user\ncurl -X POST http://localhost:8080/admin/users \\\n  -H \"Authorization: Bearer $UC_ADMIN_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"user@example.com\"}'\n# Returns: { \"user_id\": \"...\", \"api_key\": \"uc_...\" }\n\n# Store context\ncurl -X POST http://localhost:8080/v1/store \\\n  -H \"Authorization: Bearer uc_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\": \"Arweave uses pay-once permanent storage\", \"chunk_type\": \"knowledge\"}'\n\n# Query\ncurl -X POST http://localhost:8080/v1/query \\\n  -H \"Authorization: Bearer uc_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\": \"How does Arweave pricing work?\"}'\n```\n\n## Data Recovery\n\nIf you lose your local data or set up on a new machine, Pro users can rebuild their memory from Arweave:\n\n1. Install Memoryport on the new machine\n2. Open Settings → Arweave Storage\n3. Enter your API key\n4. Click \"Rebuild from Arweave\"\n\nAll encrypted batches are fetched from the permanent storage network and re-indexed locally. Your encryption key never leaves your machine — data is decrypted client-side during rebuild.\n\n## Benchmarks\n\n### LongMemEval (ICLR 2025)\n\nEvaluated on [LongMemEval](https://github.com/xiaowu0162/LongMemEval), a benchmark for long-term memory in chat assistants. Tests retrieval and answer accuracy on the standard split (`longmemeval_s`) with ~115K token haystacks per question.\n\n**Answer Accuracy** (full 500 questions, gpt-4o reader, gpt-4o-mini judge):\n\n| Category | Accuracy | Session Recall | n |\n|----------|----------|----------------|---|\n| single-session-assistant | **91.1%** | 87% | 56 |\n| single-session-user | **60.0%** | 56% | 70 |\n| knowledge-update | **53.3%** | 72% | 78 |\n| single-session-preference | **36.7%** | 53% | 30 |\n| temporal-reasoning | **27.1%** | 36% | 133 |\n| multi-session | **27.1%** | 47% | 133 |\n| **Overall** | **43.5%** | **61.1%** | **500** |\n\nNote: the full 500-question run places all questions' haystacks in a shared index (~250K chunks). In production, each user has an isolated index, which gives better retrieval quality — our 100-question runs (isolated context) consistently score 60-63%.\n\n**Session Recall** (48-question oracle split, local embeddings):\n\n| Category | Recall | n |\n|----------|--------|---|\n| knowledge-update | **100%** | 8 |\n| multi-session | **100%** | 8 |\n| single-session-user | **100%** | 8 |\n| single-session-assistant | **100%** | 8 |\n| single-session-preference | **100%** | 8 |\n| temporal-reasoning | **87.5%** | 8 |\n| **Overall** | **97.9%** | **48** |\n\nKey retrieval improvements validated across 41 experiments:\n- Temporal fallback (retry without time filter when too few results)\n- Date-enriched embeddings (prepend date to chunks before embedding)\n- Date-prefixed retrieve responses (LLMs see explicit dates per chunk)\n- Round-level conversation storage (user+assistant pairs as single embeddings)\n- Chronological session ordering in assembled context\n\nSee `tests/longmemeval/autoresearch/results.tsv` for the full experiment optimization log. Autoresearch framework (`tests/longmemeval/autoresearch/`) enables automated experiment iteration.\n\n### Stress Test (10K chunks)\n\n| Metric | Result |\n|--------|--------|\n| Insert throughput | 25 chunks/sec (1K) → 13 chunks/sec (10K) |\n| Retrieval accuracy | 91% recall@10 across 6 topic categories |\n| Query latency (p50) | 265ms (1K chunks), 361ms (oracle dataset) |\n| Index size | ~50MB at 10K chunks |\n\n### Three-Gate Retrieval Gating\n\nPrevents unnecessary retrieval on simple messages:\n\n| Gate | What it does | Latency |\n|------|-------------|---------|\n| Gate 1: Rules | Skip greetings, commands, short queries. Force memory references, temporal queries. | ~0ms |\n| Gate 2: Embedding routing | Compare query embedding against \"needs retrieval\" vs \"skip\" centroids. | ~0ms (reuses existing embedding) |\n| Gate 3: Quality threshold | Drop results below relevance score. | ~0ms (checks existing scores) |\n\n### Proxy Latency Overhead\n\nMeasures the latency added by the proxy in each mode using a mock upstream (50ms simulated LLM delay):\n\n| Mode | p50 | p95 | mean | Overhead vs direct |\n|------|-----|-----|------|--------------------|\n| Direct (no proxy) | 58ms | 61ms | 58ms | — |\n| Single-turn (context injection) | 108ms | 120ms | 107ms | +49ms |\n| Multi-turn (agentic loop, 1 round) | 139ms | 145ms | 139ms | +81ms |\n\nSingle-turn overhead is dominated by embedding + LanceDB search. Multi-turn adds one extra round trip to the upstream for tool execution.\n\nRun benchmarks yourself:\n```bash\n# LongMemEval session recall (oracle split, fast)\npython3 tests/longmemeval/run_benchmark.py --questions 50 --dataset oracle\n\n# LongMemEval answer accuracy (standard split, requires OpenAI API key)\npython3 tests/longmemeval/run_answer_accuracy.py --questions 100 --dataset s --answer-model gpt-4o\n\n# Autoresearch optimization loop (iterates experiments overnight)\npython3 tests/longmemeval/autoresearch/prepare.py --questions 100\n\n# Stress test\npython3 tests/stress/generate.py --chunks 10000\npython3 tests/stress/benchmark.py\n\n# Latency benchmark (requires mock upstream + proxy pointed at it)\npython3 tests/latency/mock_upstream.py --port 8199 \u0026\npython3 tests/latency/benchmark.py --proxy http://127.0.0.1:9292 --mock http://127.0.0.1:8199\n```\n\n## Comparison\n\nHow Memoryport compares to other AI memory tools:\n\n|  | **Memoryport** | **Supermemory** | **claude-mem** |\n|--|---------------|----------------|----------------|\n| **Architecture** | Local-first + permanent backup | Cloud SaaS | Local plugin |\n| **Language** | Rust | TypeScript | TypeScript |\n| **Storage** | LanceDB (local) + Arweave (permanent) | PostgreSQL (their cloud) | SQLite (local only) |\n| **Encryption** | AES-256-GCM per-batch, Argon2id key | Delegated to cloud infra | None |\n| **Data ownership** | You (local + on-chain) | Them (cloud) | You (local files) |\n| **Multi-tool** | Proxy + MCP (Claude Code, Cursor, Ollama, OpenAI) | API-based | Claude Code only |\n| **Capture method** | Transparent API proxy (zero-config) | Explicit API calls | Lifecycle hooks |\n| **Desktop app** | Signed Tauri native app | None (web only) | Localhost web viewer |\n| **Open protocol** | [AMP](https://github.com/t8/amp-spec) | No | No |\n| **Self-hosting** | Default (runs locally) | Enterprise only | Default (runs locally) |\n| **Scale benchmark** | 500M tokens, 294ms p50 | Not published | Not published |\n| **Retrieval accuracy** | 43.5% answer accuracy / 500q, 97.9% session recall (LongMemEval) | 84.6% answer accuracy (LongMemEval, GPT-5) | Not published |\n| **Permanent storage** | Arweave (pay once, stored forever) | No | No |\n| **License** | Apache-2.0 | MIT | AGPL-3.0 |\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft8%2Fmemoryport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft8%2Fmemoryport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft8%2Fmemoryport/lists"}