christopherkarani

Wax

Built by christopherkarani β€’ 674 stars

What is Wax?

Single-file memory layer for AI agents, sub mili-second RAG on Apple Silicon. Metal Optimized On-Device. No Server. No API. One File. Pure Swift

How to use Wax?

1. Install a compatible MCP client (like Claude Desktop). 2. Open your configuration settings. 3. Add Wax using the following command: npx @modelcontextprotocol/wax 4. Restart the client and verify the new tools are active.
πŸ›‘οΈ Scoped (Restricted)
npx @modelcontextprotocol/wax --scope restricted
πŸ”“ Unrestricted Access
npx @modelcontextprotocol/wax

Key Features

Native MCP Protocol Support
Real-time Tool Activation & Execution
Verified High-performance Implementation
Secure Resource & Context Handling

Optimized Use Cases

Extending AI models with custom local capabilities
Automating system workflows via natural language
Connecting external data sources to LLM context windows

Wax FAQ

Q

Is Wax safe?

Yes, Wax follows the standardized Model Context Protocol security patterns and only executes tools with explicit user-granted permissions.

Q

Is Wax up to date?

Wax is currently active in the registry with 674 stars on GitHub, indicating its reliability and community support.

Q

Are there any limits for Wax?

Usage limits depend on the specific implementation of the MCP server and your system resources. Refer to the official documentation below for technical details.

Official Documentation

View on GitHub
<!-- HEADER:START --> <div align="center"> <a href="https://trendshift.io/repositories/21759?utm_source=trendshift-badge&amp;utm_medium=badge&amp;utm_campaign=badge-trendshift-21759" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/21759/daily?language=Swift" alt="christopherkarani%2FWax | Trendshift" width="250" height="55"/></a> <img src="Resources/docs/assets/wax-logo.png" width="500" alt="Wax β€” a single-file memory layer for AI agents"> </div> <div style="height: 16px;"></div> <p align="center"> <strong>Give your AI agent a memory that never forgets.</strong><br/> One file. Zero cloud. Blazing fast recall on Apple Silicon. </p> <p align="center"> <a href="https://github.com/christopherkarani/Wax/releases"><img src="https://img.shields.io/github/v/release/christopherkarani/Wax?style=flat-square&logo=swift&logoColor=white&label=Swift" alt="Swift" /></a> <a href="https://developer.apple.com/ios/"><img src="https://img.shields.io/badge/platform-iOS%20%7C%20macOS-lightgrey?style=flat-square" alt="Platforms" /></a> <a href="https://github.com/christopherkarani/Wax/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square" alt="License" /></a> <a href="https://github.com/christopherkarani/Wax/stargazers"><img src="https://img.shields.io/github/stars/christopherkarani/Wax?style=flat-square&logo=github" alt="Stars" /></a> </p> <p align="center"> <a href="README.md">English</a> Β· <a href="Resources/locales/README.es.md">EspaΓ±ol</a> Β· <a href="Resources/locales/README.fr.md">FranΓ§ais</a> Β· <a href="Resources/locales/README.ja.md">ζ—₯本θͺž</a> Β· <a href="Resources/locales/README.ko.md">ν•œκ΅­μ–΄</a> Β· <a href="Resources/locales/README.pt.md">PortuguΓͺs</a> Β· <a href="Resources/locales/README.zh-CN.md">δΈ­ζ–‡</a> </p> <!-- HEADER:END -->

What is Wax?

Wax is a Swift-native memory engine for AI agents. It stores documents, embeddings, and structured knowledge in a single .wax file that lives entirely on your device.

No servers. No API keys. No Docker. Just one file you can AirDrop, sync, or back up like any other document.

import Wax

let memory = try await Memory(at: url)
try await memory.save("The user prefers dark mode and uses Vim keybindings.")
let results = try await memory.search("What editor does the user like?")
// β†’ "The user prefers dark mode and uses Vim keybindings."
<p align="center"> <img src="Resources/docs/assets/demo-terminal.svg" width="720" alt="Wax CLI Demo"> </p>

What you can build

  • Persistent chatbots β€” Your assistant remembers every conversation, preference, and decision across sessions.
  • Coding agents with long-term memory β€” Claude Code or Cursor that recalls your codebase patterns, architectural decisions, and TODOs from last week.
  • Personal knowledge bases β€” Semantic search over your notes, documents, and web clips. Ask "What did I read about HNSW?" and get the exact paragraph.
  • On-device RAG β€” Ship AI features in your iOS or macOS app without calling the cloud.

Choose Your Path

Wax meets you where you are. Pick the path that matches what you're building:

