Mema is a local-first memory tool for macOS. Save selected text, clipboard content, screenshots, images, or web pages with the reason they mattered; Mema preserves the original source and turns it into a searchable memory.
The product has three runnable parts:
| Part | What it does |
|---|---|
| macOS app | Global text, clipboard, screenshot, and image capture; library, editing, and search |
| Chrome extension | Toolbar, keyboard, and opt-in inline capture from web pages |
| Local backend | Loopback-only FastAPI API, SQLite/FTS5 storage, attachments, GPT enrichment, and hybrid search |
Original source, personal notes, user edits, and AI interpretation remain separate. Mema works without an OpenAI key for local storage and keyword search; cloud enrichment, OCR, image understanding, embeddings, and semantic search are optional.
- macOS 14 or later
- Xcode 26.x (verified with Xcode 26.2)
- Python 3.10 or later
- Google Chrome 102 or later for the extension
- Node.js 22 only for extension tests
- An OpenAI API key only for the optional GPT-5.6 path
Clone and enter the repository:
git clone https://github.com/CamaroW/Mema.git
cd MemaThe helper creates a virtual environment, installs dependencies, validates the
configuration, starts Mema on 127.0.0.1:8765, and waits for a healthy SQLite
database:
./scripts/dev.shKeep that terminal open. In another terminal, verify the service:
curl --fail http://127.0.0.1:8765/healthThe expected provider-off response includes:
{"status":"ok","database":"ok","attachments":"ok","openai_configured":false}To judge GPT-5.6 enrichment, copy the example configuration before starting
the backend and add a key only to the ignored root .env:
cp .env.example .envOPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-5.6
Never commit .env or an API key.
Open apps/macos/Mema.xcodeproj in Xcode, select
the shared Mema scheme and My Mac, and run it. With the backend running:
- Use the app's New Capture flow to save text and an optional personal note.
- Confirm the original source appears immediately in the library.
- With a key configured, wait for the GPT-5.6 interpretation; without a key, confirm the original remains stored and keyword-searchable.
- Search for a source phrase or generated tag and open the result.
- Edit the source or memory fields and confirm the captured source and AI layer remain distinguishable.
Global selection capture requires Accessibility permission. Interactive
screenshot capture requires Screen Recording permission and a stable local
Apple Development signature; ordinary library and text-capture judging does
not. The exact signing path is in the
macOS setup guide.
This is a build-free Manifest V3 extension:
-
Open
chrome://extensions. -
Enable Developer mode.
-
Choose Load unpacked and select
apps/chrome-extension/. -
Copy the generated extension ID.
-
Add its exact origin to the ignored root
.env:MEMA_CORS_ORIGINS=chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -
Restart
./scripts/dev.sh. -
Open an ordinary
httporhttpspage, select text, open Mema from the toolbar, add an optional note, and save. -
Return to the macOS app and confirm the web Capture is present and searchable.
For the optional inline path, open the extension's Settings page and enable
Show Add to Mema when I select text. Chrome then requests optional site
access. Turning it off removes Mema's injected controls while toolbar capture
continues to work. More acceptance cases are in the
judge walkthrough and
extension guide.
Mema defaults to gpt-5.6 and uses the OpenAI Responses API in three explicit,
user-visible flows:
- text Captures use strict Structured Outputs to generate a title, contextual summary, problem, key insight, why it was saved, caveats, tags, entities, and search aliases;
- GPT · Cloud extracts text from a screenshot when the user chooses it;
- image notes can opt in to background OCR plus visual interpretation. The original image remains authoritative and is saved before analysis begins.
Every Responses API call sets store: false. Provider output is validated
again at the service boundary before it can become a ready memory. Embeddings
use text-embedding-3-small as a separate retrieval step; keyword search still
works if the provider is absent or unavailable. Screenshot text also has an
on-device Apple Vision path, and cloud image analysis is off by default.
Implementation choices follow the official OpenAI guidance for
gpt-5.6,
Structured Outputs,
and API data controls.
Codex was the engineering collaborator across the Build Week project. It was used to:
- turn the product idea into contracts, architecture boundaries, and a staged implementation plan;
- implement and refactor the Swift/AppKit, Python/FastAPI, and Manifest V3 clients while keeping one shared Capture contract;
- build regression tests for idempotent retries, migrations, CORS, permissions, privacy controls, malformed model output, and offline behavior;
- audit the integrated repository, trace cross-client failures, review security and privacy boundaries, and prepare the reproducible judge path.
Human review remained part of the loop: permission-sensitive macOS behavior, real Chrome injection, product wording, privacy defaults, and final submission scope were verified against the running product rather than accepted from code generation alone.
Backend and deterministic stress tests (no real provider calls):
cd services/backend
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m pytest
.venv/bin/python tools/stress_backend.py
.venv/bin/python -m pip checkChrome extension tests:
cd apps/chrome-extension
npm testmacOS build and tests, from the repository root:
./scripts/test-macos.shCI runs these as independent backend, stress, Chrome, and macOS jobs and then requires all four to pass. Tests use local provider doubles and do not need an API key.
- The backend rejects non-loopback bind addresses.
- Chrome origins must be explicitly allowlisted; wildcards and public web origins are rejected before a request can mutate local data.
- SQLite files are created with owner-only permissions and attachment bytes are
served with
Cache-Control: no-store. - Browser selection text stays in the tab until Save.
- Cloud screenshot/image processing is explicit, with on-device or local-only alternatives.
- Source content is committed before asynchronous AI work, so provider failure cannot erase the Capture.
This is a local Build Week prototype, not a hardened multi-user or remotely hosted service. The AI runner is in-process, there is no account sync, and packaging/notarization is outside the current submission.
apps/macos/ SwiftUI/AppKit client
apps/chrome-extension/ Build-free Manifest V3 extension
services/backend/ FastAPI service and tests
contracts/ Shared API and JSON Schema contracts
docs/ Architecture, decisions, and judge walkthrough
scripts/ Startup, signing, and test helpers
Key references:
Judge walkthroughAPI contractArchitectureDecisionsBackend setupmacOS setupChrome extension setup
Mema is available under the MIT License.