remember does not return a memory
It answers 202 with a job id. Extraction and consolidation run afterwards, so nothing is searchable the instant the call returns. Poll the job if you need to know when; the terminal success state is completed.
You do not have to change how you work. Message it like a person, add it to the assistant you already talk to, or drive it from a terminal. It is the same memory behind all of them.
Message it, like a person
In the assistant you already use
On your own machine
Send it things as they happen — a photo of a letter, a voice note in the car, a line you want to remember. Nothing to install.
Everything Telegram reads, and what it does not →
Telegram is where things go IN. To ask questions, use it from your assistant or the dashboard — the bot confirms what it saved, it does not answer from your memory.
boiler service booked for the 14th, engineer is Tom
Saved.
[photo] insurance renewal letter
Read it — 2 pages. Saved.
/machines
macbook: connected
Connect a WhatsApp Business number and everything sent to it is read into memory — messages, images, documents, voice notes.
This reads a Business number, not your personal chats — no API exists that can read those, and a product claiming otherwise is doing something you would not want.
[document] Q3-invoice-8841.pdf
Read it. £4,120, due 30 September, from Northgate Ltd.
moved the deadline to the 6th
Saved. The earlier date is kept as superseded.
Give ChatGPT a memory that survives the chat. No code, no file to edit — one address pasted into settings.
What the assistant can and cannot do with it →
Needs a ChatGPT plan that allows custom connectors.
General
Personalisation
Connectors
Data controls
Add custom connector
Server address
PersistMemory wants to
Connected
Ask it to remember something. It is there in next week's chat.
The same address, added to Claude on the web or in the desktop app.
Profile
Appearance
Connectors
Privacy
Add custom connector
Server address
PersistMemory wants to
Connected
Claude writes memories as you talk, and reads them back later.
Or, in Claude Code — one line, no settings screen:
# one line, and it is connected
$ claude mcp add --transport http persistmemory https://mcp.persistmemory.com/mcp
Added stdio MCP server persistmemory
# then, inside Claude Code
$ /mcp
persistmemory connected · authenticate to finish
Editors and coding agents that speak MCP read the same memory, so a decision you explained in one is there in the next.
General
Models
MCP
Rules
Add custom connector
Server address
PersistMemory wants to
Connected
The same memory the chat surfaces write to, in your editor.
Or edit the file directly — Codex uses ~/.codex/config.toml:
{
"mcpServers": {
"persistmemory": {
"url": "https://mcp.persistmemory.com/mcp"
}
}
}Capture and search from the shell — and connect this computer, so your assistants can ask it for a file you never uploaded.
$ curl -fsSL https://persistmemory.com/install.sh | sh
installed pm 0.1.0 -> /usr/local/bin/pm
$ pm auth login
Signed in as you@example.com
# capture
$ pm remember "shipped the migration on the 12th"
Remembered.
# and ask for it back
$ pm search "when did the migration ship"
12 March — shipped the migration. high confidence
# let this machine answer for your assistants
$ pm agent --root ~/notes --root ~/projects
Answering as macbook, from: ~/notes, ~/projects Nothing outside those folders can be read.
Documentation
PersistMemory captures material from the places you already work, extracts what it meant, and hands it back months later. Connect a source, point an assistant at the MCP server, or call the API yourself — and once it is running, it can reach your own machine for a file you never uploaded.
A filing rule, an audience and a retention policy — not a folder. How one memory sits in several at once, and what happens when a Space is shared.
ReadEight sources, from Gmail to WhatsApp, and the integration API that authorises them without ever taking a third-party password.
ReadTwenty-eight tools over stdio or OAuth-authenticated HTTP, so an assistant can search your memory, capture something new, and file it where you said.
ReadAsk your own machine for a file or the output of a command. You see the exact argv before it runs, and it refuses two whole classes whatever you approve.
Readpm, for capturing and searching from a terminal. Signs in through your browser with PKCE, or with a key when there is no browser to open.
Read@persistmemory/sdk for TypeScript and persistmemory for Python. Same endpoints, same retry policy, same paginator.
ReadFour stages, all of them asynchronous. Knowing the order is what makes the timing of the API make sense.
A connector lists what changed, fetches it, and hands the bytes to the pipeline. A PDF from Drive and a PDF attached to an email take the same path from there.
The text is normalized, then a model extracts candidate claims from it: decisions, tasks, commitments, preferences, facts, and the people involved.
Entity resolution, deduplication and conflict detection run against the existing store. One piece of material may produce one memory, several, or none.
A memory that changes is revised into a new version and the old one is superseded, not overwritten. Search hides superseded facts by default, because a stale answer presented as current is the worst thing retrieval can do.
Reading an answer
Nothing is overwritten here. When something you believed changes, the new memory supersedes the old one — the old one keeps its evidence, its sources and the dates it was true between, and it moves into a section of its own. That section is headed, in those words, so a model cannot skim past it and report last year’s answer as this year’s.
Relevant memory
The ledger runs on Postgres with pgvector
No longer true — this WAS true and has since changed
The ledger runs on DynamoDB
Struck, dated, and kept — not deleted. Both rows are one lineage.
“I used to use AWS” does not stop having been true because it stopped being current. A store that erases the old claim can answer what you think now and nothing about what you thought in June — which is most of what people actually ask a memory.
Ranked together by similarity, a superseded memory sits among live ones with only a date to tell them apart — and dates are exactly what a model skims. So they are rendered as two sections with that heading between them, and the heading says what it means rather than labelling it archive and hoping.
Search returns current memories by default. Ask for the rest with includeHistorical over HTTP, or includeHistory from an assistant. Ask what was believed at a moment with asOf, and read one memory’s whole lineage with memory_timeline.
A contradiction the evidence cannot settle is a different thing, and it is not hidden either: it is rendered first, under CONTRADICTIONS IN THE RECORD, because it is the one part of an answer that must not be skimmed. Supersession says something changed. A conflict says two sources disagree and nobody has decided.
It answers 202 with a job id. Extraction and consolidation run afterwards, so nothing is searchable the instant the call returns. Poll the job if you need to know when; the terminal success state is completed.
With embeddings unavailable it falls back to deterministic retrieval and still answers. Read diagnostics.degraded before telling a user the system knows nothing. It may merely be looking with one eye.
When two memories contradict each other and nothing in the evidence decides it, the pair is held for you. A resolution you record outranks everything the system inferred.
Every request carries a bearer token: a pm_live_ key or a session JWT. Keys are minted only while you are signed in on the website, because a key that can mint another key makes revoking the first one pointless.
The response to a mint is the only place the key ever appears. Only its hash is stored, so a client that does not capture it there has lost it.
SDK reference# Mint a key. Session only, so this runs from the browser,
# not from a script holding another key.
POST /keys
{ "name": "laptop", "scopes": ["read", "write"], "expiresInDays": 90 }
# Then every call carries it.
GET /api/v1/memories?type=decision&limit=50
Authorization: Bearer pm_live_...
# /v1 is the same router, kept for clients that predate the prefix.
GET /v1/memories