πŸ› οΈ Swift Developer⌨️ CLI Power UserπŸ€– AI Agent Setup
You want: Embed memory in your iOS/macOS app or Swift tool.You want: A command-line memory store you can script against.You want: Your AI assistant (Claude Code, Cursor, etc.) to remember context across sessions.
Get started: Swift Quick Start ↓Get started: CLI Quick Start ↓Get started: Agent Quick Start ↓

Swift Quick Start

1. Add Wax to your project

Swift Package Manager

// Package.swift
dependencies: [
    .package(url: "https://github.com/christopherkarani/Wax.git", from: "0.1.8")
]

Or in Xcode: File β†’ Add Package Dependencies β†’ https://github.com/christopherkarani/Wax.git

2. Copy-paste this into your app

import Foundation
import Wax

let url = URL.documentsDirectory.appending(path: "agent.wax")

// Open a memory store
let memory = try await Memory(at: url)

// Save something
try await memory.save("The user is building a habit tracker in SwiftUI.")

// Recall it later β€” works even if the app was killed
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
    print("Found: \(best.text)")
    // β†’ "Found: The user is building a habit tracker in SwiftUI."
}

try await memory.close()
<details> <summary><strong>SwiftUI example</strong></summary>
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)"
                }
            }
    }
}
</details> <details> <summary><strong>CLI tool (<code>main.swift</code>)</strong></summary>
import Foundation
import Wax

@main
struct AgentMemory {
    static func main() async throws {
        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()
    }
}
</details>

Looking to store persistent facts and long-term reasoning? See Structured Memory.


CLI Quick Start

1. Install

# Build from source (requires Swift 6+)
git clone https://github.com/christopherkarani/Wax.git
cd Wax
swift build -c release

# The binary is now at .build/release/wax-cli
cp .build/release/wax-cli /usr/local/bin/

2. Remember and recall from the terminal

# Save a memory
wax-cli remember "An automobile needs periodic maintenance."

# Search it back
wax-cli search "car service" --mode hybrid --topK 3

# Simple text-only search (no setup required)
wax-cli search "car service" --mode text

For long-running sessions, start the daemon:

wax-cli daemon --store-path ~/.wax/memory.wax

Then send JSON-line commands:

{"id":"1","command":"remember","content":"An automobile needs periodic maintenance."}
{"id":"2","command":"search","query":"car service","mode":"hybrid","topK":3}
{"id":"3","command":"shutdown"}

[!NOTE] Vector search requires the embedder. If it's unavailable, hybrid/vector commands fail loudly instead of silently falling back to text-only mode.


Agent Quick Start

Give your AI coding assistant (Claude Code, Cursor, Windsurf) a persistent memory that survives across sessions.

1. Install the MCP server

npx -y waxmcp@latest mcp install --scope user

This stages the Wax runtime locally and registers wax-mcp with your assistant. npx is only used for the one-time install.

2. Install the Wax skill (recommended)

# From within your project directory
claude install-skill https://github.com/christopherkarani/Wax/tree/main/Resources/skills/public/wax

This lets your assistant write correct Wax code without extra prompt scaffolding.

3. Or paste this starter prompt

<details> <summary><strong>Wax starter prompt (click to expand, then copy)</strong></summary>
Use the Wax MCP server for persistent memory in this repo.

Workflow rules:
- At session start, call `handoff_latest` first to load prior context, then call `session_start` once and keep the returned `session_id`.
- Use `remember` to store decisions, discoveries, and short factual notes. If the memory is session-scoped, pass `session_id` as a top-level argument. Do not put `session_id` inside `metadata`.
- Use `recall` for assembled context and `search` for raw ranked hits.
- Prefer `mode: "hybrid"` when semantic retrieval helps. Use `mode: "text"` when I want a fast or deterministic lexical lookup.
- Do not manage `SESSION_STORE`, `--store-path`, or `flush` in normal agent flows. The broker owns long-term memory and virtual session stores.
- Use `handoff` near the end of the session with `content`, optional `project`, and `pending_tasks`, then call `session_end`.
- Use `corpus_search` only when you need cross-session retrieval across broker-managed session history with provenance metadata.
- Use structured memory tools (`entity_upsert`, `fact_assert`, `fact_retract`, `facts_query`, `entity_resolve`) for stable entities and facts, not transient debugging notes.

Behavior expectations:
- Read existing handoffs and recall results before asking me to restate prior context.
- Keep memory writes concise, factual, and scoped to the task.
- When a cross-session result looks relevant, cite the provenance metadata so we know which session store it came from.
</details>

For the full Claude Code setup flow, see Resources/docs/wax-mcp-setup.md.


Why Wax?

