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

waxmcp-v0.1.48发布于 2026-09-24 00:27 UTC809star +1 / 7 天55fork同步于 2026-11-10 17:55 UTC

怎么上手

由 README 提炼,执行前请确认
npx -y waxmcp@latest install
硬件要求按 README 说明

README 未说明具体显存或内存要求;定位为 Apple Silicon 本地运行,支持 macOS、iOS、Linux 平台,Foundation Models 部分需 iOS 26 / macOS 26 且系统支持 Apple Intelligence。

支持 Apple Silicon
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

给多个 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 工具

容易踩的坑

装完服务端还不够,必须在 AGENTS.md/CLAUDE.md 等常驻文件里写明何时调用,否则宿主会忽略 MCP 工具描述;两个及以上客户端必须共用一个 HTTP 服务,配置不同的第二个进程会直接失败;Hermes 只能用原生 wax-memory provider,不要再注册 mcp_servers.wax,也不要把它加进 plugins.enabled。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本waxmcp-v0.1.48
  1. waxmcp-v0.1.48最新正式版2026-09-24 · 2026-09-24 00:27 UTC

    What's Changed

    Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.47...waxmcp-v0.1.48

  2. waxmcp-v0.1.472026-09-20 · 2026-09-20 21:29 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.46...waxmcp-v0.1.47

  3. waxmcp-v0.1.462026-09-17 · 2026-09-17 02:33 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.45...waxmcp-v0.1.46

  4. waxmcp-v0.1.452026-09-12 · 2026-09-12 16:48 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.42...waxmcp-v0.1.45

  5. waxmcp-v0.1.422026-09-11 · 2026-09-11 04:58 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/christopherkarani/Wax/compare/waxmcp-v0.1.26...waxmcp-v0.1.42

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译
    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.
    • remember does not call an LLM to extract facts. You store a sentence; hybrid search finds it later.
    • Apple Foundation Models get waxRemember / waxRecall / waxSearch as on-device tools.
    • Hermes can drop MEMORY.md curation and use the native wax-memory provider (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.

    HostWire-up
    Claude Codeswift run --traits MCPServer wax-cli mcp install --scope user then claude install-skill ~/.local/share/waxmcp/skills/wax-mcp
    Codexwax-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
    Cursorwax-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
    HermesNative 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.
    OpenClawHTTP + memory plugin + paste the SOUL.md stanza into the workspace SOUL.md; replace an existing ## Memory (Wax) section
    Muse Codewax-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 elseHTTP 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

    FieldValue
    Namewax
    URLhttp://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:

    PieceBehavior
    PromptRecalls related memory and injects a <wax_memory> block
    ToolswaxRemember, waxRecall, waxSearch (.focused kit)
    TurnsWrites 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
    
    ModeWhat it runs
    memorySave → search → close → reopen → search
    embeddingsBuilt-in MiniLM + hybrid/vector search
    fmFoundation Models memory session (or a clear unavailable message)
    allDefault
    swift run WaxDemo --mode fm --keep --store /tmp/wax-demo.wax
    

    Why this instead of what you already have

    JobTypical optionWax
    Scratchpad the host already hasMEMORY.md / USER.md / CLAUDE.mdSearchable across sessions and projects. Agents write lessons as they happen. You do not maintain the markdown by hand.
    Hosted memory APIMem0, SuperMemory, and similarOne file on disk. No account. remember does not call a cloud LLM to extract facts.
    Markdown MCPBasic Memory and similarBinary store with FTS5 + CoreML vectors + WAL. AirDrop the file. Same MCP session loop.
    Knowledge graph platformGraphiti, CogneeDifferent product: those want Neo4j/Postgres and an LLM for ingest. Wax is a local file plus an agent session loop.
    Single-file RAGMemvid .mv2 and similarWax adds MCP remember / recall / stats, a native Hermes provider, and Foundation Models tools.
    Cloud vector DBPinecone, hosted QdrantHybrid 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.