装完服务端还不够,必须在 AGENTS.md/CLAUDE.md 等常驻文件里写明何时调用,否则宿主会忽略 MCP 工具描述;两个及以上客户端必须共用一个 HTTP 服务,配置不同的第二个进程会直接失败;Hermes 只能用原生 wax-memory provider,不要再注册 mcp_servers.wax,也不要把它加进 plugins.enabled。
Wax
christopherkaraniApache-2.0活跃维护纯 Swift 实现的单文件记忆层,让多个 Agent 在 Apple Silicon 上本地完成文本、图片和视频的亚毫秒级 RAG 检索,无需服务器和 API。
Shared Single-file memory layer for all your agents, sub mili-second RAG over text, photo and video on Apple Silicon.. No Server. No API. One File. Pure Swift
npx -y waxmcp@latest installREADME 未说明具体显存或内存要求;定位为 Apple Silicon 本地运行,支持 macOS、iOS、Linux 平台,Foundation Models 部分需 iOS 26 / macOS 26 且系统支持 Apple Intelligence。
给多个 AI 编码代理共用的单文件本地记忆层,在 Apple Silicon 上做亚毫秒级文本、图片和视频检索
纯 Swift 实现的单文件记忆层,让多个 Agent 在 Apple Silicon 上本地完成文本、图片和视频的亚毫秒级 RAG 检索,无需服务器和 API。
核心能力
- 所有代理共用同一个 .wax 文件读写记忆
- 文档、FTS5 全文检索、CoreML 向量和 WAL 都放在同一个文件里
- 通过 MCP 让 Claude、Codex、Cursor 等共享 http://127.0.0.1:3000/mcp
- remember 不调用 LLM 抽取事实,直接存句子再混合检索
- 为 Apple Foundation Models 提供 waxRemember/waxRecall/waxSearch 工具
容易踩的坑
- waxmcp-v0.1.48最新正式版2026-09-24 · 2026-09-24 00:27 UTC
What's Changed
- fix(mcp): release sockets when an HTTP client drops an SSE stream by @christopherkarani in https://github.com/christopherkarani/Wax/pull/241
- refactor(recall): keep git ancestry out of recall ranking by @christopherkarani in https://github.com/christopherkarani/Wax/pull/240
- refactor(broker): choose locks from one decoded command by @christopherkarani in https://github.com/christopherkarani/Wax/pull/239
Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.47...waxmcp-v0.1.48
- waxmcp-v0.1.472026-09-20 · 2026-09-20 21:29 UTC
查看更新说明
What's Changed
- fix(store): remember can retire multiple live twins without Invalid TOC by @christopherkarani in https://github.com/christopherkarani/Wax/pull/234
- fix(mcp): type auto-session write/recall scope policy by @christopherkarani in https://github.com/christopherkarani/Wax/pull/235
- refactor(broker): drive recall control from Hit.horizon and HitFlags by @christopherkarani in https://github.com/christopherkarani/Wax/pull/236
- refactor(broker): type corpus merge hits with CorpusOrigin by @christopherkarani in https://github.com/christopherkarani/Wax/pull/237
- fix(store): remember can commit when several replacements share one predecessor by @christopherkarani in https://github.com/christopherkarani/Wax/pull/238
Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.46...waxmcp-v0.1.47
- waxmcp-v0.1.462026-09-17 · 2026-09-17 02:33 UTC
查看更新说明
What's Changed
- refactor: deepen broker recall pipeline and collapse triple command catalog by @christopherkarani in https://github.com/christopherkarani/Wax/pull/213
- fix(mcp): stop coding skills from matching every Wax session by @christopherkarani in https://github.com/christopherkarani/Wax/pull/214
- feat(mcp): checkout-honest unique recall and a smaller daily playbook by @christopherkarani in https://github.com/christopherkarani/Wax/pull/232
- refactor: close recall identity so session scope requires a UUID by @christopherkarani in https://github.com/christopherkarani/Wax/pull/215
- VideoFile.id and VideoScope.assetIDs take VideoID by @christopherkarani in https://github.com/christopherkarani/Wax/pull/216
- refactor: type fact evidence and knowledge object at broker decode by @christopherkarani in https://github.com/christopherkarani/Wax/pull/217
- fix(mcp): bind working-session cache as UUID by @christopherkarani in https://github.com/christopherkarani/Wax/pull/222
- refactor(core): delete BinaryDecoder.decode force-cast trapdoor by @christopherkarani in https://github.com/christopherkarani/Wax/pull/223
- refactor(broker): close memory-search identity so working requires a session by @christopherkarani in https://github.com/christopherkarani/Wax/pull/225
- refactor(media): carry PhotoID and VideoID through ingest fileMissing errors by @christopherkarani in https://github.com/christopherkarani/Wax/pull/226
- refactor(broker): run MCP search through BrokerRecall snapshot by @christopherkarani in https://github.com/christopherkarani/Wax/pull/227
- refactor(mcp): close response verbosity as a package enum by @christopherkarani in https://github.com/christopherkarani/Wax/pull/228
- refactor(broker): close knowledge-capture graph writes at decode by @christopherkarani in https://github.com/christopherkarani/Wax/pull/229
- refactor(broker): type session_open bootstrap off the wire bag by @christopherkarani in https://github.com/christopherkarani/Wax/pull/230
- refactor(rag): close retrieval diagnostics so hybrid effective requires an embedding by @christopherkarani in https://github.com/christopherkarani/Wax/pull/231
- feat(memory): owner card from remember, person-lane reads it by @christopherkarani in https://github.com/christopherkarani/Wax/pull/233
Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.45...waxmcp-v0.1.46
- waxmcp-v0.1.452026-09-12 · 2026-09-12 16:48 UTC
查看更新说明
What's Changed
- fix(search): rank recent lexical facts above old vector neighbors by @christopherkarani in https://github.com/christopherkarani/Wax/pull/209
- docs(mcp): stop telling agents to pick recall mode by @christopherkarani in https://github.com/christopherkarani/Wax/pull/210
- Make coding MCP remember/recall/stats without unsafe per-chat identity by @christopherkarani in https://github.com/christopherkarani/Wax/pull/211
- Collapse fragmented host registry into MCPHostRegistry by @christopherkarani in https://github.com/christopherkarani/Wax/pull/212
Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.42...waxmcp-v0.1.45
- waxmcp-v0.1.422026-09-11 · 2026-09-11 04:58 UTC
查看更新说明
What's Changed
- fix(mcp): wait for MiniLM on first recall and teach session_open by @christopherkarani in https://github.com/christopherkarani/Wax/pull/180
- refactor(broker): type MemoryID for horizon-scoped frame refs by @christopherkarani in https://github.com/christopherkarani/Wax/pull/181
- refactor(search): store LoadedVectorSearchEngine as the production backend by @christopherkarani in https://github.com/christopherkarani/Wax/pull/182
- refactor(orchestrator): capture batch/query-aware embedders at attach by @christopherkarani in https://github.com/christopherkarani/Wax/pull/183
- refactor(broker): close remember writes as session vs durable destinations by @christopherkarani in https://github.com/christopherkarani/Wax/pull/184
- refactor(search): inject ranking nowMs and extract UnifiedRanking by @christopherkarani in https://github.com/christopherkarani/Wax/pull/185
- refactor(rag): extract RecallAssembly.pack from FastRAGContextBuilder by @christopherkarani in https://github.com/christopherkarani/Wax/pull/186
- fix(mcp): daily catalog hide + playbook lockstep by @christopherkarani in https://github.com/christopherkarani/Wax/pull/188
- fix(mcp): rebind live sessions, harvest reasons, startup GC by @christopherkarani in https://github.com/christopherkarani/Wax/pull/189
- fix(mcp): recall tells the truth; writes land in the right store by @christopherkarani in https://github.com/christopherkarani/Wax/pull/190
- refactor(broker): extract EndedSessionStore from AgentBrokerService by @christopherkarani in https://github.com/christopherkarani/Wax/pull/187
- docs: drop disabled GitHub Discussions link by @christopherkarani in https://github.com/christopherkarani/Wax/pull/191
- docs(mcp): teach agents to learn lessons and user facts by @christopherkarani in https://github.com/christopherkarani/Wax/pull/192
- fix: make Wax MCP agent memory reliable by default by @christopherkarani in https://github.com/christopherkarani/Wax/pull/195
- refactor(rag): use injected nowMs for FastRAG and orchestrator writes by @christopherkarani in https://github.com/christopherkarani/Wax/pull/193
- refactor(search): extract SearchPlan and package-visible RRF fusion by @christopherkarani in https://github.com/christopherkarani/Wax/pull/194
- fix(mcp): stop unresolved session search leaking foreign durable by @christopherkarani in https://github.com/christopherkarani/Wax/pull/196
- fix(mcp): close omit-id, empty handoff, ranking, and mute broker by @christopherkarani in https://github.com/christopherkarani/Wax/pull/199
- fix(mcp): keep session_open handoff, isolate person-lane, reclaim abandoned sessions by @christopherkarani in https://github.com/christopherkarani/Wax/pull/200
- Share access-ranking window; require FastRAG evaluation clock by @christopherkarani in https://github.com/christopherkarani/Wax/pull/198
- Extract SessionOpenDecision from broker sessionOpen by @christopherkarani in https://github.com/christopherkarani/Wax/pull/197
- SearchLane: prove vector-only search has an embedding by @christopherkarani in https://github.com/christopherkarani/Wax/pull/201
- Parse MemoryID and fact types at broker decode by @christopherkarani in https://github.com/christopherkarani/Wax/pull/202
- PhotoID: match VideoID on the experimental photo facade by @christopherkarani in https://github.com/christopherkarani/Wax/pull/205
- Default embedQuery and batch on EmbeddingProvider by @christopherkarani in https://github.com/christopherkarani/Wax/pull/206
- docs(readme): lead with MCP install and Foundation Models by @christopherkarani in https://github.com/christopherkarani/Wax/pull/207
- Extract broker presentation from AgentBrokerService by @christopherkarani in https://github.com/christopherkarani/Wax/pull/208
Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.26...waxmcp-v0.1.42
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
npx -y waxmcp@latest install
That stages the MCP server, MiniLM runtime, and operator skill on Apple Silicon. Wire one host, paste the playbook, and the next session can remember / recall. If this is the memory layer you wanted, star the repo so other agents find it.
What Wax is
Wax is a shared memory file for agents and on-device models.
Claude Code ─┐
Codex ───────┤
Cursor ──────┼─ MCP ─→ one HTTP writer ─→ ~/.wax/memory.wax
Grok ────────┤
OpenClaw ────┘
Hermes ──────── native wax-memory provider ─↗
iPhone / Mac app ── Memory + Foundation Models tools ─↗
The store is one file. Documents, FTS5 text search, CoreML vectors, and a WAL live inside it. iCloud or AirDrop the file to another Mac or iPhone. Identical MCP servers share one broker daemon automatically; a differently-configured second process fails fast with sharing guidance, so two or more hosts share http://127.0.0.1:3000/mcp.
What you get that a host scratchpad does not:
- Claude, Codex, Cursor, and Hermes read and write the same memories.
rememberdoes not call an LLM to extract facts. You store a sentence; hybrid search finds it later.- Apple Foundation Models get
waxRemember/waxRecall/waxSearchas on-device tools. - Hermes can drop
MEMORY.mdcuration and use the nativewax-memoryprovider (handoffs, turn sync,wax_remember/wax_recall).
Host playbook: wax-mcp-hosts.md
Agent Quick Start
Give Claude Code, Cursor, Codex, Hermes, OpenClaw, Muse Code, or Windsurf a memory that survives the chat.
Installing the server is not enough. Hosts ignore MCP tool descriptions unless an always-on file says when to write. Paste a block below after you wire the host.
1. Stage the server once
npx -y waxmcp@latest install
Claude-only can use stdio. Two or more clients must share one HTTP server on http://127.0.0.1:3000/mcp. A differently-configured second process on ~/.wax/memory.wax fails fast instead of locking silently.
| Host | Wire-up |
|---|---|
| Claude Code | swift run --traits MCPServer wax-cli mcp install --scope user then claude install-skill ~/.local/share/waxmcp/skills/wax-mcp |
| Codex | wax-cli mcp install prints the stdio block (writes it with --write-toml-config) + copies the skill; manual: [mcp_servers.wax] url = "http://127.0.0.1:3000/mcp" in ~/.codex/config.toml |
| Cursor | wax-cli mcp install merges the stdio entry automatically; manual: { "mcpServers": { "wax": { "url": "http://127.0.0.1:3000/mcp" } } } in ~/.cursor/mcp.json + paste the AGENTS.md block |
| Hermes | Native memory.provider: wax-memory only. npx -y waxmcp@latest install-hermes-plugin, then hermes config set memory.provider wax-memory. Daily tools: wax_remember / wax_recall (no Wax UUID). Do not add wax-memory to plugins.enabled. Do not also register mcp_servers.wax. |
| OpenClaw | HTTP + memory plugin + paste the SOUL.md stanza into the workspace SOUL.md; replace an existing ## Memory (Wax) section |
| Muse Code | wax-cli mcp install registers Muse automatically (unless --skip-muse); manual: mcp_servers.wax in ~/.config/muse/settings.json (schema_version: 1): stdio wax-cli mcp serve when solo, shared http://127.0.0.1:3000/mcp when two or more clients + paste the AGENTS.md block |
| Anything else | HTTP URL + paste the AGENTS.md block into project AGENTS.md |
Keep HTTP up with ~/.local/share/waxmcp/bin/start-wax-mcp-http.sh or LaunchAgent ai.wax.mcp-http. Prove it with npx -y waxmcp@latest vector-health, npx -y waxmcp@latest doctor (wax-cli mcp doctor), hermes wax-memory doctor, and hermes plugins doctor wax-memory. Native recall defaults to the current project; pass scope=global for person facts. Global is not an authorization boundary.
Full snippets, LaunchAgent ai.wax.mcp-http, vector-health, Hermes doctors, and a smoke test: Resources/docs/wax-mcp-hosts.md.
The wax-mcp skill is install/doctor only. The wax skill is Swift SDK integration. Daily memory follows MCP server instructions, not either skill.
2. Teach the model when to use Wax
Pick the file your host actually loads on every turn.
Use the project or user AGENTS.md, CLAUDE.md, or .cursor/rules. Same text as Resources/skills/public/wax-mcp/references/project-rules.md.
Follow the live Wax MCP server instructions for `remember`, `recall`, and `stats`. Do not invent a `session_id`. Do not load the `wax` or `wax-mcp` skills at session start. `wax` is Swift SDK only; `wax-mcp` is install/doctor only.
OpenClaw: the workspace SOUL.md. Native Hermes already owns session lifecycle. Call wax_remember / wax_recall / wax_stats. Do not pass a Wax session_id. Do not paste the MCP session_open loop. Omit mode unless you need an override. Omit scope for current-project recall; pass scope=global for person facts. Empty project recall is a miss. Do not add wax-memory to plugins.enabled.
SOUL.md is identity. Append this section if missing. If ## Memory (Wax) already exists, replace that section. Do not replace the rest of the soul.
## Memory (Wax)
You have Wax. Follow the live MCP server instructions for `remember`, `recall`, and `stats`. Do not invent a `session_id`. Do not load wax-mcp at session start.
Native Hermes already owns session lifecycle. Call wax_remember / wax_recall / wax_stats. Do not pass a Wax session_id. Do not paste the MCP session_open loop. Omit mode unless you need an override. Omit scope for current-project recall; pass scope=global for person facts. Empty project recall is a miss. Do not add wax-memory to plugins.enabled. OpenClaw still pastes the SOUL.md stanza.
Grokbot runs locally on your Mac, so Wax serves it over loopback. No tunnel. No cloud copy of your memory.
One-time setup:
# 1. Stage Wax
npx -y waxmcp@latest install
# 2. Start the server and keep it running (add to your shell profile / login items)
~/.local/share/waxmcp/bin/start-wax-mcp-http.sh
Then in Grokbot: Settings → Plugins → Add MCP server
| Field | Value |
|---|---|
| Name | wax |
| URL | http://127.0.0.1:3000/mcp |
Finally, paste this prompt into your main (coordinator) bot. It sets up its own memory and rolls Wax out to every bot on the team:
You have a memory tool server called "wax". Follow its live MCP server instructions for remember, recall, and stats. Do not invent a session_id. Do not load the wax-mcp skill at session start. Never store passwords, tokens, or secrets. If the wax tools are missing, stop and tell me instead of improvising.
Roll out to the team:
1. List every bot we already have. For each one, tell it to follow the live Wax MCP server instructions, then verify it can see the wax tools (have it run the wax stats tool) and report back which bots succeeded and which failed.
2. From now on, whenever you spawn a new bot, point it at those same live server instructions before it begins any work.
3. Save this policy in wax as memory_type user_preference so you keep enforcing it across sessions.
The .wax file stays on the machine. The loopback bind is unreachable from outside. Full host playbook: Resources/docs/wax-mcp-hosts.md.
Operator notes (not a third playbook): Daily tools are remember, recall, and stats. A successful remember returns committed true. Ignore leftover_reasons on close. WAX_MCP_TOOLS=legacy: session_open with recall_query is enough.
Host install path (LaunchAgent ai.wax.mcp-http, vector-health, Hermes
doctors, recovery): Resources/docs/wax-mcp-hosts.md.
Claude/doctor details: Resources/docs/wax-mcp-setup.md.
Foundation Models (iOS 26 / macOS 26)
Apple's on-device LanguageModelSession generates text. It does not keep a store across launches. Wax is that store: recall into the prompt, register memory tools, optionally write turns back.
Requires Apple Intelligence where the system model is available. Guard with #if canImport(FoundationModels) and WaxFoundationModelsAvailability.current(). Compilation on a machine without Apple Intelligence is not a successful respond.
import Foundation
import FoundationModels
import Wax
@available(iOS 26.0, macOS 26.0, *)
func chatWithMemory() async throws {
let url = URL.documentsDirectory.appending(path: "assistant.wax")
let memory = try await Memory(at: url)
let session = memory.foundationModelsSession(
instructions: "You are a helpful assistant with durable on-device memory."
)
switch WaxFoundationModelsAvailability.current() {
case .available:
let answer = try await session.respond(
to: "I prefer dark mode and Vim keybindings."
)
print(answer)
case .unavailable(let reason):
print("Foundation Models unavailable: \(reason)")
}
try await session.close() // does not close `memory`
try await memory.close()
}
foundationModelsSession is synchronous. It captures the Memory handle. Closing the session leaves the store open so other screens can share it.
Default config is hybrid:
| Piece | Behavior |
|---|---|
| Prompt | Recalls related memory and injects a <wax_memory> block |
| Tools | waxRemember, waxRecall, waxSearch (.focused kit) |
| Turns | Writes user and assistant turns when persistencePolicy allows it |
Attach tools to your own LanguageModelSession:
let tools = memory.foundationModelsTools(kit: .focused)
let session = LanguageModelSession(tools: tools) {
"You have long-term memory via waxRemember / waxRecall / waxSearch."
}
Kits: .focused (default), .compact, .combined, .focusedWithForget. Full walkthrough: Foundation Models.
Swift app
Same engine inside an iOS or macOS app. No MCP process required.
// Package.swift
dependencies: [
.package(url: "https://github.com/christopherkarani/Wax.git", from: "0.1.47")
]
Or in Xcode: File → Add Package Dependencies → https://github.com/christopherkarani/Wax.git
import Foundation
import Wax
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
print("Found: \(best.text)")
}
try await memory.close()
Memory(at:) auto-configures the on-device MiniLM embedder on iOS 18 / macOS 15+ (default MiniLMEmbeddings trait). Hybrid search is text until the embedder attaches; vectorOnly throws. Check results.diagnostics and memory.stats().
import SwiftUI
import Wax
struct ContentView: View {
@State private var result = "Searching…"
var body: some View {
Text(result)
.task {
do {
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let context = try await memory.search("What is the user building?")
result = context.items.first?.text ?? "Nothing found"
try await memory.close()
} catch {
result = "Error: \(error.localizedDescription)"
}
}
}
}
Experimental Darwin facades: PhotoMemory / VideoMemory (OCR, keyframes, host-supplied transcripts; video does not store media bytes). Structured entities and facts are MCP/broker tools today (entity_upsert, fact_assert, facts_query). The Swift CRUD API for that graph is package-internal.
Public surface: public-api.md. iOS docs: christopherkarani.github.io/Wax.
Run the demo
Resources/WaxDemo stress-tests Memory (save/search durability, embeddings, Foundation Models, errors). macOS 26 for the demo package; Foundation Models mode needs Apple Intelligence.
cd Resources/WaxDemo
swift run WaxDemo --mode all
| Mode | What it runs |
|---|---|
memory | Save → search → close → reopen → search |
embeddings | Built-in MiniLM + hybrid/vector search |
fm | Foundation Models memory session (or a clear unavailable message) |
all | Default |
swift run WaxDemo --mode fm --keep --store /tmp/wax-demo.wax
Why this instead of what you already have
| Job | Typical option | Wax |
|---|---|---|
| Scratchpad the host already has | MEMORY.md / USER.md / CLAUDE.md | Searchable across sessions and projects. Agents write lessons as they happen. You do not maintain the markdown by hand. |
| Hosted memory API | Mem0, SuperMemory, and similar | One file on disk. No account. remember does not call a cloud LLM to extract facts. |
| Markdown MCP | Basic Memory and similar | Binary store with FTS5 + CoreML vectors + WAL. AirDrop the file. Same MCP session loop. |
| Knowledge graph platform | Graphiti, Cognee | Different product: those want Neo4j/Postgres and an LLM for ingest. Wax is a local file plus an agent session loop. |
| Single-file RAG | Memvid .mv2 and similar | Wax adds MCP remember / recall / stats, a native Hermes provider, and Foundation Models tools. |
| Cloud vector DB | Pinecone, hosted Qdrant | Hybrid text + vector on Apple Silicon. p95 hybrid recall 6.1 ms on the 2026-03-06 M-series sweep. |
Wax is the shared local store. It does not replace a temporal knowledge graph, and it does not claim LoCoMo numbers it has not published.
Performance
Measured on Apple Silicon, 2026-03-06. Full report: Resources/docs/benchmarks/2026-03-06-performance-results.md.
Hybrid recall p95 6.1 ms
Hybrid recall p99 6.5 ms
Cold open p95 9.2 ms
Cold open is store open only. The built-in embedder's first CoreML compile is a separate one-time cost; later launches reuse the cached compiled model.
Text search works with no embedder. Semantic search auto-configures MiniLM on iOS 18 / macOS 15+. The CLI and MCP server fail loud when hybrid/vector is requested without an embedder. The Swift SDK reports the mode that ran via results.diagnostics.
Architecture
Wax bundles documents, metadata, and indexes in one binary. SQLite FTS5 for text. Metal-accelerated HNSW for vectors once an index holds 10,000+ vectors; smaller indexes use an exact Accelerate/CPU flat index with the same recall.
┌──────────────────────────────────────────────────────────────────────────┐
│ Dual Header Pages (A/B) │
│ (Magic, Version, Generation, Pointers to WAL & TOC, Checksums) │
├──────────────────────────────────────────────────────────────────────────┤
│ WAL (Write-Ahead Log) │
│ (Atomic ring buffer for crash-resilient uncommitted mutations) │
├──────────────────────────────────────────────────────────────────────────┤
│ Compressed Data Frames │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Frame 0 (LZ4) │ │ Frame 1 (LZ4) │ │ Frame 2 (LZ4) │ ... │
│ │ [Raw Document] │ │ [Metadata/JSON] │ │ [System Info] │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ Hybrid Search Indices │
│ ┌──────────────────────────────┐ ┌──────────────────────────────┐ │
│ │ SQLite FTS5 Blob │ │ Metal HNSW Index │ │
│ │ (Text Search + EAV Facts) │ │ (Vector Search) │ │
│ └──────────────────────────────┘ └──────────────────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ TOC (Table of Contents) │
│ (Index of all frames, parent-child relations, and engine manifests) │
└──────────────────────────────────────────────────────────────────────────┘
Dual headers and the WAL keep the store consistent if the process dies mid-write. One query fans out to BM25 and HNSW. EAV facts ship through MCP tools.
FAQ
Do I need the internet?
No. Memory stays on device. The npm installer fetches the staged binaries once.
How big is the file?
LZ4-compressed frames. Typical use is a few MB for thousands of documents.
Can I sync across devices?
Yes. iCloud Drive, Dropbox, AirDrop. One file.
What if the app crashes during a write?
WAL plus dual headers. The next open recovers.
Does this run on Intel Macs?
The engine can run via Rosetta. Metal vector acceleration and the waxmcp npm package target Apple Silicon. Build wax-cli from source on Intel.
I get "embedder unavailable" on hybrid search.
Hybrid and vector need a local embedding model. Swift Memory(at:) loads MiniLM on iOS 18 / macOS 15+, or set Memory.Config.embedding = .custom(...). Older OS: text-only or bring your own embedder. CLI/MCP fail loud; Swift reports the effective mode on diagnostics.
Two agents time out on the same store.
One writer. Start ~/.local/share/waxmcp/bin/start-wax-mcp-http.sh and point every host at http://127.0.0.1:3000/mcp.
Community
License
Apache License 2.0. See LICENSE.