FeatureWaxSQLite (FTS5)Cloud Vector DBs
SearchHybrid (Text + Vector)Text Only*Vector Only*
Latency~6ms (p95)~10ms (p95)150ms - 500ms+
Privacy100% Local100% LocalCloud-hosted
SetupZero ConfigLowComplex (API Keys)
ArchitectureApple Silicon NativeGenericVaries

Why a single .wax file?

Most RAG setups end up with a database, a vector store, and a file server. Wax keeps the moving pieces smaller by bundling documents, metadata, and indexes into one binary.

  • Less setup β€” no Docker stack and no separate database to babysit.
  • Portable β€” move the file with AirDrop, iCloud, or whatever sync layer you already use.
  • Atomic β€” backup, copy, or delete one file instead of chasing state across services.

Performance

Wax is tuned for M-series hardware and local recall.

Recall Latency (p95)

Lower is better. Measured in milliseconds.

Wax (Hybrid)  |β–ˆβ–ˆ 6.1ms
SQLite (Text) |β–ˆβ–ˆβ–ˆβ–ˆ 12ms
Cloud RAG     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 150ms+

Cold Open Time (p95)

Lower is better. Measured in milliseconds.

Wax           |β–ˆβ–ˆβ–ˆ 9.2ms
Traditional   |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 120ms+

[!TIP] Ingest Throughput: Wax handles 85.9 docs/s with full hybrid indexing on an M3 Max. Full benchmark report: Resources/docs/benchmarks/2026-03-06-performance-results.md


Architecture

<details> <summary><strong>How Wax works under the hood (click to expand)</strong></summary>

Wax uses a frame-based container format and embeds the search engines it needs inside the main file: SQLite FTS5 for text and a Metal-accelerated HNSW index for vectors.

Internal File Layout

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          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)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. Atomic resilience: dual headers and the WAL keep the store consistent even if the process dies mid-write.
  2. Unified retrieval: one query fans out to both the BM25 text index and the HNSW vector index.
  3. Structured knowledge: built-in EAV (Entity-Attribute-Value) storage handles durable facts and long-term reasoning.
</details>

Ecosystem Tools

πŸ€– MCP Server

Wax provides a first-class Model Context Protocol (MCP) server. Connect your local memory to Claude Code or any MCP-compatible agent.

npx -y waxmcp@latest mcp install --scope user

For the recommended Claude Code prompt and setup flow, see Resources/docs/wax-mcp-setup.md. For the OpenClaw adapter verification pass used in this repo, run scripts/verify-openclaw-adapter.sh. For the native-memory operator guide, verifier, and benchmark sweep, see docs/openclaw-native-memory.md.

The MCP surface now supports managed Markdown round-trips with markdown_export / markdown_sync, including MEMORY.md, daily notes, and DREAMS.md promotion review. markdown_sync also supports dry_run, and OpenClaw-oriented promotion thresholds can be overridden on session_synthesize / memory_promote or via environment variables.

For remote or team-hosted deployments, wax-mcp also supports HTTP transport:

./.build/debug/wax-mcp --no-embedder --transport http --http-host 127.0.0.1 --http-port 3000

πŸ” WaxRepo

A semantic search TUI for your git history. Index any repository and find code or commits using natural language.

# From within any git repo
wax-repo index
wax-repo search "where did we implement the WAL?"

FAQ

Q: Do I need an internet connection?
A: No. Wax is 100% on-device. No cloud APIs, no network calls.

Q: How big does the .wax file get?
A: It depends on your data, but the file stays compact thanks to LZ4 compression. Typical usage: a few MB for thousands of documents.

Q: Can I sync the .wax file across devices?
A: Yes. It's a single file. iCloud Drive, Dropbox, AirDrop β€” whatever you already use.

Q: What happens if the app crashes during a write?
A: Wax uses a write-ahead log (WAL) and dual headers. The store recovers automatically on the next open.

Q: Does Wax work on Intel Macs?
A: Wax is optimized for Apple Silicon (M-series). It may run on Intel via Rosetta but vector acceleration requires Metal performance shaders best supported on Apple Silicon.

Q: I get "embedder unavailable" when using hybrid search.
A: Hybrid and vector search require the local embedding model. Make sure the WaxEmbedder target is linked, or fall back to --mode text for pure text search.


Community & Support


License

Wax is released under the Apache License 2.0. See LICENSE for details.

<div align="center"> <sub>Built for developers who believe user data belongs on the user's device</sub> </div>

Global Ranking

-
Trust ScoreMCPHub Index

Based on codebase health & activity.

Manual Config

{ "mcpServers": { "wax": { "command": "npx", "args": ["wax"] } } }